forked from OSchip/llvm-project
[SROA] Reduce the number of times a IRBuilder is constructed (NFC).
This patch reduces the number of times IRBuilders need to be constructed in SROA.cpp by passing existing ones by reference to the appropriate places.
This commit is contained in:
parent
55d96ac3dc
commit
003ac239d8
|
@ -1264,14 +1264,14 @@ static bool isSafePHIToSpeculate(PHINode &PN) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void speculatePHINodeLoads(PHINode &PN) {
|
static void speculatePHINodeLoads(IRBuilderTy &IRB, PHINode &PN) {
|
||||||
LLVM_DEBUG(dbgs() << " original: " << PN << "\n");
|
LLVM_DEBUG(dbgs() << " original: " << PN << "\n");
|
||||||
|
|
||||||
LoadInst *SomeLoad = cast<LoadInst>(PN.user_back());
|
LoadInst *SomeLoad = cast<LoadInst>(PN.user_back());
|
||||||
Type *LoadTy = SomeLoad->getType();
|
Type *LoadTy = SomeLoad->getType();
|
||||||
IRBuilderTy PHIBuilder(&PN);
|
IRB.SetInsertPoint(&PN);
|
||||||
PHINode *NewPN = PHIBuilder.CreatePHI(LoadTy, PN.getNumIncomingValues(),
|
PHINode *NewPN = IRB.CreatePHI(LoadTy, PN.getNumIncomingValues(),
|
||||||
PN.getName() + ".sroa.speculated");
|
PN.getName() + ".sroa.speculated");
|
||||||
|
|
||||||
// Get the AA tags and alignment to use from one of the loads. It does not
|
// Get the AA tags and alignment to use from one of the loads. It does not
|
||||||
// matter which one we get and if any differ.
|
// matter which one we get and if any differ.
|
||||||
|
@ -1301,9 +1301,9 @@ static void speculatePHINodeLoads(PHINode &PN) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Instruction *TI = Pred->getTerminator();
|
Instruction *TI = Pred->getTerminator();
|
||||||
IRBuilderTy PredBuilder(TI);
|
IRB.SetInsertPoint(TI);
|
||||||
|
|
||||||
LoadInst *Load = PredBuilder.CreateAlignedLoad(
|
LoadInst *Load = IRB.CreateAlignedLoad(
|
||||||
LoadTy, InVal, Alignment,
|
LoadTy, InVal, Alignment,
|
||||||
(PN.getName() + ".sroa.speculate.load." + Pred->getName()));
|
(PN.getName() + ".sroa.speculate.load." + Pred->getName()));
|
||||||
++NumLoadsSpeculated;
|
++NumLoadsSpeculated;
|
||||||
|
@ -1361,10 +1361,10 @@ static bool isSafeSelectToSpeculate(SelectInst &SI) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void speculateSelectInstLoads(SelectInst &SI) {
|
static void speculateSelectInstLoads(IRBuilderTy &IRB, SelectInst &SI) {
|
||||||
LLVM_DEBUG(dbgs() << " original: " << SI << "\n");
|
LLVM_DEBUG(dbgs() << " original: " << SI << "\n");
|
||||||
|
|
||||||
IRBuilderTy IRB(&SI);
|
IRB.SetInsertPoint(&SI);
|
||||||
Value *TV = SI.getTrueValue();
|
Value *TV = SI.getTrueValue();
|
||||||
Value *FV = SI.getFalseValue();
|
Value *FV = SI.getFalseValue();
|
||||||
// Replace the loads of the select with a select of two loads.
|
// Replace the loads of the select with a select of two loads.
|
||||||
|
@ -3223,8 +3223,11 @@ class AggLoadStoreRewriter : public InstVisitor<AggLoadStoreRewriter, bool> {
|
||||||
/// Used to calculate offsets, and hence alignment, of subobjects.
|
/// Used to calculate offsets, and hence alignment, of subobjects.
|
||||||
const DataLayout &DL;
|
const DataLayout &DL;
|
||||||
|
|
||||||
|
IRBuilderTy &IRB;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AggLoadStoreRewriter(const DataLayout &DL) : DL(DL) {}
|
AggLoadStoreRewriter(const DataLayout &DL, IRBuilderTy &IRB)
|
||||||
|
: DL(DL), IRB(IRB) {}
|
||||||
|
|
||||||
/// Rewrite loads and stores through a pointer and all pointers derived from
|
/// Rewrite loads and stores through a pointer and all pointers derived from
|
||||||
/// it.
|
/// it.
|
||||||
|
@ -3255,7 +3258,7 @@ private:
|
||||||
template <typename Derived> class OpSplitter {
|
template <typename Derived> class OpSplitter {
|
||||||
protected:
|
protected:
|
||||||
/// The builder used to form new instructions.
|
/// The builder used to form new instructions.
|
||||||
IRBuilderTy IRB;
|
IRBuilderTy &IRB;
|
||||||
|
|
||||||
/// The indices which to be used with insert- or extractvalue to select the
|
/// The indices which to be used with insert- or extractvalue to select the
|
||||||
/// appropriate value within the aggregate.
|
/// appropriate value within the aggregate.
|
||||||
|
@ -3282,9 +3285,11 @@ private:
|
||||||
/// Initialize the splitter with an insertion point, Ptr and start with a
|
/// Initialize the splitter with an insertion point, Ptr and start with a
|
||||||
/// single zero GEP index.
|
/// single zero GEP index.
|
||||||
OpSplitter(Instruction *InsertionPoint, Value *Ptr, Type *BaseTy,
|
OpSplitter(Instruction *InsertionPoint, Value *Ptr, Type *BaseTy,
|
||||||
Align BaseAlign, const DataLayout &DL)
|
Align BaseAlign, const DataLayout &DL, IRBuilderTy &IRB)
|
||||||
: IRB(InsertionPoint), GEPIndices(1, IRB.getInt32(0)), Ptr(Ptr),
|
: IRB(IRB), GEPIndices(1, IRB.getInt32(0)), Ptr(Ptr), BaseTy(BaseTy),
|
||||||
BaseTy(BaseTy), BaseAlign(BaseAlign), DL(DL) {}
|
BaseAlign(BaseAlign), DL(DL) {
|
||||||
|
IRB.SetInsertPoint(InsertionPoint);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Generic recursive split emission routine.
|
/// Generic recursive split emission routine.
|
||||||
|
@ -3345,9 +3350,10 @@ private:
|
||||||
AAMDNodes AATags;
|
AAMDNodes AATags;
|
||||||
|
|
||||||
LoadOpSplitter(Instruction *InsertionPoint, Value *Ptr, Type *BaseTy,
|
LoadOpSplitter(Instruction *InsertionPoint, Value *Ptr, Type *BaseTy,
|
||||||
AAMDNodes AATags, Align BaseAlign, const DataLayout &DL)
|
AAMDNodes AATags, Align BaseAlign, const DataLayout &DL,
|
||||||
: OpSplitter<LoadOpSplitter>(InsertionPoint, Ptr, BaseTy, BaseAlign,
|
IRBuilderTy &IRB)
|
||||||
DL),
|
: OpSplitter<LoadOpSplitter>(InsertionPoint, Ptr, BaseTy, BaseAlign, DL,
|
||||||
|
IRB),
|
||||||
AATags(AATags) {}
|
AATags(AATags) {}
|
||||||
|
|
||||||
/// Emit a leaf load of a single value. This is called at the leaves of the
|
/// Emit a leaf load of a single value. This is called at the leaves of the
|
||||||
|
@ -3379,7 +3385,7 @@ private:
|
||||||
// We have an aggregate being loaded, split it apart.
|
// We have an aggregate being loaded, split it apart.
|
||||||
LLVM_DEBUG(dbgs() << " original: " << LI << "\n");
|
LLVM_DEBUG(dbgs() << " original: " << LI << "\n");
|
||||||
LoadOpSplitter Splitter(&LI, *U, LI.getType(), LI.getAAMetadata(),
|
LoadOpSplitter Splitter(&LI, *U, LI.getType(), LI.getAAMetadata(),
|
||||||
getAdjustedAlignment(&LI, 0), DL);
|
getAdjustedAlignment(&LI, 0), DL, IRB);
|
||||||
Value *V = UndefValue::get(LI.getType());
|
Value *V = UndefValue::get(LI.getType());
|
||||||
Splitter.emitSplitOps(LI.getType(), V, LI.getName() + ".fca");
|
Splitter.emitSplitOps(LI.getType(), V, LI.getName() + ".fca");
|
||||||
Visited.erase(&LI);
|
Visited.erase(&LI);
|
||||||
|
@ -3390,9 +3396,10 @@ private:
|
||||||
|
|
||||||
struct StoreOpSplitter : public OpSplitter<StoreOpSplitter> {
|
struct StoreOpSplitter : public OpSplitter<StoreOpSplitter> {
|
||||||
StoreOpSplitter(Instruction *InsertionPoint, Value *Ptr, Type *BaseTy,
|
StoreOpSplitter(Instruction *InsertionPoint, Value *Ptr, Type *BaseTy,
|
||||||
AAMDNodes AATags, Align BaseAlign, const DataLayout &DL)
|
AAMDNodes AATags, Align BaseAlign, const DataLayout &DL,
|
||||||
|
IRBuilderTy &IRB)
|
||||||
: OpSplitter<StoreOpSplitter>(InsertionPoint, Ptr, BaseTy, BaseAlign,
|
: OpSplitter<StoreOpSplitter>(InsertionPoint, Ptr, BaseTy, BaseAlign,
|
||||||
DL),
|
DL, IRB),
|
||||||
AATags(AATags) {}
|
AATags(AATags) {}
|
||||||
AAMDNodes AATags;
|
AAMDNodes AATags;
|
||||||
/// Emit a leaf store of a single value. This is called at the leaves of the
|
/// Emit a leaf store of a single value. This is called at the leaves of the
|
||||||
|
@ -3430,7 +3437,7 @@ private:
|
||||||
// We have an aggregate being stored, split it apart.
|
// We have an aggregate being stored, split it apart.
|
||||||
LLVM_DEBUG(dbgs() << " original: " << SI << "\n");
|
LLVM_DEBUG(dbgs() << " original: " << SI << "\n");
|
||||||
StoreOpSplitter Splitter(&SI, *U, V->getType(), SI.getAAMetadata(),
|
StoreOpSplitter Splitter(&SI, *U, V->getType(), SI.getAAMetadata(),
|
||||||
getAdjustedAlignment(&SI, 0), DL);
|
getAdjustedAlignment(&SI, 0), DL, IRB);
|
||||||
Splitter.emitSplitOps(V->getType(), V, V->getName() + ".fca");
|
Splitter.emitSplitOps(V->getType(), V, V->getName() + ".fca");
|
||||||
Visited.erase(&SI);
|
Visited.erase(&SI);
|
||||||
SI.eraseFromParent();
|
SI.eraseFromParent();
|
||||||
|
@ -3458,7 +3465,7 @@ private:
|
||||||
<< "\n original: " << *Sel
|
<< "\n original: " << *Sel
|
||||||
<< "\n " << GEPI);
|
<< "\n " << GEPI);
|
||||||
|
|
||||||
IRBuilderTy Builder(&GEPI);
|
IRB.SetInsertPoint(&GEPI);
|
||||||
SmallVector<Value *, 4> Index(GEPI.indices());
|
SmallVector<Value *, 4> Index(GEPI.indices());
|
||||||
bool IsInBounds = GEPI.isInBounds();
|
bool IsInBounds = GEPI.isInBounds();
|
||||||
|
|
||||||
|
@ -3466,21 +3473,20 @@ private:
|
||||||
Value *True = Sel->getTrueValue();
|
Value *True = Sel->getTrueValue();
|
||||||
Value *NTrue =
|
Value *NTrue =
|
||||||
IsInBounds
|
IsInBounds
|
||||||
? Builder.CreateInBoundsGEP(Ty, True, Index,
|
? IRB.CreateInBoundsGEP(Ty, True, Index,
|
||||||
True->getName() + ".sroa.gep")
|
True->getName() + ".sroa.gep")
|
||||||
: Builder.CreateGEP(Ty, True, Index, True->getName() + ".sroa.gep");
|
: IRB.CreateGEP(Ty, True, Index, True->getName() + ".sroa.gep");
|
||||||
|
|
||||||
Value *False = Sel->getFalseValue();
|
Value *False = Sel->getFalseValue();
|
||||||
|
|
||||||
Value *NFalse =
|
Value *NFalse =
|
||||||
IsInBounds
|
IsInBounds
|
||||||
? Builder.CreateInBoundsGEP(Ty, False, Index,
|
? IRB.CreateInBoundsGEP(Ty, False, Index,
|
||||||
False->getName() + ".sroa.gep")
|
False->getName() + ".sroa.gep")
|
||||||
: Builder.CreateGEP(Ty, False, Index,
|
: IRB.CreateGEP(Ty, False, Index, False->getName() + ".sroa.gep");
|
||||||
False->getName() + ".sroa.gep");
|
|
||||||
|
|
||||||
Value *NSel = Builder.CreateSelect(Sel->getCondition(), NTrue, NFalse,
|
Value *NSel = IRB.CreateSelect(Sel->getCondition(), NTrue, NFalse,
|
||||||
Sel->getName() + ".sroa.sel");
|
Sel->getName() + ".sroa.sel");
|
||||||
Visited.erase(&GEPI);
|
Visited.erase(&GEPI);
|
||||||
GEPI.replaceAllUsesWith(NSel);
|
GEPI.replaceAllUsesWith(NSel);
|
||||||
GEPI.eraseFromParent();
|
GEPI.eraseFromParent();
|
||||||
|
@ -3517,10 +3523,9 @@ private:
|
||||||
|
|
||||||
SmallVector<Value *, 4> Index(GEPI.indices());
|
SmallVector<Value *, 4> Index(GEPI.indices());
|
||||||
bool IsInBounds = GEPI.isInBounds();
|
bool IsInBounds = GEPI.isInBounds();
|
||||||
IRBuilderTy PHIBuilder(GEPI.getParent()->getFirstNonPHI());
|
IRB.SetInsertPoint(GEPI.getParent()->getFirstNonPHI());
|
||||||
PHINode *NewPN = PHIBuilder.CreatePHI(GEPI.getType(),
|
PHINode *NewPN = IRB.CreatePHI(GEPI.getType(), PHI->getNumIncomingValues(),
|
||||||
PHI->getNumIncomingValues(),
|
PHI->getName() + ".sroa.phi");
|
||||||
PHI->getName() + ".sroa.phi");
|
|
||||||
for (unsigned I = 0, E = PHI->getNumIncomingValues(); I != E; ++I) {
|
for (unsigned I = 0, E = PHI->getNumIncomingValues(); I != E; ++I) {
|
||||||
BasicBlock *B = PHI->getIncomingBlock(I);
|
BasicBlock *B = PHI->getIncomingBlock(I);
|
||||||
Value *NewVal = nullptr;
|
Value *NewVal = nullptr;
|
||||||
|
@ -3530,11 +3535,12 @@ private:
|
||||||
} else {
|
} else {
|
||||||
Instruction *In = cast<Instruction>(PHI->getIncomingValue(I));
|
Instruction *In = cast<Instruction>(PHI->getIncomingValue(I));
|
||||||
|
|
||||||
IRBuilderTy B(In->getParent(), std::next(In->getIterator()));
|
IRB.SetInsertPoint(In->getParent(), std::next(In->getIterator()));
|
||||||
Type *Ty = GEPI.getSourceElementType();
|
Type *Ty = GEPI.getSourceElementType();
|
||||||
NewVal = IsInBounds
|
NewVal = IsInBounds ? IRB.CreateInBoundsGEP(Ty, In, Index,
|
||||||
? B.CreateInBoundsGEP(Ty, In, Index, In->getName() + ".sroa.gep")
|
In->getName() + ".sroa.gep")
|
||||||
: B.CreateGEP(Ty, In, Index, In->getName() + ".sroa.gep");
|
: IRB.CreateGEP(Ty, In, Index,
|
||||||
|
In->getName() + ".sroa.gep");
|
||||||
}
|
}
|
||||||
NewPN->addIncoming(NewVal, B);
|
NewPN->addIncoming(NewVal, B);
|
||||||
}
|
}
|
||||||
|
@ -4598,7 +4604,8 @@ bool SROAPass::runOnAlloca(AllocaInst &AI) {
|
||||||
|
|
||||||
// First, split any FCA loads and stores touching this alloca to promote
|
// First, split any FCA loads and stores touching this alloca to promote
|
||||||
// better splitting and promotion opportunities.
|
// better splitting and promotion opportunities.
|
||||||
AggLoadStoreRewriter AggRewriter(DL);
|
IRBuilderTy IRB(&AI);
|
||||||
|
AggLoadStoreRewriter AggRewriter(DL, IRB);
|
||||||
Changed |= AggRewriter.rewrite(AI);
|
Changed |= AggRewriter.rewrite(AI);
|
||||||
|
|
||||||
// Build the slices using a recursive instruction-visiting builder.
|
// Build the slices using a recursive instruction-visiting builder.
|
||||||
|
@ -4633,11 +4640,11 @@ bool SROAPass::runOnAlloca(AllocaInst &AI) {
|
||||||
|
|
||||||
LLVM_DEBUG(dbgs() << " Speculating PHIs\n");
|
LLVM_DEBUG(dbgs() << " Speculating PHIs\n");
|
||||||
while (!SpeculatablePHIs.empty())
|
while (!SpeculatablePHIs.empty())
|
||||||
speculatePHINodeLoads(*SpeculatablePHIs.pop_back_val());
|
speculatePHINodeLoads(IRB, *SpeculatablePHIs.pop_back_val());
|
||||||
|
|
||||||
LLVM_DEBUG(dbgs() << " Speculating Selects\n");
|
LLVM_DEBUG(dbgs() << " Speculating Selects\n");
|
||||||
while (!SpeculatableSelects.empty())
|
while (!SpeculatableSelects.empty())
|
||||||
speculateSelectInstLoads(*SpeculatableSelects.pop_back_val());
|
speculateSelectInstLoads(IRB, *SpeculatableSelects.pop_back_val());
|
||||||
|
|
||||||
return Changed;
|
return Changed;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue