1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-26 12:43:36 +01:00

[ARM][TTI] Scan for existing loop intrinsics

TTI should report that it's not profitable to generate a hardware loop
if it, or one of its child loops, has already been converted.

Differential Revision: https://reviews.llvm.org/D63212

llvm-svn: 363234
This commit is contained in:
Sam Parker 2019-06-13 08:28:46 +00:00
parent dfbd44a9f0
commit a6e678d64e
2 changed files with 101 additions and 5 deletions

View File

@ -804,12 +804,39 @@ bool ARMTTIImpl::isHardwareLoopProfitable(Loop *L, ScalarEvolution &SE,
return false;
};
auto IsHardwareLoopIntrinsic = [](Instruction &I) {
if (auto *Call = dyn_cast<IntrinsicInst>(&I)) {
switch (Call->getCalledFunction()->getIntrinsicID()) {
default:
break;
case Intrinsic::set_loop_iterations:
case Intrinsic::loop_decrement:
case Intrinsic::loop_decrement_reg:
return true;
}
}
return false;
};
// Scan the instructions to see if there's any that we know will turn into a
// call.
for (auto *BB : L->getBlocks())
for (auto &I : *BB)
if (MaybeCall(I))
return false;
// call or if this loop is already a low-overhead loop.
auto ScanLoop = [&](Loop *L) {
for (auto *BB : L->getBlocks()) {
for (auto &I : *BB) {
if (MaybeCall(I) || IsHardwareLoopIntrinsic(I))
return false;
}
}
return true;
};
// Visit inner loops.
for (auto Inner : *L)
if (!ScanLoop(Inner))
return false;
if (!ScanLoop(L))
return false;
// TODO: Check whether the trip count calculation is expensive. If L is the
// inner loop but we know it has a low trip count, calculating that trip
@ -817,6 +844,7 @@ bool ARMTTIImpl::isHardwareLoopProfitable(Loop *L, ScalarEvolution &SE,
LLVMContext &C = L->getHeader()->getContext();
HWLoopInfo.CounterInReg = true;
HWLoopInfo.IsNestingLegal = false;
HWLoopInfo.CountType = Type::getInt32Ty(C);
HWLoopInfo.LoopDecrement = ConstantInt::get(HWLoopInfo.CountType, 1);
return true;

View File

@ -70,3 +70,71 @@ while.cond1.while.end_crit_edge.us:
while.end7:
ret void
}
; CHECK-LABEL: pre_existing
; CHECK: llvm.set.loop.iterations
; CHECK-NOT: llvm.set.loop.iterations
; CHECK: call i32 @llvm.loop.decrement.reg.i32.i32.i32(i32 %0, i32 1)
; CHECK-NOT: call i32 @llvm.loop.decrement.reg
define i32 @pre_existing(i32 %n, i32* nocapture %p, i32* nocapture readonly %q) {
entry:
call void @llvm.set.loop.iterations.i32(i32 %n)
br label %while.body
while.body: ; preds = %while.body, %entry
%q.addr.05 = phi i32* [ %incdec.ptr, %while.body ], [ %q, %entry ]
%p.addr.04 = phi i32* [ %incdec.ptr1, %while.body ], [ %p, %entry ]
%0 = phi i32 [ %n, %entry ], [ %2, %while.body ]
%incdec.ptr = getelementptr inbounds i32, i32* %q.addr.05, i32 1
%1 = load i32, i32* %q.addr.05, align 4
%incdec.ptr1 = getelementptr inbounds i32, i32* %p.addr.04, i32 1
store i32 %1, i32* %p.addr.04, align 4
%2 = call i32 @llvm.loop.decrement.reg.i32.i32.i32(i32 %0, i32 1)
%3 = icmp ne i32 %2, 0
br i1 %3, label %while.body, label %while.end
while.end: ; preds = %while.body
ret i32 0
}
; CHECK-LABEL: pre_existing_inner
; CHECK-NOT: llvm.set.loop.iterations
; CHECK: while.cond1.preheader.us:
; CHECK: call void @llvm.set.loop.iterations.i32(i32 %N)
; CHECK: call i32 @llvm.loop.decrement.reg.i32.i32.i32(i32 %0, i32 1)
; CHECK: br i1
; CHECK-NOT: call i32 @llvm.loop.decrement
define void @pre_existing_inner(i32* nocapture %A, i32 %N) {
entry:
%cmp20 = icmp eq i32 %N, 0
br i1 %cmp20, label %while.end7, label %while.cond1.preheader.us
while.cond1.preheader.us:
%i.021.us = phi i32 [ %inc6.us, %while.cond1.while.end_crit_edge.us ], [ 0, %entry ]
%mul.us = mul i32 %i.021.us, %N
call void @llvm.set.loop.iterations.i32(i32 %N)
br label %while.body3.us
while.body3.us:
%j.019.us = phi i32 [ 0, %while.cond1.preheader.us ], [ %inc.us, %while.body3.us ]
%0 = phi i32 [ %N, %while.cond1.preheader.us ], [ %1, %while.body3.us ]
%add.us = add i32 %j.019.us, %mul.us
%arrayidx.us = getelementptr inbounds i32, i32* %A, i32 %add.us
store i32 %add.us, i32* %arrayidx.us, align 4
%inc.us = add nuw i32 %j.019.us, 1
%1 = call i32 @llvm.loop.decrement.reg.i32.i32.i32(i32 %0, i32 1)
%2 = icmp ne i32 %1, 0
br i1 %2, label %while.body3.us, label %while.cond1.while.end_crit_edge.us
while.cond1.while.end_crit_edge.us:
%inc6.us = add nuw i32 %i.021.us, 1
%exitcond23 = icmp eq i32 %inc6.us, %N
br i1 %exitcond23, label %while.end7, label %while.cond1.preheader.us
while.end7:
ret void
}
declare void @llvm.set.loop.iterations.i32(i32) #0
declare i32 @llvm.loop.decrement.reg.i32.i32.i32(i32, i32) #0