1 //===- TypeBasedAliasAnalysis.cpp - Type-Based Alias Analysis -------------===// 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 // This file defines the TypeBasedAliasAnalysis pass, which implements 11 // metadata-based TBAA. 12 // 13 // In LLVM IR, memory does not have types, so LLVM's own type system is not 14 // suitable for doing TBAA. Instead, metadata is added to the IR to describe 15 // a type system of a higher level language. 16 // 17 // This pass is language-independent. The type system is encoded in 18 // metadata. This allows this pass to support typical C and C++ TBAA, but 19 // it can also support custom aliasing behavior for other languages. 20 // 21 // This is a work-in-progress. It doesn't work yet, and the metadata 22 // format isn't stable. 23 // 24 // TODO: getModRefBehavior. The AliasAnalysis infrastructure will need to 25 // be extended. 26 // TODO: struct fields 27 // 28 //===----------------------------------------------------------------------===// 29 30 #include "llvm/Analysis/AliasAnalysis.h" 31 #include "llvm/Analysis/Passes.h" 32 #include "llvm/Module.h" 33 #include "llvm/Metadata.h" 34 #include "llvm/Pass.h" 35 #include "llvm/Support/CommandLine.h" 36 using namespace llvm; 37 38 // For testing purposes, enable TBAA only via a special option. 39 static cl::opt<bool> EnableTBAA("enable-tbaa"); 40 41 namespace { 42 /// TBAANode - This is a simple wrapper around an MDNode which provides a 43 /// higher-level interface by hiding the details of how alias analysis 44 /// information is encoded in its operands. 45 class TBAANode { 46 const MDNode *Node; 47 48 public: 49 TBAANode() : Node(0) {} 50 explicit TBAANode(const MDNode *N) : Node(N) {} 51 52 /// getNode - Get the MDNode for this TBAANode. 53 const MDNode *getNode() const { return Node; } 54 55 /// getParent - Get this TBAANode's Alias tree parent. 56 TBAANode getParent() const { 57 if (Node->getNumOperands() < 2) 58 return TBAANode(); 59 MDNode *P = dyn_cast_or_null<MDNode>(Node->getOperand(1)); 60 if (!P) 61 return TBAANode(); 62 // Ok, this node has a valid parent. Return it. 63 return TBAANode(P); 64 } 65 66 /// TypeIsImmutable - Test if this TBAANode represents a type for objects 67 /// which are not modified (by any means) in the context where this 68 /// AliasAnalysis is relevant. 69 bool TypeIsImmutable() const { 70 if (Node->getNumOperands() < 3) 71 return false; 72 ConstantInt *CI = dyn_cast<ConstantInt>(Node->getOperand(2)); 73 if (!CI) 74 return false; 75 // TODO: Think about the encoding. 76 return CI->isOne(); 77 } 78 }; 79 } 80 81 namespace { 82 /// TypeBasedAliasAnalysis - This is a simple alias analysis 83 /// implementation that uses TypeBased to answer queries. 84 class TypeBasedAliasAnalysis : public ImmutablePass, 85 public AliasAnalysis { 86 public: 87 static char ID; // Class identification, replacement for typeinfo 88 TypeBasedAliasAnalysis() : ImmutablePass(ID) { 89 initializeTypeBasedAliasAnalysisPass(*PassRegistry::getPassRegistry()); 90 } 91 92 virtual void initializePass() { 93 InitializeAliasAnalysis(this); 94 } 95 96 /// getAdjustedAnalysisPointer - This method is used when a pass implements 97 /// an analysis interface through multiple inheritance. If needed, it 98 /// should override this to adjust the this pointer as needed for the 99 /// specified pass info. 100 virtual void *getAdjustedAnalysisPointer(const void *PI) { 101 if (PI == &AliasAnalysis::ID) 102 return (AliasAnalysis*)this; 103 return this; 104 } 105 106 bool Aliases(const MDNode *A, const MDNode *B) const; 107 108 private: 109 virtual void getAnalysisUsage(AnalysisUsage &AU) const; 110 virtual AliasResult alias(const Location &LocA, const Location &LocB); 111 virtual bool pointsToConstantMemory(const Location &Loc); 112 }; 113 } // End of anonymous namespace 114 115 // Register this pass... 116 char TypeBasedAliasAnalysis::ID = 0; 117 INITIALIZE_AG_PASS(TypeBasedAliasAnalysis, AliasAnalysis, "tbaa", 118 "Type-Based Alias Analysis", false, true, false) 119 120 ImmutablePass *llvm::createTypeBasedAliasAnalysisPass() { 121 return new TypeBasedAliasAnalysis(); 122 } 123 124 void 125 TypeBasedAliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { 126 AU.setPreservesAll(); 127 AliasAnalysis::getAnalysisUsage(AU); 128 } 129 130 /// Aliases - Test whether the type represented by A may alias the 131 /// type represented by B. 132 bool 133 TypeBasedAliasAnalysis::Aliases(const MDNode *A, 134 const MDNode *B) const { 135 // Keep track of the root node for A and B. 136 TBAANode RootA, RootB; 137 138 // Climb the tree from A to see if we reach B. 139 for (TBAANode T(A); ; ) { 140 if (T.getNode() == B) 141 // B is an ancestor of A. 142 return true; 143 144 RootA = T; 145 T = T.getParent(); 146 if (!T.getNode()) 147 break; 148 } 149 150 // Climb the tree from B to see if we reach A. 151 for (TBAANode T(B); ; ) { 152 if (T.getNode() == A) 153 // A is an ancestor of B. 154 return true; 155 156 RootB = T; 157 T = T.getParent(); 158 if (!T.getNode()) 159 break; 160 } 161 162 // Neither node is an ancestor of the other. 163 164 // If they have different roots, they're part of different potentially 165 // unrelated type systems, so we must be conservative. 166 if (RootA.getNode() != RootB.getNode()) 167 return true; 168 169 // If they have the same root, then we've proved there's no alias. 170 return false; 171 } 172 173 AliasAnalysis::AliasResult 174 TypeBasedAliasAnalysis::alias(const Location &LocA, 175 const Location &LocB) { 176 if (!EnableTBAA) 177 return AliasAnalysis::alias(LocA, LocB); 178 179 // Get the attached MDNodes. If either value lacks a tbaa MDNode, we must 180 // be conservative. 181 const MDNode *AM = LocA.TBAATag; 182 if (!AM) return AliasAnalysis::alias(LocA, LocB); 183 const MDNode *BM = LocB.TBAATag; 184 if (!BM) return AliasAnalysis::alias(LocA, LocB); 185 186 // If they may alias, chain to the next AliasAnalysis. 187 if (Aliases(AM, BM)) 188 return AliasAnalysis::alias(LocA, LocB); 189 190 // Otherwise return a definitive result. 191 return NoAlias; 192 } 193 194 bool TypeBasedAliasAnalysis::pointsToConstantMemory(const Location &Loc) { 195 if (!EnableTBAA) 196 return AliasAnalysis::pointsToConstantMemory(Loc); 197 198 const MDNode *M = Loc.TBAATag; 199 if (!M) return false; 200 201 // If this is an "immutable" type, we can assume the pointer is pointing 202 // to constant memory. 203 if (TBAANode(M).TypeIsImmutable()) 204 return true; 205 206 return AliasAnalysis::pointsToConstantMemory(Loc); 207 } 208