Skip to content

Commit 74e3aef

Browse files
committed
Changes to make Float-to-int scalar transform codegen deterministic
1 parent 76f71dd commit 74e3aef

File tree

2 files changed

+42
-7
lines changed

2 files changed

+42
-7
lines changed

llvm/include/llvm/Transforms/Scalar/Float2Int.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,25 @@ class LLVMContext;
2828
class Type;
2929
class Value;
3030

31+
class OrderedInstruction {
32+
Instruction *Ins;
33+
unsigned int Order;
34+
35+
public:
36+
OrderedInstruction(Instruction *Inst, unsigned int Ord) : Ins(Inst), Order(Ord) {}
37+
38+
Instruction *getInstruction() { return Ins; }
39+
unsigned int getOrder() { return Order; }
40+
};
41+
42+
template <class T> struct OrderedInstructionLess {
43+
bool operator()(const T &lhs, const T &rhs) const {
44+
OrderedInstruction lhsOrder = lhs;
45+
OrderedInstruction rhsOrder = rhs;
46+
return rhsOrder.getOrder() < lhsOrder.getOrder();
47+
}
48+
};
49+
3150
class Float2IntPass : public PassInfoMixin<Float2IntPass> {
3251
public:
3352
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
@@ -36,6 +55,7 @@ class Float2IntPass : public PassInfoMixin<Float2IntPass> {
3655
bool runImpl(Function &F, const DominatorTree &DT);
3756

3857
private:
58+
unsigned int insOrder(Instruction *I);
3959
void findRoots(Function &F, const DominatorTree &DT);
4060
void seen(Instruction *I, ConstantRange R);
4161
ConstantRange badRange();
@@ -50,7 +70,9 @@ class Float2IntPass : public PassInfoMixin<Float2IntPass> {
5070

5171
MapVector<Instruction *, ConstantRange> SeenInsts;
5272
SmallSetVector<Instruction *, 8> Roots;
53-
EquivalenceClasses<Instruction *> ECs;
73+
EquivalenceClasses<OrderedInstruction,
74+
OrderedInstructionLess<OrderedInstruction>> ECs;
75+
MapVector<Instruction *, unsigned int> InstructionOrders;
5476
MapVector<Instruction *, Value *> ConvertedInsts;
5577
LLVMContext *Ctx;
5678
};

llvm/lib/Transforms/Scalar/Float2Int.cpp

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,16 @@ static Instruction::BinaryOps mapBinOpcode(unsigned Opcode) {
8484
}
8585
}
8686

87+
// Instruction order - return deterministic order suitable as set
88+
// order for EquivalenceClasses.
89+
unsigned int Float2IntPass::insOrder(Instruction* I) {
90+
static unsigned int order = 0;
91+
if (InstructionOrders.find(I) != InstructionOrders.end())
92+
return InstructionOrders[I];
93+
InstructionOrders[I] = order++;
94+
return order - 1;
95+
}
96+
8797
// Find the roots - instructions that convert from the FP domain to
8898
// integer domain.
8999
void Float2IntPass::findRoots(Function &F, const DominatorTree &DT) {
@@ -191,7 +201,7 @@ void Float2IntPass::walkBackwards() {
191201
for (Value *O : I->operands()) {
192202
if (Instruction *OI = dyn_cast<Instruction>(O)) {
193203
// Unify def-use chains if they interfere.
194-
ECs.unionSets(I, OI);
204+
ECs.unionSets(OrderedInstruction(I, insOrder(I)), OrderedInstruction(OI, insOrder(OI)));
195205
if (SeenInsts.find(I)->second != badRange())
196206
Worklist.push_back(OI);
197207
} else if (!isa<ConstantFP>(O)) {
@@ -323,7 +333,8 @@ bool Float2IntPass::validateAndTransform(const DataLayout &DL) {
323333
// For every member of the partition, union all the ranges together.
324334
for (auto MI = ECs.member_begin(It), ME = ECs.member_end();
325335
MI != ME; ++MI) {
326-
Instruction *I = *MI;
336+
OrderedInstruction OMI = *MI;
337+
Instruction *I = OMI.getInstruction();
327338
auto SeenI = SeenInsts.find(I);
328339
if (SeenI == SeenInsts.end())
329340
continue;
@@ -392,9 +403,10 @@ bool Float2IntPass::validateAndTransform(const DataLayout &DL) {
392403
}
393404
}
394405

395-
for (auto MI = ECs.member_begin(It), ME = ECs.member_end();
396-
MI != ME; ++MI)
397-
convert(*MI, Ty);
406+
for (auto MI = ECs.member_begin(It), ME = ECs.member_end(); MI != ME; ++MI) {
407+
OrderedInstruction OMI = *MI;
408+
convert(OMI.getInstruction(), Ty);
409+
}
398410
MadeChange = true;
399411
}
400412

@@ -485,8 +497,9 @@ void Float2IntPass::cleanup() {
485497
bool Float2IntPass::runImpl(Function &F, const DominatorTree &DT) {
486498
LLVM_DEBUG(dbgs() << "F2I: Looking at function " << F.getName() << "\n");
487499
// Clear out all state.
488-
ECs = EquivalenceClasses<Instruction*>();
500+
ECs = EquivalenceClasses<OrderedInstruction, OrderedInstructionLess<OrderedInstruction> >();
489501
SeenInsts.clear();
502+
InstructionOrders.clear();
490503
ConvertedInsts.clear();
491504
Roots.clear();
492505

0 commit comments

Comments
 (0)