Skip to content

Commit 5b59b3a

Browse files
authored
[NFC][RemoveDIs] Switch constant-hoisting to insert with iterators (#84738)
Seeing how constant-hoisting also happens to store an insertion-point in a DenseMap, this means we have to install DenseMapInfo for hashing BasicBlock::iterators and comparing them. I'm not really sure where to put the DenseMapInfo declarations as BasicBlock.h seems most logical, but that then means including DenseMap.h into pretty much all of LLVM. I've sent this up to the compile time tracker to see whether there's a major cost from this. --------- Merged by: Stephen Tozer <[email protected]>
1 parent 835c1b5 commit 5b59b3a

File tree

3 files changed

+61
-30
lines changed

3 files changed

+61
-30
lines changed

llvm/include/llvm/IR/BasicBlock.h

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@
1414
#define LLVM_IR_BASICBLOCK_H
1515

1616
#include "llvm-c/Types.h"
17+
#include "llvm/ADT/DenseMap.h"
1718
#include "llvm/ADT/Twine.h"
1819
#include "llvm/ADT/ilist.h"
1920
#include "llvm/ADT/ilist_node.h"
2021
#include "llvm/ADT/iterator.h"
2122
#include "llvm/ADT/iterator_range.h"
2223
#include "llvm/IR/DebugProgramInstruction.h"
2324
#include "llvm/IR/Instruction.h"
24-
#include "llvm/IR/DebugProgramInstruction.h"
2525
#include "llvm/IR/SymbolTableListTraits.h"
2626
#include "llvm/IR/Value.h"
2727
#include <cassert>
@@ -774,6 +774,32 @@ BasicBlock::iterator skipDebugIntrinsics(BasicBlock::iterator It);
774774
inline void BasicBlock::validateInstrOrdering() const {}
775775
#endif
776776

777+
// Specialize DenseMapInfo for iterators, so that ththey can be installed into
778+
// maps and sets. The iterator is made up of its node pointer, and the
779+
// debug-info "head" bit.
780+
template <> struct DenseMapInfo<BasicBlock::iterator> {
781+
static inline BasicBlock::iterator getEmptyKey() {
782+
return BasicBlock::iterator(nullptr);
783+
}
784+
785+
static inline BasicBlock::iterator getTombstoneKey() {
786+
BasicBlock::iterator It(nullptr);
787+
It.setHeadBit(true);
788+
return It;
789+
}
790+
791+
static unsigned getHashValue(const BasicBlock::iterator &It) {
792+
return DenseMapInfo<void *>::getHashValue(
793+
reinterpret_cast<void *>(It.getNodePtr())) ^
794+
It.getHeadBit();
795+
}
796+
797+
static bool isEqual(const BasicBlock::iterator &LHS,
798+
const BasicBlock::iterator &RHS) {
799+
return LHS == RHS && LHS.getHeadBit() == RHS.getHeadBit();
800+
}
801+
};
802+
777803
} // end namespace llvm
778804

779805
#endif // LLVM_IR_BASICBLOCK_H

llvm/include/llvm/Transforms/Scalar/ConstantHoisting.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -172,11 +172,12 @@ class ConstantHoistingPass : public PassInfoMixin<ConstantHoistingPass> {
172172

173173
void collectMatInsertPts(
174174
const consthoist::RebasedConstantListType &RebasedConstants,
175-
SmallVectorImpl<Instruction *> &MatInsertPts) const;
176-
Instruction *findMatInsertPt(Instruction *Inst, unsigned Idx = ~0U) const;
177-
SetVector<Instruction *>
178-
findConstantInsertionPoint(const consthoist::ConstantInfo &ConstInfo,
179-
const ArrayRef<Instruction *> MatInsertPts) const;
175+
SmallVectorImpl<BasicBlock::iterator> &MatInsertPts) const;
176+
BasicBlock::iterator findMatInsertPt(Instruction *Inst,
177+
unsigned Idx = ~0U) const;
178+
SetVector<BasicBlock::iterator> findConstantInsertionPoint(
179+
const consthoist::ConstantInfo &ConstInfo,
180+
const ArrayRef<BasicBlock::iterator> MatInsertPts) const;
180181
void collectConstantCandidates(ConstCandMapType &ConstCandMap,
181182
Instruction *Inst, unsigned Idx,
182183
ConstantInt *ConstInt);
@@ -203,9 +204,9 @@ class ConstantHoistingPass : public PassInfoMixin<ConstantHoistingPass> {
203204
struct UserAdjustment {
204205
Constant *Offset;
205206
Type *Ty;
206-
Instruction *MatInsertPt;
207+
BasicBlock::iterator MatInsertPt;
207208
const consthoist::ConstantUser User;
208-
UserAdjustment(Constant *O, Type *T, Instruction *I,
209+
UserAdjustment(Constant *O, Type *T, BasicBlock::iterator I,
209210
consthoist::ConstantUser U)
210211
: Offset(O), Ty(T), MatInsertPt(I), User(U) {}
211212
};

llvm/lib/Transforms/Scalar/ConstantHoisting.cpp

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -162,27 +162,27 @@ bool ConstantHoistingLegacyPass::runOnFunction(Function &Fn) {
162162

163163
void ConstantHoistingPass::collectMatInsertPts(
164164
const RebasedConstantListType &RebasedConstants,
165-
SmallVectorImpl<Instruction *> &MatInsertPts) const {
165+
SmallVectorImpl<BasicBlock::iterator> &MatInsertPts) const {
166166
for (const RebasedConstantInfo &RCI : RebasedConstants)
167167
for (const ConstantUser &U : RCI.Uses)
168168
MatInsertPts.emplace_back(findMatInsertPt(U.Inst, U.OpndIdx));
169169
}
170170

171171
/// Find the constant materialization insertion point.
172-
Instruction *ConstantHoistingPass::findMatInsertPt(Instruction *Inst,
173-
unsigned Idx) const {
172+
BasicBlock::iterator ConstantHoistingPass::findMatInsertPt(Instruction *Inst,
173+
unsigned Idx) const {
174174
// If the operand is a cast instruction, then we have to materialize the
175175
// constant before the cast instruction.
176176
if (Idx != ~0U) {
177177
Value *Opnd = Inst->getOperand(Idx);
178178
if (auto CastInst = dyn_cast<Instruction>(Opnd))
179179
if (CastInst->isCast())
180-
return CastInst;
180+
return CastInst->getIterator();
181181
}
182182

183183
// The simple and common case. This also includes constant expressions.
184184
if (!isa<PHINode>(Inst) && !Inst->isEHPad())
185-
return Inst;
185+
return Inst->getIterator();
186186

187187
// We can't insert directly before a phi node or an eh pad. Insert before
188188
// the terminator of the incoming or dominating block.
@@ -191,7 +191,7 @@ Instruction *ConstantHoistingPass::findMatInsertPt(Instruction *Inst,
191191
if (Idx != ~0U && isa<PHINode>(Inst)) {
192192
InsertionBlock = cast<PHINode>(Inst)->getIncomingBlock(Idx);
193193
if (!InsertionBlock->isEHPad()) {
194-
return InsertionBlock->getTerminator();
194+
return InsertionBlock->getTerminator()->getIterator();
195195
}
196196
} else {
197197
InsertionBlock = Inst->getParent();
@@ -206,7 +206,7 @@ Instruction *ConstantHoistingPass::findMatInsertPt(Instruction *Inst,
206206
IDom = IDom->getIDom();
207207
}
208208

209-
return IDom->getBlock()->getTerminator();
209+
return IDom->getBlock()->getTerminator()->getIterator();
210210
}
211211

212212
/// Given \p BBs as input, find another set of BBs which collectively
@@ -314,26 +314,27 @@ static void findBestInsertionSet(DominatorTree &DT, BlockFrequencyInfo &BFI,
314314
}
315315

316316
/// Find an insertion point that dominates all uses.
317-
SetVector<Instruction *> ConstantHoistingPass::findConstantInsertionPoint(
317+
SetVector<BasicBlock::iterator>
318+
ConstantHoistingPass::findConstantInsertionPoint(
318319
const ConstantInfo &ConstInfo,
319-
const ArrayRef<Instruction *> MatInsertPts) const {
320+
const ArrayRef<BasicBlock::iterator> MatInsertPts) const {
320321
assert(!ConstInfo.RebasedConstants.empty() && "Invalid constant info entry.");
321322
// Collect all basic blocks.
322323
SetVector<BasicBlock *> BBs;
323-
SetVector<Instruction *> InsertPts;
324+
SetVector<BasicBlock::iterator> InsertPts;
324325

325-
for (Instruction *MatInsertPt : MatInsertPts)
326+
for (BasicBlock::iterator MatInsertPt : MatInsertPts)
326327
BBs.insert(MatInsertPt->getParent());
327328

328329
if (BBs.count(Entry)) {
329-
InsertPts.insert(&Entry->front());
330+
InsertPts.insert(Entry->begin());
330331
return InsertPts;
331332
}
332333

333334
if (BFI) {
334335
findBestInsertionSet(*DT, *BFI, Entry, BBs);
335336
for (BasicBlock *BB : BBs)
336-
InsertPts.insert(&*BB->getFirstInsertionPt());
337+
InsertPts.insert(BB->getFirstInsertionPt());
337338
return InsertPts;
338339
}
339340

@@ -343,7 +344,7 @@ SetVector<Instruction *> ConstantHoistingPass::findConstantInsertionPoint(
343344
BB2 = BBs.pop_back_val();
344345
BB = DT->findNearestCommonDominator(BB1, BB2);
345346
if (BB == Entry) {
346-
InsertPts.insert(&Entry->front());
347+
InsertPts.insert(Entry->begin());
347348
return InsertPts;
348349
}
349350
BBs.insert(BB);
@@ -764,11 +765,13 @@ void ConstantHoistingPass::emitBaseConstants(Instruction *Base,
764765
Mat = GetElementPtrInst::Create(Type::getInt8Ty(*Ctx), Base, Adj->Offset,
765766
"mat_gep", Adj->MatInsertPt);
766767
// Hide it behind a bitcast.
767-
Mat = new BitCastInst(Mat, Adj->Ty, "mat_bitcast", Adj->MatInsertPt);
768+
Mat = new BitCastInst(Mat, Adj->Ty, "mat_bitcast",
769+
Adj->MatInsertPt->getIterator());
768770
} else
769771
// Constant being rebased is a ConstantInt.
770-
Mat = BinaryOperator::Create(Instruction::Add, Base, Adj->Offset,
771-
"const_mat", Adj->MatInsertPt);
772+
Mat =
773+
BinaryOperator::Create(Instruction::Add, Base, Adj->Offset,
774+
"const_mat", Adj->MatInsertPt->getIterator());
772775

773776
LLVM_DEBUG(dbgs() << "Materialize constant (" << *Base->getOperand(0)
774777
<< " + " << *Adj->Offset << ") in BB "
@@ -819,7 +822,8 @@ void ConstantHoistingPass::emitBaseConstants(Instruction *Base,
819822

820823
// Aside from constant GEPs, only constant cast expressions are collected.
821824
assert(ConstExpr->isCast() && "ConstExpr should be a cast");
822-
Instruction *ConstExprInst = ConstExpr->getAsInstruction(Adj->MatInsertPt);
825+
Instruction *ConstExprInst = ConstExpr->getAsInstruction();
826+
ConstExprInst->insertBefore(Adj->MatInsertPt);
823827
ConstExprInst->setOperand(0, Mat);
824828

825829
// Use the same debug location as the instruction we are about to update.
@@ -845,9 +849,9 @@ bool ConstantHoistingPass::emitBaseConstants(GlobalVariable *BaseGV) {
845849
SmallVectorImpl<consthoist::ConstantInfo> &ConstInfoVec =
846850
BaseGV ? ConstGEPInfoMap[BaseGV] : ConstIntInfoVec;
847851
for (const consthoist::ConstantInfo &ConstInfo : ConstInfoVec) {
848-
SmallVector<Instruction *, 4> MatInsertPts;
852+
SmallVector<BasicBlock::iterator, 4> MatInsertPts;
849853
collectMatInsertPts(ConstInfo.RebasedConstants, MatInsertPts);
850-
SetVector<Instruction *> IPSet =
854+
SetVector<BasicBlock::iterator> IPSet =
851855
findConstantInsertionPoint(ConstInfo, MatInsertPts);
852856
// We can have an empty set if the function contains unreachable blocks.
853857
if (IPSet.empty())
@@ -856,15 +860,15 @@ bool ConstantHoistingPass::emitBaseConstants(GlobalVariable *BaseGV) {
856860
unsigned UsesNum = 0;
857861
unsigned ReBasesNum = 0;
858862
unsigned NotRebasedNum = 0;
859-
for (Instruction *IP : IPSet) {
863+
for (const BasicBlock::iterator &IP : IPSet) {
860864
// First, collect constants depending on this IP of the base.
861865
UsesNum = 0;
862866
SmallVector<UserAdjustment, 4> ToBeRebased;
863867
unsigned MatCtr = 0;
864868
for (auto const &RCI : ConstInfo.RebasedConstants) {
865869
UsesNum += RCI.Uses.size();
866870
for (auto const &U : RCI.Uses) {
867-
Instruction *MatInsertPt = MatInsertPts[MatCtr++];
871+
const BasicBlock::iterator &MatInsertPt = MatInsertPts[MatCtr++];
868872
BasicBlock *OrigMatInsertBB = MatInsertPt->getParent();
869873
// If Base constant is to be inserted in multiple places,
870874
// generate rebase for U using the Base dominating U.

0 commit comments

Comments
 (0)