1 //===------ PollyIRBuilder.cpp --------------------------------------------===// 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 // The Polly IRBuilder file contains Polly specific extensions for the IRBuilder 11 // that are used e.g. to emit the llvm.loop.parallel metadata. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "polly/CodeGen/IRBuilder.h" 16 17 #include "polly/ScopInfo.h" 18 #include "polly/Support/ScopHelper.h" 19 20 #include "llvm/IR/Metadata.h" 21 #include "llvm/Support/Debug.h" 22 23 using namespace llvm; 24 using namespace polly; 25 26 /// @brief Get a self referencing id metadata node. 27 /// 28 /// The MDNode looks like this (if arg0/arg1 are not null): 29 /// 30 /// '!n = metadata !{metadata !n, arg0, arg1}' 31 /// 32 /// @return The self referencing id metadata node. 33 static MDNode *getID(LLVMContext &Ctx, Metadata *arg0 = nullptr, 34 Metadata *arg1 = nullptr) { 35 MDNode *ID; 36 SmallVector<Metadata *, 3> Args; 37 // Use a temporary node to safely create a unique pointer for the first arg. 38 auto TempNode = MDNode::getTemporary(Ctx, None); 39 // Reserve operand 0 for loop id self reference. 40 Args.push_back(TempNode.get()); 41 42 if (arg0) 43 Args.push_back(arg0); 44 if (arg1) 45 Args.push_back(arg1); 46 47 ID = MDNode::get(Ctx, Args); 48 ID->replaceOperandWith(0, ID); 49 return ID; 50 } 51 52 ScopAnnotator::ScopAnnotator() : SE(nullptr), AliasScopeDomain(nullptr) {} 53 54 void ScopAnnotator::buildAliasScopes(Scop &S) { 55 SE = S.getSE(); 56 57 LLVMContext &Ctx = SE->getContext(); 58 AliasScopeDomain = getID(Ctx, MDString::get(Ctx, "polly.alias.scope.domain")); 59 60 AliasScopeMap.clear(); 61 OtherAliasScopeListMap.clear(); 62 63 SetVector<Value *> BasePtrs; 64 for (ScopStmt *Stmt : S) 65 for (MemoryAccess *MA : *Stmt) 66 BasePtrs.insert(MA->getBaseAddr()); 67 68 std::string AliasScopeStr = "polly.alias.scope."; 69 for (Value *BasePtr : BasePtrs) 70 AliasScopeMap[BasePtr] = getID( 71 Ctx, AliasScopeDomain, 72 MDString::get(Ctx, (AliasScopeStr + BasePtr->getName()).str().c_str())); 73 74 for (Value *BasePtr : BasePtrs) { 75 MDNode *AliasScopeList = MDNode::get(Ctx, {}); 76 for (const auto &AliasScopePair : AliasScopeMap) { 77 if (BasePtr == AliasScopePair.first) 78 continue; 79 80 Metadata *Args = {AliasScopePair.second}; 81 AliasScopeList = 82 MDNode::concatenate(AliasScopeList, MDNode::get(Ctx, Args)); 83 } 84 85 OtherAliasScopeListMap[BasePtr] = AliasScopeList; 86 } 87 } 88 89 void ScopAnnotator::pushLoop(Loop *L, bool IsParallel) { 90 91 ActiveLoops.push_back(L); 92 if (!IsParallel) 93 return; 94 95 BasicBlock *Header = L->getHeader(); 96 MDNode *Id = getID(Header->getContext()); 97 assert(Id->getOperand(0) == Id && "Expected Id to be a self-reference"); 98 assert(Id->getNumOperands() == 1 && "Unexpected extra operands in Id"); 99 MDNode *Ids = ParallelLoops.empty() 100 ? Id 101 : MDNode::concatenate(ParallelLoops.back(), Id); 102 ParallelLoops.push_back(Ids); 103 } 104 105 void ScopAnnotator::popLoop(bool IsParallel) { 106 ActiveLoops.pop_back(); 107 if (!IsParallel) 108 return; 109 110 assert(!ParallelLoops.empty() && "Expected a parallel loop to pop"); 111 ParallelLoops.pop_back(); 112 } 113 114 void ScopAnnotator::annotateLoopLatch(BranchInst *B, Loop *L, 115 bool IsParallel) const { 116 if (!IsParallel) 117 return; 118 119 assert(!ParallelLoops.empty() && "Expected a parallel loop to annotate"); 120 MDNode *Ids = ParallelLoops.back(); 121 MDNode *Id = cast<MDNode>(Ids->getOperand(Ids->getNumOperands() - 1)); 122 B->setMetadata("llvm.loop", Id); 123 } 124 125 void ScopAnnotator::annotate(Instruction *Inst) { 126 if (!Inst->mayReadOrWriteMemory()) 127 return; 128 129 // TODO: Use the ScopArrayInfo once available here. 130 if (AliasScopeDomain) { 131 Value *BasePtr = nullptr; 132 if (isa<StoreInst>(Inst) || isa<LoadInst>(Inst)) { 133 const SCEV *PtrSCEV = SE->getSCEV(getPointerOperand(*Inst)); 134 const SCEV *BaseSCEV = SE->getPointerBase(PtrSCEV); 135 if (const SCEVUnknown *SU = dyn_cast<SCEVUnknown>(BaseSCEV)) 136 BasePtr = SU->getValue(); 137 } 138 139 if (BasePtr) { 140 Inst->setMetadata("alias.scope", AliasScopeMap[BasePtr]); 141 Inst->setMetadata("noalias", OtherAliasScopeListMap[BasePtr]); 142 } 143 } 144 145 if (ParallelLoops.empty()) 146 return; 147 148 Inst->setMetadata("llvm.mem.parallel_loop_access", ParallelLoops.back()); 149 } 150