llvm.org GIT mirror llvm / 8a04253
[RS4GC] Use SetVector/MapVector instead of DenseSet/DenseMap to guarantee stable ordering Goal of this change is to guarantee stable ordering of the statepoint arguments and other newly inserted values such as gc.relocates. Previously we had explicit sorting in a couple of places. However for unnamed values ordering was partial and overall we didn't have any strong invariant regarding it. This change switches all data structures to use SetVector's and MapVector's which provide possibility for deterministic iteration over them. Explicit sorting is now redundant and was removed. Differential Revision: http://reviews.llvm.org/D19669 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@268502 91177308-0d34-0410-b5e6-96231b3b80d8 Igor Laevsky 3 years ago
6 changed file(s) with 66 addition(s) and 106 deletion(s). Raw diff Collapse all Expand all
224224 bool operator!=(const SetVector &that) const {
225225 return vector_ != that.vector_;
226226 }
227
228 /// \brief Compute This := This u S, return whether 'This' changed.
229 /// TODO: We should be able to use set_union from SetOperations.h, but
230 /// SetVector interface is inconsistent with DenseSet.
231 template
232 bool set_union(const STy &S) {
233 bool Changed = false;
234
235 for (typename STy::const_iterator SI = S.begin(), SE = S.end(); SI != SE;
236 ++SI)
237 if (insert(*SI))
238 Changed = true;
239
240 return Changed;
241 }
242
243 /// \brief Compute This := This - B
244 /// TODO: We should be able to use set_subtract from SetOperations.h, but
245 /// SetVector interface is inconsistent with DenseSet.
246 template
247 void set_subtract(const STy &S) {
248 for (typename STy::const_iterator SI = S.begin(), SE = S.end(); SI != SE;
249 ++SI)
250 remove(*SI);
251 }
227252
228253 private:
229254 /// \brief A wrapper predicate designed for use with std::remove_if.
136136 namespace {
137137 struct GCPtrLivenessData {
138138 /// Values defined in this block.
139 DenseMap> KillSet;
139 MapVector> KillSet;
140140 /// Values used in this block (and thus live); does not included values
141141 /// killed within this block.
142 DenseMap> LiveSet;
142 MapVector> LiveSet;
143143
144144 /// Values live into this basic block (i.e. used by any
145145 /// instruction in this basic block or ones reachable from here)
146 DenseMap> LiveIn;
146 MapVector> LiveIn;
147147
148148 /// Values live out of this basic block (i.e. live into
149149 /// any successor block)
150 DenseMap> LiveOut;
150 MapVector> LiveOut;
151151 };
152152
153153 // The type of the internal cache used inside the findBasePointers family
160160 // Generally, after the execution of a full findBasePointer call, only the
161161 // base relation will remain. Internally, we add a mixture of the two
162162 // types, then update all the second type to the first type
163 typedef DenseMap DefiningValueMapTy;
164 typedef DenseSet StatepointLiveSetTy;
165 typedef DenseMap, AssertingVH>
163 typedef MapVector DefiningValueMapTy;
164 typedef SetVector StatepointLiveSetTy;
165 typedef MapVector, AssertingVH>
166166 RematerializedValueMapTy;
167167
168168 struct PartiallyConstructedSafepointRecord {
170170 StatepointLiveSetTy LiveSet;
171171
172172 /// Mapping from live pointers to a base-defining-value
173 DenseMap PointerToBase;
173 MapVector PointerToBase;
174174
175175 /// The *new* gc.statepoint instruction itself. This produces the token
176176 /// that normal path gc.relocates and the gc.result are tied to.
261261 }
262262 #endif
263263
264 static bool order_by_name(Value *a, Value *b) {
265 if (a->hasName() && b->hasName()) {
266 return -1 == a->getName().compare(b->getName());
267 } else if (a->hasName() && !b->hasName()) {
268 return true;
269 } else if (!a->hasName() && b->hasName()) {
270 return false;
271 } else {
272 // Better than nothing, but not stable
273 return a < b;
274 }
275 }
276
277264 // Return the name of the value suffixed with the provided value, or if the
278265 // value didn't have a name, the default value specified.
279266 static std::string suffixed_name_or(Value *V, StringRef Suffix,
294281 findLiveSetAtInst(inst, OriginalLivenessData, LiveSet);
295282
296283 if (PrintLiveSet) {
297 // Note: This output is used by several of the test cases
298 // The order of elements in a set is not stable, put them in a vec and sort
299 // by name
300 SmallVector Temp;
301 Temp.insert(Temp.end(), LiveSet.begin(), LiveSet.end());
302 std::sort(Temp.begin(), Temp.end(), order_by_name);
303284 errs() << "Live Variables:\n";
304 for (Value *V : Temp)
285 for (Value *V : LiveSet)
305286 dbgs() << " " << V->getName() << " " << *V << "\n";
306287 }
307288 if (PrintLiveSetSize) {
10621043 // pointer was a base pointer.
10631044 static void
10641045 findBasePointers(const StatepointLiveSetTy &live,
1065 DenseMap &PointerToBase,
1046 MapVector &PointerToBase,
10661047 DominatorTree *DT, DefiningValueMapTy &DVCache) {
1067 // For the naming of values inserted to be deterministic - which makes for
1068 // much cleaner and more stable tests - we need to assign an order to the
1069 // live values. DenseSets do not provide a deterministic order across runs.
1070 SmallVector Temp;
1071 Temp.insert(Temp.end(), live.begin(), live.end());
1072 std::sort(Temp.begin(), Temp.end(), order_by_name);
1073 for (Value *ptr : Temp) {
1048 for (Value *ptr : live) {
10741049 Value *base = findBasePointer(ptr, DVCache);
10751050 assert(base && "failed to find base pointer");
10761051 PointerToBase[ptr] = base;
10941069 static void findBasePointers(DominatorTree &DT, DefiningValueMapTy &DVCache,
10951070 const CallSite &CS,
10961071 PartiallyConstructedSafepointRecord &result) {
1097 DenseMap PointerToBase;
1072 MapVector PointerToBase;
10981073 findBasePointers(result.LiveSet, PointerToBase, &DT, DVCache);
10991074
11001075 if (PrintBasePointers) {
1101 // Note: Need to print these in a stable order since this is checked in
1102 // some tests.
11031076 errs() << "Base Pairs (w/o Relocation):\n";
1104 SmallVector Temp;
1105 Temp.reserve(PointerToBase.size());
1106 for (auto Pair : PointerToBase) {
1107 Temp.push_back(Pair.first);
1108 }
1109 std::sort(Temp.begin(), Temp.end(), order_by_name);
1110 for (Value *Ptr : Temp) {
1111 Value *Base = PointerToBase[Ptr];
1077 for (auto &Pair : PointerToBase) {
11121078 errs() << " derived ";
1113 Ptr->printAsOperand(errs(), false);
1079 Pair.first->printAsOperand(errs(), false);
11141080 errs() << " base ";
1115 Base->printAsOperand(errs(), false);
1081 Pair.second->printAsOperand(errs(), false);
11161082 errs() << "\n";;
11171083 }
11181084 }
15181484 CreateGCRelocates(LiveVariables, LiveStartIdx, BasePtrs, Token, Builder);
15191485 }
15201486
1521 static void StabilizeOrder(SmallVectorImpl &BaseVec,
1522 SmallVectorImpl &LiveVec) {
1523 assert(BaseVec.size() == LiveVec.size());
1524
1525 struct BaseDerivedPair {
1526 Value *Base;
1527 Value *Derived;
1528 };
1529
1530 SmallVector NameOrdering;
1531 NameOrdering.reserve(BaseVec.size());
1532
1533 for (size_t i = 0, e = BaseVec.size(); i < e; i++)
1534 NameOrdering.push_back({BaseVec[i], LiveVec[i]});
1535
1536 std::sort(NameOrdering.begin(), NameOrdering.end(),
1537 [](const BaseDerivedPair &L, const BaseDerivedPair &R) {
1538 return L.Derived->getName() < R.Derived->getName();
1539 });
1540
1541 for (size_t i = 0; i < BaseVec.size(); i++) {
1542 BaseVec[i] = NameOrdering[i].Base;
1543 LiveVec[i] = NameOrdering[i].Derived;
1544 }
1545 }
1546
15471487 // Replace an existing gc.statepoint with a new one and a set of gc.relocates
15481488 // which make the relocations happening at this safepoint explicit.
15491489 //
15671507 BaseVec.push_back(Base);
15681508 }
15691509 assert(LiveVec.size() == BaseVec.size());
1570
1571 // To make the output IR slightly more stable (for use in diffs), ensure a
1572 // fixed order of the values in the safepoint (by sorting the value name).
1573 // The order is otherwise meaningless.
1574 StabilizeOrder(BaseVec, LiveVec);
15751510
15761511 // Do the actual rewriting and delete the old statepoint
15771512 makeStatepointExplicitImpl(CS, BaseVec, LiveVec, Result, Replacements);
20682003
20692004 // Remove rematerializaed values from the live set
20702005 for (auto LiveValue: LiveValuesToBeDeleted) {
2071 Info.LiveSet.erase(LiveValue);
2006 Info.LiveSet.remove(LiveValue);
20722007 }
20732008 }
20742009
21902125 for (auto &Info : Records)
21912126 for (auto &BasePair : Info.PointerToBase)
21922127 if (isa(BasePair.second))
2193 Info.LiveSet.erase(BasePair.first);
2128 Info.LiveSet.remove(BasePair.first);
21942129
21952130 for (CallInst *CI : Holders)
21962131 CI->eraseFromParent();
24802415 /// the live-out set of the basic block
24812416 static void computeLiveInValues(BasicBlock::reverse_iterator rbegin,
24822417 BasicBlock::reverse_iterator rend,
2483 DenseSet &LiveTmp) {
2418 SetVector &LiveTmp) {
24842419
24852420 for (BasicBlock::reverse_iterator ritr = rbegin; ritr != rend; ritr++) {
24862421 Instruction *I = &*ritr;
24872422
24882423 // KILL/Def - Remove this definition from LiveIn
2489 LiveTmp.erase(I);
2424 LiveTmp.remove(I);
24902425
24912426 // Don't consider *uses* in PHI nodes, we handle their contribution to
24922427 // predecessor blocks when we seed the LiveOut sets
25142449 }
25152450 }
25162451
2517 static void computeLiveOutSeed(BasicBlock *BB, DenseSet &LiveTmp) {
2452 static void computeLiveOutSeed(BasicBlock *BB, SetVector &LiveTmp) {
25182453
25192454 for (BasicBlock *Succ : successors(BB)) {
25202455 const BasicBlock::iterator E(Succ->getFirstNonPHI());
25302465 }
25312466 }
25322467
2533 static DenseSet computeKillSet(BasicBlock *BB) {
2534 DenseSet KillSet;
2468 static SetVector computeKillSet(BasicBlock *BB) {
2469 SetVector KillSet;
25352470 for (Instruction &I : *BB)
25362471 if (isHandledGCPointerType(I.getType()))
25372472 KillSet.insert(&I);
25412476 #ifndef NDEBUG
25422477 /// Check that the items in 'Live' dominate 'TI'. This is used as a basic
25432478 /// sanity check for the liveness computation.
2544 static void checkBasicSSA(DominatorTree &DT, DenseSet &Live,
2479 static void checkBasicSSA(DominatorTree &DT, SetVector &Live,
25452480 TerminatorInst *TI, bool TermOkay = false) {
25462481 for (Value *V : Live) {
25472482 if (auto *I = dyn_cast(V)) {
25922527 assert(!Data.LiveSet[&BB].count(Kill) && "live set contains kill");
25932528 #endif
25942529
2595 Data.LiveOut[&BB] = DenseSet();
2530 Data.LiveOut[&BB] = SetVector();
25962531 computeLiveOutSeed(&BB, Data.LiveOut[&BB]);
25972532 Data.LiveIn[&BB] = Data.LiveSet[&BB];
2598 set_union(Data.LiveIn[&BB], Data.LiveOut[&BB]);
2599 set_subtract(Data.LiveIn[&BB], Data.KillSet[&BB]);
2533 Data.LiveIn[&BB].set_union(Data.LiveOut[&BB]);
2534 Data.LiveIn[&BB].set_subtract(Data.KillSet[&BB]);
26002535 if (!Data.LiveIn[&BB].empty())
26012536 AddPredsToWorklist(&BB);
26022537 }
26072542
26082543 // Compute our new liveout set, then exit early if it hasn't changed
26092544 // despite the contribution of our successor.
2610 DenseSet LiveOut = Data.LiveOut[BB];
2545 SetVector LiveOut = Data.LiveOut[BB];
26112546 const auto OldLiveOutSize = LiveOut.size();
26122547 for (BasicBlock *Succ : successors(BB)) {
26132548 assert(Data.LiveIn.count(Succ));
2614 set_union(LiveOut, Data.LiveIn[Succ]);
2549 LiveOut.set_union(Data.LiveIn[Succ]);
26152550 }
26162551 // assert OutLiveOut is a subset of LiveOut
26172552 if (OldLiveOutSize == LiveOut.size()) {
26232558 Data.LiveOut[BB] = LiveOut;
26242559
26252560 // Apply the effects of this basic block
2626 DenseSet LiveTmp = LiveOut;
2627 set_union(LiveTmp, Data.LiveSet[BB]);
2628 set_subtract(LiveTmp, Data.KillSet[BB]);
2561 SetVector LiveTmp = LiveOut;
2562 LiveTmp.set_union(Data.LiveSet[BB]);
2563 LiveTmp.set_subtract(Data.KillSet[BB]);
26292564
26302565 assert(Data.LiveIn.count(BB));
2631 const DenseSet &OldLiveIn = Data.LiveIn[BB];
2566 const SetVector &OldLiveIn = Data.LiveIn[BB];
26322567 // assert: OldLiveIn is a subset of LiveTmp
26332568 if (OldLiveIn.size() != LiveTmp.size()) {
26342569 Data.LiveIn[BB] = LiveTmp;
26522587
26532588 // Note: The copy is intentional and required
26542589 assert(Data.LiveOut.count(BB));
2655 DenseSet LiveOut = Data.LiveOut[BB];
2590 SetVector LiveOut = Data.LiveOut[BB];
26562591
26572592 // We want to handle the statepoint itself oddly. It's
26582593 // call result is not live (normal), nor are it's arguments
26602595 // specifically what we need to relocate
26612596 BasicBlock::reverse_iterator rend(Inst->getIterator());
26622597 computeLiveInValues(BB->rbegin(), rend, LiveOut);
2663 LiveOut.erase(Inst);
2598 LiveOut.remove(Inst);
26642599 Out.insert(LiveOut.begin(), LiveOut.end());
26652600 }
26662601
66 ; CHECK: extractelement
77 ; CHECK: statepoint
88 ; CHECK: gc.relocate
9 ; CHECK-DAG: ; (%base_ee, %obj)
10 ; CHECK: gc.relocate
911 ; CHECK-DAG: ; (%base_ee, %base_ee)
10 ; CHECK: gc.relocate
11 ; CHECK-DAG: ; (%base_ee, %obj)
1212 ; Note that the second extractelement is actually redundant here. A correct output would
1313 ; be to reuse the existing obj as a base since it is actually a base pointer.
1414 entry:
3434 ; CHECK-LABEL: entry:
3535 ; CHECK-NEXT: getelementptr
3636 ; CHECK-NEXT: gc.statepoint
37 ; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
3738 ; CHECK-NEXT: %derived.relocated = call coldcc i8 addrspace(1)*
38 ; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
3939 ; CHECK-NEXT: load i8, i8 addrspace(1)* %derived.relocated
4040 ; CHECK-NEXT: load i8, i8 addrspace(1)* %obj.relocated
4141 ; Tests to make sure we visit both the taken and untaken predeccessor
7575 ; CHECK: addrspacecast i32* %ptr1 to i32 addrspace(1)*
7676 call void @do_safepoint() [ "deopt"() ]
7777
78 ; CHECK: %base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 7, i32 7)
79 ; CHECK: %base.relocated.casted = bitcast i8 addrspace(1)* %base.relocated to i32 addrspace(1)*
80 ; CHECK: %ptr2.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 7, i32 8)
78 ; CHECK: %ptr2.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 8, i32 7)
8179 ; CHECK: %ptr2.relocated.casted = bitcast i8 addrspace(1)* %ptr2.relocated to i32 addrspace(1)*
80 ; CHECK: %base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 8, i32 8)
81 ; CHECK: %base.relocated.casted = bitcast i8 addrspace(1)* %base.relocated to i32 addrspace(1)*
8282 call void @use_obj32(i32 addrspace(1)* %base)
8383 call void @use_obj32(i32 addrspace(1)* %ptr2)
8484 ret void
55 define i64 addrspace(1)* @test_invoke_format(i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1) gc "statepoint-example" personality i32 ()* @personality {
66 ; CHECK-LABEL: @test_invoke_format(
77 ; CHECK-LABEL: entry:
8 ; CHECK: invoke token (i64, i32, i64 addrspace(1)* (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64p1i64f(i64 2882400000, i32 0, i64 addrspace(1)* (i64 addrspace(1)*)* @callee, i32 1, i32 0, i64 addrspace(1)* %obj, i32 0, i32 0, i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1)
8 ; CHECK: invoke token (i64, i32, i64 addrspace(1)* (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64p1i64f(i64 2882400000, i32 0, i64 addrspace(1)* (i64 addrspace(1)*)* @callee, i32 1, i32 0, i64 addrspace(1)* %obj, i32 0, i32 0, i64 addrspace(1)* %obj1, i64 addrspace(1)* %obj)
99 entry:
1010 %ret_val = invoke i64 addrspace(1)* @callee(i64 addrspace(1)* %obj)
1111 to label %normal_return unwind label %exceptional_return