]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/IR/SafepointIRVerifier.cpp
Vendor import of llvm trunk r307894:
[FreeBSD/FreeBSD.git] / lib / IR / SafepointIRVerifier.cpp
1 //===-- SafepointIRVerifier.cpp - Verify gc.statepoint invariants ---------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Run a sanity check on the IR to ensure that Safepoints - if they've been
11 // inserted - were inserted correctly.  In particular, look for use of
12 // non-relocated values after a safepoint.  It's primary use is to check the
13 // correctness of safepoint insertion immediately after insertion, but it can
14 // also be used to verify that later transforms have not found a way to break
15 // safepoint semenatics.
16 //
17 // In its current form, this verify checks a property which is sufficient, but
18 // not neccessary for correctness.  There are some cases where an unrelocated
19 // pointer can be used after the safepoint.  Consider this example:
20 //
21 //    a = ...
22 //    b = ...
23 //    (a',b') = safepoint(a,b)
24 //    c = cmp eq a b
25 //    br c, ..., ....
26 //
27 // Because it is valid to reorder 'c' above the safepoint, this is legal.  In
28 // practice, this is a somewhat uncommon transform, but CodeGenPrep does create
29 // idioms like this.  The verifier knows about these cases and avoids reporting
30 // false positives.
31 //
32 //===----------------------------------------------------------------------===//
33
34 #include "llvm/ADT/DenseSet.h"
35 #include "llvm/ADT/SetOperations.h"
36 #include "llvm/ADT/SetVector.h"
37 #include "llvm/IR/BasicBlock.h"
38 #include "llvm/IR/Dominators.h"
39 #include "llvm/IR/Function.h"
40 #include "llvm/IR/Instructions.h"
41 #include "llvm/IR/Intrinsics.h"
42 #include "llvm/IR/IntrinsicInst.h"
43 #include "llvm/IR/Module.h"
44 #include "llvm/IR/Value.h"
45 #include "llvm/IR/SafepointIRVerifier.h"
46 #include "llvm/IR/Statepoint.h"
47 #include "llvm/Support/Debug.h"
48 #include "llvm/Support/CommandLine.h"
49 #include "llvm/Support/raw_ostream.h"
50
51 #define DEBUG_TYPE "safepoint-ir-verifier"
52
53 using namespace llvm;
54
55 /// This option is used for writing test cases.  Instead of crashing the program
56 /// when verification fails, report a message to the console (for FileCheck
57 /// usage) and continue execution as if nothing happened.
58 static cl::opt<bool> PrintOnly("safepoint-ir-verifier-print-only",
59                                cl::init(false));
60
61 static void Verify(const Function &F, const DominatorTree &DT);
62
63 struct SafepointIRVerifier : public FunctionPass {
64   static char ID; // Pass identification, replacement for typeid
65   DominatorTree DT;
66   SafepointIRVerifier() : FunctionPass(ID) {
67     initializeSafepointIRVerifierPass(*PassRegistry::getPassRegistry());
68   }
69
70   bool runOnFunction(Function &F) override {
71     DT.recalculate(F);
72     Verify(F, DT);
73     return false; // no modifications
74   }
75
76   void getAnalysisUsage(AnalysisUsage &AU) const override {
77     AU.setPreservesAll();
78   }
79
80   StringRef getPassName() const override { return "safepoint verifier"; }
81 };
82
83 void llvm::verifySafepointIR(Function &F) {
84   SafepointIRVerifier pass;
85   pass.runOnFunction(F);
86 }
87
88 char SafepointIRVerifier::ID = 0;
89
90 FunctionPass *llvm::createSafepointIRVerifierPass() {
91   return new SafepointIRVerifier();
92 }
93
94 INITIALIZE_PASS_BEGIN(SafepointIRVerifier, "verify-safepoint-ir",
95                       "Safepoint IR Verifier", false, true)
96 INITIALIZE_PASS_END(SafepointIRVerifier, "verify-safepoint-ir",
97                     "Safepoint IR Verifier", false, true)
98
99 static bool isGCPointerType(Type *T) {
100   if (auto *PT = dyn_cast<PointerType>(T))
101     // For the sake of this example GC, we arbitrarily pick addrspace(1) as our
102     // GC managed heap.  We know that a pointer into this heap needs to be
103     // updated and that no other pointer does.
104     return (1 == PT->getAddressSpace());
105   return false;
106 }
107
108 static bool containsGCPtrType(Type *Ty) {
109   if (isGCPointerType(Ty))
110     return true;
111   if (VectorType *VT = dyn_cast<VectorType>(Ty))
112     return isGCPointerType(VT->getScalarType());
113   if (ArrayType *AT = dyn_cast<ArrayType>(Ty))
114     return containsGCPtrType(AT->getElementType());
115   if (StructType *ST = dyn_cast<StructType>(Ty))
116     return std::any_of(ST->subtypes().begin(), ST->subtypes().end(),
117                        containsGCPtrType);
118   return false;
119 }
120
121 // Debugging aid -- prints a [Begin, End) range of values.
122 template<typename IteratorTy>
123 static void PrintValueSet(raw_ostream &OS, IteratorTy Begin, IteratorTy End) {
124   OS << "[ ";
125   while (Begin != End) {
126     OS << **Begin << " ";
127     ++Begin;
128   }
129   OS << "]";
130 }
131
132 /// The verifier algorithm is phrased in terms of availability.  The set of
133 /// values "available" at a given point in the control flow graph is the set of
134 /// correctly relocated value at that point, and is a subset of the set of
135 /// definitions dominating that point.
136
137 /// State we compute and track per basic block.
138 struct BasicBlockState {
139   // Set of values available coming in, before the phi nodes
140   DenseSet<const Value *> AvailableIn;
141
142   // Set of values available going out
143   DenseSet<const Value *> AvailableOut;
144
145   // AvailableOut minus AvailableIn.
146   // All elements are Instructions
147   DenseSet<const Value *> Contribution;
148
149   // True if this block contains a safepoint and thus AvailableIn does not
150   // contribute to AvailableOut.
151   bool Cleared = false;
152 };
153
154
155 /// Gather all the definitions dominating the start of BB into Result.  This is
156 /// simply the Defs introduced by every dominating basic block and the function
157 /// arguments.
158 static void GatherDominatingDefs(const BasicBlock *BB,
159                                  DenseSet<const Value *> &Result,
160                                  const DominatorTree &DT,
161                     DenseMap<const BasicBlock *, BasicBlockState *> &BlockMap) {
162   DomTreeNode *DTN = DT[const_cast<BasicBlock *>(BB)];
163
164   while (DTN->getIDom()) {
165     DTN = DTN->getIDom();
166     const auto &Defs = BlockMap[DTN->getBlock()]->Contribution;
167     Result.insert(Defs.begin(), Defs.end());
168     // If this block is 'Cleared', then nothing LiveIn to this block can be
169     // available after this block completes.  Note: This turns out to be 
170     // really important for reducing memory consuption of the initial available
171     // sets and thus peak memory usage by this verifier.
172     if (BlockMap[DTN->getBlock()]->Cleared)
173       return;
174   }
175
176   for (const Argument &A : BB->getParent()->args())
177     if (containsGCPtrType(A.getType()))
178       Result.insert(&A);
179 }
180
181 /// Model the effect of an instruction on the set of available values.
182 static void TransferInstruction(const Instruction &I, bool &Cleared,
183                               DenseSet<const Value *> &Available) {
184   if (isStatepoint(I)) {
185     Cleared = true;
186     Available.clear();
187   } else if (containsGCPtrType(I.getType()))
188     Available.insert(&I);
189 }
190
191 /// Compute the AvailableOut set for BB, based on the
192 /// BasicBlockState BBS, which is the BasicBlockState for BB. FirstPass is set
193 /// when the verifier runs for the first time computing the AvailableOut set
194 /// for BB.
195 static void TransferBlock(const BasicBlock *BB,
196                           BasicBlockState &BBS, bool FirstPass) {
197
198   const DenseSet<const Value *> &AvailableIn = BBS.AvailableIn; 
199   DenseSet<const Value *> &AvailableOut  = BBS.AvailableOut;
200
201   if (BBS.Cleared) {
202     // AvailableOut does not change no matter how the input changes, just
203     // leave it be.  We need to force this calculation the first time so that
204     // we have a AvailableOut at all.
205     if (FirstPass) {
206       AvailableOut = BBS.Contribution;
207     }
208   } else {
209     // Otherwise, we need to reduce the AvailableOut set by things which are no
210     // longer in our AvailableIn
211     DenseSet<const Value *> Temp = BBS.Contribution;
212     set_union(Temp, AvailableIn);
213     AvailableOut = std::move(Temp);
214   }
215
216   DEBUG(dbgs() << "Transfered block " << BB->getName() << " from ";
217         PrintValueSet(dbgs(), AvailableIn.begin(), AvailableIn.end());
218         dbgs() << " to ";
219         PrintValueSet(dbgs(), AvailableOut.begin(), AvailableOut.end());
220         dbgs() << "\n";);
221 }
222
223 /// A given derived pointer can have multiple base pointers through phi/selects.
224 /// This type indicates when the base pointer is exclusively constant
225 /// (ExclusivelySomeConstant), and if that constant is proven to be exclusively
226 /// null, we record that as ExclusivelyNull. In all other cases, the BaseType is
227 /// NonConstant.
228 enum BaseType {
229   NonConstant = 1, // Base pointers is not exclusively constant.
230   ExclusivelyNull,
231   ExclusivelySomeConstant // Base pointers for a given derived pointer is from a
232                           // set of constants, but they are not exclusively
233                           // null.
234 };
235
236 /// Return the baseType for Val which states whether Val is exclusively
237 /// derived from constant/null, or not exclusively derived from constant.
238 /// Val is exclusively derived off a constant base when all operands of phi and
239 /// selects are derived off a constant base.
240 static enum BaseType getBaseType(const Value *Val) {
241
242   SmallVector<const Value *, 32> Worklist;
243   DenseSet<const Value *> Visited;
244   bool isExclusivelyDerivedFromNull = true;
245   Worklist.push_back(Val);
246   // Strip through all the bitcasts and geps to get base pointer. Also check for
247   // the exclusive value when there can be multiple base pointers (through phis
248   // or selects).
249   while(!Worklist.empty()) {
250     const Value *V = Worklist.pop_back_val();
251     if (!Visited.insert(V).second)
252       continue;
253
254     if (const auto *CI = dyn_cast<CastInst>(V)) {
255       Worklist.push_back(CI->stripPointerCasts());
256       continue;
257     }
258     if (const auto *GEP = dyn_cast<GetElementPtrInst>(V)) {
259       Worklist.push_back(GEP->getPointerOperand());
260       continue;
261     }
262     // Push all the incoming values of phi node into the worklist for
263     // processing.
264     if (const auto *PN = dyn_cast<PHINode>(V)) {
265       for (Value *InV: PN->incoming_values())
266         Worklist.push_back(InV);
267       continue;
268     }
269     if (const auto *SI = dyn_cast<SelectInst>(V)) {
270       // Push in the true and false values
271       Worklist.push_back(SI->getTrueValue());
272       Worklist.push_back(SI->getFalseValue());
273       continue;
274     }
275     if (isa<Constant>(V)) {
276       // We found at least one base pointer which is non-null, so this derived
277       // pointer is not exclusively derived from null.
278       if (V != Constant::getNullValue(V->getType()))
279         isExclusivelyDerivedFromNull = false;
280       // Continue processing the remaining values to make sure it's exclusively
281       // constant.
282       continue;
283     }
284     // At this point, we know that the base pointer is not exclusively
285     // constant.
286     return BaseType::NonConstant;
287   }
288   // Now, we know that the base pointer is exclusively constant, but we need to
289   // differentiate between exclusive null constant and non-null constant.
290   return isExclusivelyDerivedFromNull ? BaseType::ExclusivelyNull
291                                       : BaseType::ExclusivelySomeConstant;
292 }
293
294 static void Verify(const Function &F, const DominatorTree &DT) {
295   SpecificBumpPtrAllocator<BasicBlockState> BSAllocator;
296   DenseMap<const BasicBlock *, BasicBlockState *> BlockMap;
297  
298   DEBUG(dbgs() << "Verifying gc pointers in function: " << F.getName() << "\n");
299   if (PrintOnly)
300     dbgs() << "Verifying gc pointers in function: " << F.getName() << "\n";
301
302
303   for (const BasicBlock &BB : F) {
304     BasicBlockState *BBS = new(BSAllocator.Allocate()) BasicBlockState;
305     for (const auto &I : BB)
306       TransferInstruction(I, BBS->Cleared, BBS->Contribution);
307     BlockMap[&BB] = BBS;
308   }
309
310   for (auto &BBI : BlockMap) {
311     GatherDominatingDefs(BBI.first, BBI.second->AvailableIn, DT, BlockMap);
312     TransferBlock(BBI.first, *BBI.second, true);
313   }
314
315   SetVector<const BasicBlock *> Worklist;
316   for (auto &BBI : BlockMap)
317     Worklist.insert(BBI.first);
318
319   // This loop iterates the AvailableIn and AvailableOut sets to a fixed point.
320   // The AvailableIn and AvailableOut sets decrease as we iterate.
321   while (!Worklist.empty()) {
322     const BasicBlock *BB = Worklist.pop_back_val();
323     BasicBlockState *BBS = BlockMap[BB];
324
325     size_t OldInCount = BBS->AvailableIn.size();
326     for (const BasicBlock *PBB : predecessors(BB))
327       set_intersect(BBS->AvailableIn, BlockMap[PBB]->AvailableOut);
328
329     if (OldInCount == BBS->AvailableIn.size())
330       continue;
331
332     assert(OldInCount > BBS->AvailableIn.size() && "invariant!");
333
334     size_t OldOutCount = BBS->AvailableOut.size();
335     TransferBlock(BB, *BBS, false);
336     if (OldOutCount != BBS->AvailableOut.size()) {
337       assert(OldOutCount > BBS->AvailableOut.size() && "invariant!");
338       Worklist.insert(succ_begin(BB), succ_end(BB));
339     }
340   }
341
342   // We now have all the information we need to decide if the use of a heap
343   // reference is legal or not, given our safepoint semantics.
344
345   bool AnyInvalidUses = false;
346
347   auto ReportInvalidUse = [&AnyInvalidUses](const Value &V,
348                                             const Instruction &I) {
349     errs() << "Illegal use of unrelocated value found!\n";
350     errs() << "Def: " << V << "\n";
351     errs() << "Use: " << I << "\n";
352     if (!PrintOnly)
353       abort();
354     AnyInvalidUses = true;
355   };
356
357   auto isNotExclusivelyConstantDerived = [](const Value *V) {
358     return getBaseType(V) == BaseType::NonConstant;
359   };
360
361   for (const BasicBlock &BB : F) {
362     // We destructively modify AvailableIn as we traverse the block instruction
363     // by instruction.
364     DenseSet<const Value *> &AvailableSet = BlockMap[&BB]->AvailableIn;
365     for (const Instruction &I : BB) {
366       if (const PHINode *PN = dyn_cast<PHINode>(&I)) {
367         if (containsGCPtrType(PN->getType()))
368           for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
369             const BasicBlock *InBB = PN->getIncomingBlock(i);
370             const Value *InValue = PN->getIncomingValue(i);
371
372             if (isNotExclusivelyConstantDerived(InValue) &&
373                 !BlockMap[InBB]->AvailableOut.count(InValue))
374               ReportInvalidUse(*InValue, *PN);
375           }
376       } else if (isa<CmpInst>(I) &&
377                  containsGCPtrType(I.getOperand(0)->getType())) {
378         Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
379         enum BaseType baseTyLHS = getBaseType(LHS),
380                       baseTyRHS = getBaseType(RHS);
381
382         // Returns true if LHS and RHS are unrelocated pointers and they are
383         // valid unrelocated uses.
384         auto hasValidUnrelocatedUse = [&AvailableSet, baseTyLHS, baseTyRHS, &LHS, &RHS] () {
385             // A cmp instruction has valid unrelocated pointer operands only if
386             // both operands are unrelocated pointers.
387             // In the comparison between two pointers, if one is an unrelocated
388             // use, the other *should be* an unrelocated use, for this
389             // instruction to contain valid unrelocated uses. This unrelocated
390             // use can be a null constant as well, or another unrelocated
391             // pointer.
392             if (AvailableSet.count(LHS) || AvailableSet.count(RHS))
393               return false;
394             // Constant pointers (that are not exclusively null) may have
395             // meaning in different VMs, so we cannot reorder the compare
396             // against constant pointers before the safepoint. In other words,
397             // comparison of an unrelocated use against a non-null constant
398             // maybe invalid.
399             if ((baseTyLHS == BaseType::ExclusivelySomeConstant &&
400                  baseTyRHS == BaseType::NonConstant) ||
401                 (baseTyLHS == BaseType::NonConstant &&
402                  baseTyRHS == BaseType::ExclusivelySomeConstant))
403               return false;
404             // All other cases are valid cases enumerated below:
405             // 1. Comparison between an exlusively derived null pointer and a
406             // constant base pointer.
407             // 2. Comparison between an exlusively derived null pointer and a
408             // non-constant unrelocated base pointer.
409             // 3. Comparison between 2 unrelocated pointers.
410             return true;
411         };
412         if (!hasValidUnrelocatedUse()) {
413           // Print out all non-constant derived pointers that are unrelocated
414           // uses, which are invalid.
415           if (baseTyLHS == BaseType::NonConstant && !AvailableSet.count(LHS))
416             ReportInvalidUse(*LHS, I);
417           if (baseTyRHS == BaseType::NonConstant && !AvailableSet.count(RHS))
418             ReportInvalidUse(*RHS, I);
419         }
420       } else {
421         for (const Value *V : I.operands())
422           if (containsGCPtrType(V->getType()) &&
423               isNotExclusivelyConstantDerived(V) && !AvailableSet.count(V))
424             ReportInvalidUse(*V, I);
425       }
426
427       bool Cleared = false;
428       TransferInstruction(I, Cleared, AvailableSet);
429       (void)Cleared;
430     }
431   }
432
433   if (PrintOnly && !AnyInvalidUses) {
434     dbgs() << "No illegal uses found by SafepointIRVerifier in: " << F.getName()
435            << "\n";
436   }
437 }