summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeo Li <aoli@google.com>2017-07-10 20:45:34 +0000
committerLeo Li <aoli@google.com>2017-07-10 20:45:34 +0000
commit93abd7d915fb12c9967fe2433dfc873d3b4e938d (patch)
treec37b55fac997a6034a8646df03ff81e3e8fbcb41
parenta7a77540ef747aa5674014c696a289d45a168641 (diff)
downloadbcm5719-llvm-93abd7d915fb12c9967fe2433dfc873d3b4e938d.tar.gz
bcm5719-llvm-93abd7d915fb12c9967fe2433dfc873d3b4e938d.zip
[ConstantHoisting] Remove dupliate logic in constant hoisting
Summary: As metioned in https://reviews.llvm.org/D34576, checkings in `collectConstantCandidates` can be replaced by using `llvm::canReplaceOperandWithVariable`. The only special case is that `collectConstantCandidates` return false for all `IntrinsicInst` but it is safe for us to collect constant candidates from `IntrinsicInst`. Reviewers: pirama, efriedma, srhines Reviewed By: efriedma Subscribers: llvm-commits, javed.absar Differential Revision: https://reviews.llvm.org/D34921 llvm-svn: 307587
-rw-r--r--llvm/lib/Transforms/Scalar/ConstantHoisting.cpp42
-rw-r--r--llvm/lib/Transforms/Utils/Local.cpp3
-rw-r--r--llvm/test/Transforms/ConstantHoisting/ARM/bad-cases.ll31
-rw-r--r--llvm/test/Transforms/ConstantHoisting/ARM/insertvalue.ll31
4 files changed, 73 insertions, 34 deletions
diff --git a/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp b/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp
index 14638e85293..122c9314e02 100644
--- a/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp
@@ -44,6 +44,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils/Local.h"
#include <tuple>
using namespace llvm;
@@ -401,42 +402,15 @@ void ConstantHoistingPass::collectConstantCandidates(
if (Inst->isCast())
return;
- // Can't handle inline asm. Skip it.
- if (auto Call = dyn_cast<CallInst>(Inst))
- if (isa<InlineAsm>(Call->getCalledValue()))
- return;
-
- // Switch cases must remain constant, and if the value being tested is
- // constant the entire thing should disappear.
- if (isa<SwitchInst>(Inst))
- return;
-
- // Static allocas (constant size in the entry block) are handled by
- // prologue/epilogue insertion so they're free anyway. We definitely don't
- // want to make them non-constant.
- auto AI = dyn_cast<AllocaInst>(Inst);
- if (AI && AI->isStaticAlloca())
- return;
-
- // Constants in GEPs that index into a struct type should not be hoisted.
- if (isa<GetElementPtrInst>(Inst)) {
- gep_type_iterator GTI = gep_type_begin(Inst);
-
- // Collect constant for first operand.
- collectConstantCandidates(ConstCandMap, Inst, 0);
- // Scan rest operands.
- for (unsigned Idx = 1, E = Inst->getNumOperands(); Idx != E; ++Idx, ++GTI) {
- // Only collect constants that index into a non struct type.
- if (!GTI.isStruct()) {
- collectConstantCandidates(ConstCandMap, Inst, Idx);
- }
- }
- return;
- }
-
// Scan all operands.
for (unsigned Idx = 0, E = Inst->getNumOperands(); Idx != E; ++Idx) {
- collectConstantCandidates(ConstCandMap, Inst, Idx);
+ // The cost of materializing the constants (defined in
+ // `TargetTransformInfo::getIntImmCost`) for instructions which only take
+ // constant variables is lower than `TargetTransformInfo::TCC_Basic`. So
+ // it's safe for us to collect constant candidates from all IntrinsicInsts.
+ if (canReplaceOperandWithVariable(Inst, Idx) || isa<IntrinsicInst>(Inst)) {
+ collectConstantCandidates(ConstCandMap, Inst, Idx);
+ }
} // end of for all operands
}
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index bc135852cd4..74610613001 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -2169,6 +2169,9 @@ bool llvm::canReplaceOperandWithVariable(const Instruction *I, unsigned OpIdx) {
return true;
case Instruction::Call:
case Instruction::Invoke:
+ // Can't handle inline asm. Skip it.
+ if (isa<InlineAsm>(ImmutableCallSite(I).getCalledValue()))
+ return false;
// Many arithmetic intrinsics have no issue taking a
// variable, however it's hard to distingish these from
// specials such as @llvm.frameaddress that require a constant.
diff --git a/llvm/test/Transforms/ConstantHoisting/ARM/bad-cases.ll b/llvm/test/Transforms/ConstantHoisting/ARM/bad-cases.ll
index ffcfb2e56c9..315e69998c6 100644
--- a/llvm/test/Transforms/ConstantHoisting/ARM/bad-cases.ll
+++ b/llvm/test/Transforms/ConstantHoisting/ARM/bad-cases.ll
@@ -107,3 +107,34 @@ entry:
%ret = add i32 %cast0, %cast1
ret i32 %ret
}
+
+@exception_type = external global i8
+
+; Constants in inline ASM should not be hoisted.
+define i32 @inline_asm_invoke() personality i8* null {
+;CHECK-LABEL: @inline_asm_invoke
+;CHECK-NOT: %const = 214672
+;CHECK: %X = invoke i32 asm "bswap $0", "=r,r"(i32 214672)
+ %X = invoke i32 asm "bswap $0", "=r,r"(i32 214672)
+ to label %L unwind label %lpad
+;CHECK: %Y = invoke i32 asm "bswap $0", "=r,r"(i32 214672)
+ %Y = invoke i32 asm "bswap $0", "=r,r"(i32 214672)
+ to label %L unwind label %lpad
+L:
+ ret i32 %X
+lpad:
+ %lp = landingpad i32
+ cleanup
+ catch i8* @exception_type
+ ret i32 1
+}
+
+define i32 @inline_asm_call() {
+;CHECK-LABEL: @inline_asm_call
+;CHECK-NOT: %const = 214672
+;CHECK: %X = call i32 asm "bswap $0", "=r,r"(i32 214672)
+ %X = call i32 asm "bswap $0", "=r,r"(i32 214672)
+;CHECK: %Y = call i32 asm "bswap $0", "=r,r"(i32 214672)
+ %Y = call i32 asm "bswap $0", "=r,r"(i32 214672)
+ ret i32 %X
+}
diff --git a/llvm/test/Transforms/ConstantHoisting/ARM/insertvalue.ll b/llvm/test/Transforms/ConstantHoisting/ARM/insertvalue.ll
new file mode 100644
index 00000000000..99fe7fbe22a
--- /dev/null
+++ b/llvm/test/Transforms/ConstantHoisting/ARM/insertvalue.ll
@@ -0,0 +1,31 @@
+; RUN: opt -consthoist -S < %s | FileCheck %s
+target triple = "thumbv6m-none-eabi"
+
+%T = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
+i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
+i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
+i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
+i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
+i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
+i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
+i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
+i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
+i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
+i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
+i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
+i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
+i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
+i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
+i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
+i32, i32, i32, i32, i32, i32 }
+
+; The second operand of insertvalue is able to be hoisted.
+define void @test1(%T %P) {
+; CHECK-LABEL: @test1
+; CHECK: %const = bitcast i32 256 to i32
+; CHECK: %1 = insertvalue %T %P, i32 %const, 256
+; CHECK: %2 = insertvalue %T %P, i32 %const, 256
+ %1 = insertvalue %T %P, i32 256, 256
+ %2 = insertvalue %T %P, i32 256, 256
+ ret void
+}
OpenPOWER on IntegriCloud