Skip to content

Commit 0c0bf38

Browse files
committed
[𝘀𝗽𝗿] initial version
Created using spr 1.3.6-beta.1
2 parents efa2833 + 49a3762 commit 0c0bf38

19 files changed

+94
-75
lines changed

llvm/include/llvm/IR/Module.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -471,15 +471,14 @@ class LLVM_ABI Module {
471471

472472
/// Look up the specified global in the module symbol table.
473473
/// If it does not exist, invoke a callback to create a declaration of the
474-
/// global and return it. The global is constantexpr casted to the expected
475-
/// type if necessary.
476-
Constant *
474+
/// global and return it.
475+
GlobalVariable *
477476
getOrInsertGlobal(StringRef Name, Type *Ty,
478477
function_ref<GlobalVariable *()> CreateGlobalCallback);
479478

480479
/// Look up the specified global in the module symbol table. If required, this
481480
/// overload constructs the global variable using its constructor's defaults.
482-
Constant *getOrInsertGlobal(StringRef Name, Type *Ty);
481+
GlobalVariable *getOrInsertGlobal(StringRef Name, Type *Ty);
483482

484483
/// @}
485484
/// @name Global Alias Accessors

llvm/include/llvm/Transforms/Scalar/GVN.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class NonLocalDepResult;
5353
class OptimizationRemarkEmitter;
5454
class PHINode;
5555
class TargetLibraryInfo;
56+
class TargetTransformInfo;
5657
class Value;
5758
/// A private "module" namespace for types and utilities used by GVN. These
5859
/// are implementation details and should not be used by clients.
@@ -226,6 +227,7 @@ class GVNPass : public PassInfoMixin<GVNPass> {
226227
MemoryDependenceResults *MD = nullptr;
227228
DominatorTree *DT = nullptr;
228229
const TargetLibraryInfo *TLI = nullptr;
230+
const TargetTransformInfo *TTI = nullptr;
229231
AssumptionCache *AC = nullptr;
230232
SetVector<BasicBlock *> DeadBlocks;
231233
OptimizationRemarkEmitter *ORE = nullptr;
@@ -318,7 +320,8 @@ class GVNPass : public PassInfoMixin<GVNPass> {
318320
using UnavailBlkVect = SmallVector<BasicBlock *, 64>;
319321

320322
bool runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
321-
const TargetLibraryInfo &RunTLI, AAResults &RunAA,
323+
const TargetLibraryInfo &RunTLI,
324+
const TargetTransformInfo &RunTTI, AAResults &RunAA,
322325
MemoryDependenceResults *RunMD, LoopInfo &LI,
323326
OptimizationRemarkEmitter *ORE, MemorySSA *MSSA = nullptr);
324327

llvm/include/llvm/Transforms/Utils/LoopUtils.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,10 +175,10 @@ bool sinkRegionForLoopNest(DomTreeNode *, AAResults *, LoopInfo *,
175175
/// \p AllowSpeculation is whether values should be hoisted even if they are not
176176
/// guaranteed to execute in the loop, but are safe to speculatively execute.
177177
bool hoistRegion(DomTreeNode *, AAResults *, LoopInfo *, DominatorTree *,
178-
AssumptionCache *, TargetLibraryInfo *, Loop *,
179-
MemorySSAUpdater &, ScalarEvolution *, ICFLoopSafetyInfo *,
180-
SinkAndHoistLICMFlags &, OptimizationRemarkEmitter *, bool,
181-
bool AllowSpeculation);
178+
AssumptionCache *, TargetLibraryInfo *, TargetTransformInfo *,
179+
Loop *, MemorySSAUpdater &, ScalarEvolution *,
180+
ICFLoopSafetyInfo *, SinkAndHoistLICMFlags &,
181+
OptimizationRemarkEmitter *, bool, bool AllowSpeculation);
182182

183183
/// Return true if the induction variable \p IV in a Loop whose latch is
184184
/// \p LatchBlock would become dead if the exit test \p Cond were removed.

llvm/lib/CodeGen/LowerEmuTLS.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,7 @@ bool addEmuTlsVar(Module &M, const GlobalVariable *GV) {
140140
PointerType *InitPtrType = PointerType::getUnqual(C);
141141
Type *ElementTypes[4] = {WordType, WordType, VoidPtrType, InitPtrType};
142142
StructType *EmuTlsVarType = StructType::create(ElementTypes);
143-
EmuTlsVar = cast<GlobalVariable>(
144-
M.getOrInsertGlobal(EmuTlsVarName, EmuTlsVarType));
143+
EmuTlsVar = M.getOrInsertGlobal(EmuTlsVarName, EmuTlsVarType);
145144
copyLinkageVisibility(M, GV, EmuTlsVar);
146145

147146
// Define "__emutls_t.*" and "__emutls_v.*" only if GV is defined.
@@ -155,8 +154,7 @@ bool addEmuTlsVar(Module &M, const GlobalVariable *GV) {
155154
GlobalVariable *EmuTlsTmplVar = nullptr;
156155
if (InitValue) {
157156
std::string EmuTlsTmplName = ("__emutls_t." + GV->getName()).str();
158-
EmuTlsTmplVar = dyn_cast_or_null<GlobalVariable>(
159-
M.getOrInsertGlobal(EmuTlsTmplName, GVType));
157+
EmuTlsTmplVar = M.getOrInsertGlobal(EmuTlsTmplName, GVType);
160158
assert(EmuTlsTmplVar && "Failed to create emualted TLS initializer");
161159
EmuTlsTmplVar->setConstant(true);
162160
EmuTlsTmplVar->setInitializer(const_cast<Constant*>(InitValue));

llvm/lib/CodeGen/TargetLoweringBase.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1975,10 +1975,9 @@ Value *TargetLoweringBase::getIRStackGuard(IRBuilderBase &IRB) const {
19751975
if (getTargetMachine().getTargetTriple().isOSOpenBSD()) {
19761976
Module &M = *IRB.GetInsertBlock()->getParent()->getParent();
19771977
PointerType *PtrTy = PointerType::getUnqual(M.getContext());
1978-
Constant *C = M.getOrInsertGlobal("__guard_local", PtrTy);
1979-
if (GlobalVariable *G = dyn_cast_or_null<GlobalVariable>(C))
1980-
G->setVisibility(GlobalValue::HiddenVisibility);
1981-
return C;
1978+
GlobalVariable *G = M.getOrInsertGlobal("__guard_local", PtrTy);
1979+
G->setVisibility(GlobalValue::HiddenVisibility);
1980+
return G;
19821981
}
19831982
return nullptr;
19841983
}

llvm/lib/CodeGen/WasmEHPrepare.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,7 @@ bool WasmEHPrepareImpl::prepareEHPads(Function &F) {
247247
// we depend on CoalesceFeaturesAndStripAtomics to downgrade it to
248248
// non-thread-local ones, in which case we don't allow this object to be
249249
// linked with other objects using shared memory.
250-
LPadContextGV = cast<GlobalVariable>(
251-
M.getOrInsertGlobal("__wasm_lpad_context", LPadContextTy));
250+
LPadContextGV = M.getOrInsertGlobal("__wasm_lpad_context", LPadContextTy);
252251
LPadContextGV->setThreadLocalMode(GlobalValue::GeneralDynamicTLSModel);
253252

254253
LPadIndexField = LPadContextGV;

llvm/lib/IR/Module.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -250,12 +250,9 @@ GlobalVariable *Module::getGlobalVariable(StringRef Name,
250250
}
251251

252252
/// getOrInsertGlobal - Look up the specified global in the module symbol table.
253-
/// 1. If it does not exist, add a declaration of the global and return it.
254-
/// 2. Else, the global exists but has the wrong type: return the function
255-
/// with a constantexpr cast to the right type.
256-
/// 3. Finally, if the existing global is the correct declaration, return the
257-
/// existing global.
258-
Constant *Module::getOrInsertGlobal(
253+
/// If it does not exist, add a declaration of the global and return it.
254+
/// Otherwise, return the existing global.
255+
GlobalVariable *Module::getOrInsertGlobal(
259256
StringRef Name, Type *Ty,
260257
function_ref<GlobalVariable *()> CreateGlobalCallback) {
261258
// See if we have a definition for the specified global already.
@@ -269,7 +266,7 @@ Constant *Module::getOrInsertGlobal(
269266
}
270267

271268
// Overload to construct a global variable using its constructor's defaults.
272-
Constant *Module::getOrInsertGlobal(StringRef Name, Type *Ty) {
269+
GlobalVariable *Module::getOrInsertGlobal(StringRef Name, Type *Ty) {
273270
return getOrInsertGlobal(Name, Ty, [&] {
274271
return new GlobalVariable(*this, Ty, false, GlobalVariable::ExternalLinkage,
275272
nullptr, Name);

llvm/lib/Transforms/IPO/LowerTypeTests.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -983,11 +983,10 @@ LowerTypeTestsModule::importTypeId(StringRef TypeId) {
983983
auto ImportGlobal = [&](StringRef Name) {
984984
// Give the global a type of length 0 so that it is not assumed not to alias
985985
// with any other global.
986-
Constant *C = M.getOrInsertGlobal(("__typeid_" + TypeId + "_" + Name).str(),
987-
Int8Arr0Ty);
988-
if (auto *GV = dyn_cast<GlobalVariable>(C))
989-
GV->setVisibility(GlobalValue::HiddenVisibility);
990-
return C;
986+
GlobalVariable *GV = M.getOrInsertGlobal(
987+
("__typeid_" + TypeId + "_" + Name).str(), Int8Arr0Ty);
988+
GV->setVisibility(GlobalValue::HiddenVisibility);
989+
return GV;
991990
};
992991

993992
auto ImportConstant = [&](StringRef Name, uint64_t Const, unsigned AbsWidth,
@@ -1020,8 +1019,14 @@ LowerTypeTestsModule::importTypeId(StringRef TypeId) {
10201019
return C;
10211020
};
10221021

1023-
if (TIL.TheKind != TypeTestResolution::Unsat)
1024-
TIL.OffsetedGlobal = ImportGlobal("global_addr");
1022+
if (TIL.TheKind != TypeTestResolution::Unsat) {
1023+
auto *GV = ImportGlobal("global_addr");
1024+
// This is either a vtable (in .data.rel.ro) or a jump table (in .text).
1025+
// Either way it's expected to be in the low 2 GiB, so set the small code
1026+
// model.
1027+
GV->setCodeModel(CodeModel::Small);
1028+
TIL.OffsetedGlobal = GV;
1029+
}
10251030

10261031
if (TIL.TheKind == TypeTestResolution::ByteArray ||
10271032
TIL.TheKind == TypeTestResolution::Inline ||

llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1689,12 +1689,10 @@ void DevirtModule::exportConstant(VTableSlot Slot, ArrayRef<uint64_t> Args,
16891689

16901690
Constant *DevirtModule::importGlobal(VTableSlot Slot, ArrayRef<uint64_t> Args,
16911691
StringRef Name) {
1692-
Constant *C =
1692+
GlobalVariable *GV =
16931693
M.getOrInsertGlobal(getGlobalName(Slot, Args, Name), Int8Arr0Ty);
1694-
auto *GV = dyn_cast<GlobalVariable>(C);
1695-
if (GV)
1696-
GV->setVisibility(GlobalValue::HiddenVisibility);
1697-
return C;
1694+
GV->setVisibility(GlobalValue::HiddenVisibility);
1695+
return GV;
16981696
}
16991697

17001698
Constant *DevirtModule::importConstant(VTableSlot Slot, ArrayRef<uint64_t> Args,

llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,12 +1506,10 @@ bool DataFlowSanitizer::runImpl(
15061506

15071507
auto GetOrInsertGlobal = [this, &Changed](StringRef Name,
15081508
Type *Ty) -> Constant * {
1509-
Constant *C = Mod->getOrInsertGlobal(Name, Ty);
1510-
if (GlobalVariable *G = dyn_cast<GlobalVariable>(C)) {
1511-
Changed |= G->getThreadLocalMode() != GlobalVariable::InitialExecTLSModel;
1512-
G->setThreadLocalMode(GlobalVariable::InitialExecTLSModel);
1513-
}
1514-
return C;
1509+
GlobalVariable *G = Mod->getOrInsertGlobal(Name, Ty);
1510+
Changed |= G->getThreadLocalMode() != GlobalVariable::InitialExecTLSModel;
1511+
G->setThreadLocalMode(GlobalVariable::InitialExecTLSModel);
1512+
return G;
15151513
};
15161514

15171515
// These globals must be kept in sync with the ones in dfsan.cpp.

llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -692,15 +692,14 @@ void HWAddressSanitizer::initializeModule() {
692692
}
693693

694694
if (!TargetTriple.isAndroid()) {
695-
Constant *C = M.getOrInsertGlobal("__hwasan_tls", IntptrTy, [&] {
695+
ThreadPtrGlobal = M.getOrInsertGlobal("__hwasan_tls", IntptrTy, [&] {
696696
auto *GV = new GlobalVariable(M, IntptrTy, /*isConstant=*/false,
697697
GlobalValue::ExternalLinkage, nullptr,
698698
"__hwasan_tls", nullptr,
699699
GlobalVariable::InitialExecTLSModel);
700700
appendToCompilerUsed(M, GV);
701701
return GV;
702702
});
703-
ThreadPtrGlobal = cast<GlobalVariable>(C);
704703
}
705704
}
706705

llvm/lib/Transforms/Instrumentation/NumericalStabilitySanitizer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -642,11 +642,11 @@ NumericalStabilitySanitizerPass::run(Module &M, ModuleAnalysisManager &MAM) {
642642
}
643643

644644
static GlobalValue *createThreadLocalGV(const char *Name, Module &M, Type *Ty) {
645-
return dyn_cast<GlobalValue>(M.getOrInsertGlobal(Name, Ty, [&M, Ty, Name] {
645+
return M.getOrInsertGlobal(Name, Ty, [&M, Ty, Name] {
646646
return new GlobalVariable(M, Ty, false, GlobalVariable::ExternalLinkage,
647647
nullptr, Name, nullptr,
648648
GlobalVariable::InitialExecTLSModel);
649-
}));
649+
});
650650
}
651651

652652
NumericalStabilitySanitizer::NumericalStabilitySanitizer(Module &M)

llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -486,10 +486,8 @@ bool ModuleSanitizerCoverage::instrumentModule() {
486486
SanCovTraceSwitchFunction =
487487
M.getOrInsertFunction(SanCovTraceSwitchName, VoidTy, Int64Ty, PtrTy);
488488

489-
Constant *SanCovLowestStackConstant =
490-
M.getOrInsertGlobal(SanCovLowestStackName, IntptrTy);
491-
SanCovLowestStack = dyn_cast<GlobalVariable>(SanCovLowestStackConstant);
492-
if (!SanCovLowestStack || SanCovLowestStack->getValueType() != IntptrTy) {
489+
SanCovLowestStack = M.getOrInsertGlobal(SanCovLowestStackName, IntptrTy);
490+
if (SanCovLowestStack->getValueType() != IntptrTy) {
493491
C->emitError(StringRef("'") + SanCovLowestStackName +
494492
"' should not be declared by the user");
495493
return true;

llvm/lib/Transforms/Scalar/EarlyCSE.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1534,6 +1534,16 @@ bool EarlyCSE::processNode(DomTreeNode *Node) {
15341534
}
15351535
// See if the instruction has an available value. If so, use it.
15361536
if (Value *V = AvailableValues.lookup(&Inst)) {
1537+
// If this CSE would effectively hoist the instruction and that's known
1538+
// to be unprofitable, don't do it. Remember the instruction so that it
1539+
// can be used by other instructions in the same block.
1540+
if (auto *ReplI = dyn_cast<Instruction>(V)) {
1541+
if (ReplI->getParent() != Inst.getParent() &&
1542+
!TTI.isProfitableToHoist(&Inst)) {
1543+
AvailableValues.insert(&Inst, &Inst);
1544+
continue;
1545+
}
1546+
}
15371547
LLVM_DEBUG(dbgs() << "EarlyCSE CSE: " << Inst << " to: " << *V
15381548
<< '\n');
15391549
if (!DebugCounter::shouldExecute(CSECounter)) {

llvm/lib/Transforms/Scalar/GVN.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
4343
#include "llvm/Analysis/PHITransAddr.h"
4444
#include "llvm/Analysis/TargetLibraryInfo.h"
45+
#include "llvm/Analysis/TargetTransformInfo.h"
4546
#include "llvm/Analysis/ValueTracking.h"
4647
#include "llvm/IR/Attributes.h"
4748
#include "llvm/IR/BasicBlock.h"
@@ -832,6 +833,7 @@ PreservedAnalyses GVNPass::run(Function &F, FunctionAnalysisManager &AM) {
832833
auto &AC = AM.getResult<AssumptionAnalysis>(F);
833834
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
834835
auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
836+
auto &TTI = AM.getResult<TargetIRAnalysis>(F);
835837
auto &AA = AM.getResult<AAManager>(F);
836838
auto *MemDep =
837839
isMemDepEnabled() ? &AM.getResult<MemoryDependenceAnalysis>(F) : nullptr;
@@ -843,7 +845,7 @@ PreservedAnalyses GVNPass::run(Function &F, FunctionAnalysisManager &AM) {
843845
MSSA = &AM.getResult<MemorySSAAnalysis>(F);
844846
}
845847
auto &ORE = AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
846-
bool Changed = runImpl(F, AC, DT, TLI, AA, MemDep, LI, &ORE,
848+
bool Changed = runImpl(F, AC, DT, TLI, TTI, AA, MemDep, LI, &ORE,
847849
MSSA ? &MSSA->getMSSA() : nullptr);
848850
if (!Changed)
849851
return PreservedAnalyses::all();
@@ -2719,6 +2721,16 @@ bool GVNPass::processInstruction(Instruction *I) {
27192721
return false;
27202722
}
27212723

2724+
// If this GVN would effectively hoist the instruction and that's known to be
2725+
// unprofitable, don't do it. Remember the instruction so that it can be used
2726+
// by other instructions in the same block.
2727+
if (auto *ReplI = dyn_cast<Instruction>(I)) {
2728+
if (ReplI->getParent() != I->getParent() && !TTI->isProfitableToHoist(I)) {
2729+
LeaderTable.insert(Num, I, I->getParent());
2730+
return false;
2731+
}
2732+
}
2733+
27222734
// Remove it!
27232735
patchAndReplaceAllUsesWith(I, Repl);
27242736
if (MD && Repl->getType()->isPtrOrPtrVectorTy())
@@ -2729,13 +2741,15 @@ bool GVNPass::processInstruction(Instruction *I) {
27292741

27302742
/// runOnFunction - This is the main transformation entry point for a function.
27312743
bool GVNPass::runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
2732-
const TargetLibraryInfo &RunTLI, AAResults &RunAA,
2744+
const TargetLibraryInfo &RunTLI,
2745+
const TargetTransformInfo &RunTTI, AAResults &RunAA,
27332746
MemoryDependenceResults *RunMD, LoopInfo &LI,
27342747
OptimizationRemarkEmitter *RunORE, MemorySSA *MSSA) {
27352748
AC = &RunAC;
27362749
DT = &RunDT;
27372750
VN.setDomTree(DT);
27382751
TLI = &RunTLI;
2752+
TTI = &RunTTI;
27392753
VN.setAliasAnalysis(&RunAA);
27402754
MD = RunMD;
27412755
ImplicitControlFlowTracking ImplicitCFT;
@@ -3295,6 +3309,7 @@ class llvm::gvn::GVNLegacyPass : public FunctionPass {
32953309
F, getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F),
32963310
getAnalysis<DominatorTreeWrapperPass>().getDomTree(),
32973311
getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F),
3312+
getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F),
32983313
getAnalysis<AAResultsWrapperPass>().getAAResults(),
32993314
Impl.isMemDepEnabled()
33003315
? &getAnalysis<MemoryDependenceWrapperPass>().getMemDep()
@@ -3308,6 +3323,7 @@ class llvm::gvn::GVNLegacyPass : public FunctionPass {
33083323
AU.addRequired<AssumptionCacheTracker>();
33093324
AU.addRequired<DominatorTreeWrapperPass>();
33103325
AU.addRequired<TargetLibraryInfoWrapperPass>();
3326+
AU.addRequired<TargetTransformInfoWrapperPass>();
33113327
AU.addRequired<LoopInfoWrapperPass>();
33123328
if (Impl.isMemDepEnabled())
33133329
AU.addRequired<MemoryDependenceWrapperPass>();

llvm/lib/Transforms/Scalar/LICM.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -467,9 +467,9 @@ bool LoopInvariantCodeMotion::runOnLoop(Loop *L, AAResults *AA, LoopInfo *LI,
467467
MSSAU, &SafetyInfo, Flags, ORE);
468468
Flags.setIsSink(false);
469469
if (Preheader)
470-
Changed |= hoistRegion(DT->getNode(L->getHeader()), AA, LI, DT, AC, TLI, L,
471-
MSSAU, SE, &SafetyInfo, Flags, ORE, LoopNestMode,
472-
LicmAllowSpeculation);
470+
Changed |= hoistRegion(DT->getNode(L->getHeader()), AA, LI, DT, AC, TLI,
471+
TTI, L, MSSAU, SE, &SafetyInfo, Flags, ORE,
472+
LoopNestMode, LicmAllowSpeculation);
473473

474474
// Now that all loop invariants have been removed from the loop, promote any
475475
// memory references to scalars that we can.
@@ -873,9 +873,9 @@ class ControlFlowHoister {
873873
///
874874
bool llvm::hoistRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI,
875875
DominatorTree *DT, AssumptionCache *AC,
876-
TargetLibraryInfo *TLI, Loop *CurLoop,
877-
MemorySSAUpdater &MSSAU, ScalarEvolution *SE,
878-
ICFLoopSafetyInfo *SafetyInfo,
876+
TargetLibraryInfo *TLI, TargetTransformInfo *TTI,
877+
Loop *CurLoop, MemorySSAUpdater &MSSAU,
878+
ScalarEvolution *SE, ICFLoopSafetyInfo *SafetyInfo,
879879
SinkAndHoistLICMFlags &Flags,
880880
OptimizationRemarkEmitter *ORE, bool LoopNestMode,
881881
bool AllowSpeculation) {
@@ -911,11 +911,12 @@ bool llvm::hoistRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI,
911911
// TODO: It may be safe to hoist if we are hoisting to a conditional block
912912
// and we have accurately duplicated the control flow from the loop header
913913
// to that block.
914-
if (CurLoop->hasLoopInvariantOperands(&I) &&
914+
if (TTI->isProfitableToHoist(&I) &&
915+
CurLoop->hasLoopInvariantOperands(&I) &&
915916
canSinkOrHoistInst(I, AA, DT, CurLoop, MSSAU, true, Flags, ORE) &&
916-
isSafeToExecuteUnconditionally(
917-
I, DT, TLI, CurLoop, SafetyInfo, ORE,
918-
Preheader->getTerminator(), AC, AllowSpeculation)) {
917+
isSafeToExecuteUnconditionally(I, DT, TLI, CurLoop, SafetyInfo, ORE,
918+
Preheader->getTerminator(), AC,
919+
AllowSpeculation)) {
919920
hoist(I, DT, CurLoop, CFH.getOrCreateHoistedBlock(BB), SafetyInfo,
920921
MSSAU, SE, ORE);
921922
HoistedInstructions.push_back(&I);

0 commit comments

Comments
 (0)