void SpecializationTable::initialize(Module* m) { assert(this->module == NULL); this->module = m; #ifdef RECORD_IN_METADATA // Parse the module metadata to populate the table NamedMDNode* specs = m->getNamedMetadata("previrt::specializations"); if (specs == NULL) return; errs() << "Specialization Count: " << specs->getNumOperands() << "\n"; for (unsigned int i = 0; i < specs->getNumOperands(); ++i) { MDNode* funNode = specs->getOperand(i); if (funNode == NULL) { continue; } assert (funNode->getNumOperands() > 2); MDString* prinName = dyn_cast_or_null<MDString>(funNode->getOperand(0)); MDString* specName = dyn_cast_or_null<MDString>(funNode->getOperand(1)); if (prinName == NULL || specName == NULL) { errs() << "must skip " << (prinName == NULL ? "?" : prinName->getString()) << "\n"; continue; } Function* prin = m->getFunction(prinName->getString()); Function* spec = m->getFunction(specName->getString()); if (prin == NULL || spec == NULL) { errs() << "must skip " << (prin == NULL ? "?" : prin->getName()) << "\n"; continue; } const unsigned int arg_count = prin->getArgumentList().size(); if (funNode->getNumOperands() != 2 + arg_count) { continue; } SpecScheme scheme = new Value*[arg_count]; for (unsigned int i = 0; i < arg_count; i++) { Value* opr = funNode->getOperand(2 + i); if (opr == NULL) { scheme[i] = NULL; } else { assert (dyn_cast<Constant>(opr) != NULL); scheme[i] = opr; } } this->addSpecialization(prin, scheme, spec, false); errs() << "recording specialization of '" << prin->getName() << "' to '" << spec->getName() << "'\n"; } #endif /* RECORD_IN_METADATA */ }
/// buildCFICheck - emits __cfi_check for the current module. void CrossDSOCFI::buildCFICheck() { // FIXME: verify that __cfi_check ends up near the end of the code section, // but before the jump slots created in LowerBitSets. llvm::DenseSet<uint64_t> BitSetIds; NamedMDNode *BitSetNM = M->getNamedMetadata("llvm.bitsets"); if (BitSetNM) for (unsigned I = 0, E = BitSetNM->getNumOperands(); I != E; ++I) if (ConstantInt *TypeId = extractBitSetTypeId(BitSetNM->getOperand(I))) BitSetIds.insert(TypeId->getZExtValue()); LLVMContext &Ctx = M->getContext(); Constant *C = M->getOrInsertFunction( "__cfi_check", FunctionType::get( Type::getVoidTy(Ctx), {Type::getInt64Ty(Ctx), PointerType::getUnqual(Type::getInt8Ty(Ctx))}, false)); Function *F = dyn_cast<Function>(C); F->setAlignment(4096); auto args = F->arg_begin(); Argument &CallSiteTypeId = *(args++); CallSiteTypeId.setName("CallSiteTypeId"); Argument &Addr = *(args++); Addr.setName("Addr"); assert(args == F->arg_end()); BasicBlock *BB = BasicBlock::Create(Ctx, "entry", F); BasicBlock *TrapBB = BasicBlock::Create(Ctx, "trap", F); IRBuilder<> IRBTrap(TrapBB); Function *TrapFn = Intrinsic::getDeclaration(M, Intrinsic::trap); llvm::CallInst *TrapCall = IRBTrap.CreateCall(TrapFn); TrapCall->setDoesNotReturn(); TrapCall->setDoesNotThrow(); IRBTrap.CreateUnreachable(); BasicBlock *ExitBB = BasicBlock::Create(Ctx, "exit", F); IRBuilder<> IRBExit(ExitBB); IRBExit.CreateRetVoid(); IRBuilder<> IRB(BB); SwitchInst *SI = IRB.CreateSwitch(&CallSiteTypeId, TrapBB, BitSetIds.size()); for (uint64_t TypeId : BitSetIds) { ConstantInt *CaseTypeId = ConstantInt::get(Type::getInt64Ty(Ctx), TypeId); BasicBlock *TestBB = BasicBlock::Create(Ctx, "test", F); IRBuilder<> IRBTest(TestBB); Function *BitsetTestFn = Intrinsic::getDeclaration(M, Intrinsic::bitset_test); Value *Test = IRBTest.CreateCall( BitsetTestFn, {&Addr, MetadataAsValue::get( Ctx, ConstantAsMetadata::get(CaseTypeId))}); BranchInst *BI = IRBTest.CreateCondBr(Test, ExitBB, TrapBB); BI->setMetadata(LLVMContext::MD_prof, VeryLikelyWeights); SI->addCase(CaseTypeId, TestBB); ++TypeIds; } }
map<string, Variable*>* IRParser::parseParameters(Module* module){ map<string, Variable*>* parameters = new map<string, Variable*>(); NamedMDNode* inputsMD = module->getNamedMetadata(IRConstant::KEY_PARAMETERS); if (inputsMD != NULL){ for (unsigned i = 0, e = inputsMD->getNumOperands(); i != e; ++i) { //Parse a parameter MDNode* parameterNode = cast<MDNode>(inputsMD->getOperand(i)); MDNode* details = cast<MDNode>(parameterNode->getOperand(0)); MDString* nameMD = cast<MDString>(details->getOperand(0)); Type* type = parseType(cast<MDNode>(parameterNode->getOperand(1))); GlobalVariable* variable = cast<GlobalVariable>(parameterNode->getOperand(2)); //Parse create parameter StateVar* parameter = new StateVar(type, nameMD->getString(), false, variable); parameters->insert(pair<string, Variable*>(nameMD->getString(), parameter)); } } return parameters; }
static std::string ModuleMetaGet(const Module *module, StringRef MetaName) { NamedMDNode *node = module->getNamedMetadata(MetaName); if (node == NULL) return ""; assert(node->getNumOperands() == 1); MDNode *subnode = node->getOperand(0); assert(subnode->getNumOperands() == 1); MDString *value = dyn_cast<MDString>(subnode->getOperand(0)); assert(value != NULL); return value->getString(); }
/// Find the debug info descriptor corresponding to this global variable. static Value *findDbgGlobalDeclare(GlobalVariable *V) { const Module *M = V->getParent(); NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.gv"); if (!NMD) return 0; for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { DIDescriptor DIG(cast<MDNode>(NMD->getOperand(i))); if (!DIG.isGlobalVariable()) continue; if (DIGlobalVariable(DIG).getGlobal() == V) return DIG; } return 0; }
/// Find the debug info descriptor corresponding to this function. static Value *findDbgSubprogramDeclare(Function *V) { const Module *M = V->getParent(); NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.sp"); if (!NMD) return 0; for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { DIDescriptor DIG(cast<MDNode>(NMD->getOperand(i))); if (!DIG.isSubprogram()) continue; if (DISubprogram(DIG).getFunction() == V) return DIG; } return 0; }
// @LOCALMOD-BEGIN void Module::convertMetadataToLibraryList() { LibraryList.clear(); // Get the DepLib node NamedMDNode *Node = getNamedMetadata("DepLibs"); if (!Node) return; for (unsigned i = 0; i < Node->getNumOperands(); i++) { MDString* Mds = dyn_cast_or_null<MDString>( Node->getOperand(i)->getOperand(0)); assert(Mds && "Bad NamedMetadata operand"); LibraryList.push_back(Mds->getString()); } // Clear the metadata so the linker won't try to merge it Node->dropAllReferences(); }
list<Action*>* IRParser::parseActions(string key, Module* module){ list<Action*>* actions = new list<Action*>(); NamedMDNode* inputsMD = module->getNamedMetadata(key); if (inputsMD == NULL) { return actions; } for (unsigned i = 0, e = inputsMD->getNumOperands(); i != e; ++i) { Action* action = parseAction(inputsMD->getOperand(i)); actions->push_back(action); } return actions; }
map<string, StateVar*>* IRParser::parseStateVars(Module* module){ map<string, StateVar*>* stateVars = new map<string, StateVar*>(); NamedMDNode* stateVarsMD = module->getNamedMetadata(IRConstant::KEY_STATE_VARS); if (stateVarsMD == NULL) { return stateVars; } for (unsigned i = 0, e = stateVarsMD->getNumOperands(); i != e; ++i) { StateVar* var = parseStateVar(stateVarsMD->getOperand(i)); stateVars->insert(pair<string, StateVar*>(var->getName(), var)); } return stateVars; }
// Print the main compile unit's source filename, // falls back to printing the module identifier. static void printLocation(const llvm::Module *M) { NamedMDNode *ND = M->getNamedMetadata("llvm.dbg.gv"); if (ND) { unsigned N = ND->getNumOperands(); // Try to find main compile unit for (unsigned i=0;i<N;i++) { DIGlobalVariable G(ND->getOperand(i)); DICompileUnit CU(G.getCompileUnit()); if (!CU.isMain()) continue; errs() << /*CU.getDirectory() << "/" <<*/ CU.getFilename() << ": "; return; } } errs() << M->getModuleIdentifier() << ": "; }
// Get the NeededRecord for SOName. // Returns an empty NeededRecord if there was no metadata found. static void getNeededRecordFor(const Module *M, StringRef SOName, Module::NeededRecord *NR) { NR->DynFile = SOName; NR->Symbols.clear(); std::string Key = NeededPrefix; Key += SOName; NamedMDNode *Node = M->getNamedMetadata(Key); if (!Node) return; for (unsigned k = 0; k < Node->getNumOperands(); ++k) { // Insert the symbol name. const MDString *SymName = dyn_cast<MDString>(Node->getOperand(k)->getOperand(0)); NR->Symbols.push_back(SymName->getString()); } }
void AddressSanitizer::FindDynamicInitializers(Module& M) { // Clang generates metadata identifying all dynamically initialized globals. NamedMDNode *DynamicGlobals = M.getNamedMetadata("llvm.asan.dynamically_initialized_globals"); if (!DynamicGlobals) return; for (int i = 0, n = DynamicGlobals->getNumOperands(); i < n; ++i) { MDNode *MDN = DynamicGlobals->getOperand(i); assert(MDN->getNumOperands() == 1); Value *VG = MDN->getOperand(0); // The optimizer may optimize away a global entirely, in which case we // cannot instrument access to it. if (!VG) continue; GlobalVariable *G = cast<GlobalVariable>(VG); DynamicallyInitializedGlobals.insert(G); } }
static std::unique_ptr<StructInfo> getCpuArchStructInfo(Module *module) { GlobalVariable *env = module->getGlobalVariable("cpuarchstruct_type_anchor", false); assert(env); assert(env->getType() && env->getType()->isPointerTy()); assert(env->getType()->getElementType() && env->getType()->getElementType()->isPointerTy()); PointerType *envDeref = dyn_cast<PointerType>(env->getType()->getElementType()); assert(envDeref && envDeref->getElementType() && envDeref->getElementType()->isStructTy()); StructType *structType = dyn_cast<StructType>(envDeref->getElementType()); assert(structType); NamedMDNode *mdCuNodes = module->getNamedMetadata("llvm.dbg.cu"); if (!mdCuNodes) { return nullptr; } std::shared_ptr<DITypeIdentifierMap> typeIdentifierMap(new DITypeIdentifierMap(generateDITypeIdentifierMap(mdCuNodes))); DICompositeType *diStructType = nullptr; for ( unsigned i = 0; i < mdCuNodes->getNumOperands() && !diStructType; ++i ) { DICompileUnit diCu(mdCuNodes->getOperand(i)); for ( unsigned j = 0; j < diCu.getGlobalVariables().getNumElements(); ++j ) { DIGlobalVariable diGlobalVar(diCu.getGlobalVariables().getElement(j)); if (diGlobalVar.getName() != "cpuarchstruct_type_anchor") { continue; } assert(diGlobalVar.getType().isDerivedType()); DIDerivedType diEnvPtrType(diGlobalVar.getType()); assert(diEnvPtrType.getTypeDerivedFrom().resolve(*typeIdentifierMap).isCompositeType()); return std::unique_ptr<StructInfo>(new StructInfo(module, structType, new DICompositeType(diEnvPtrType.getTypeDerivedFrom().resolve(*typeIdentifierMap)), typeIdentifierMap)); } } llvm::errs() << "WARNING: Debug information for struct CPUArchState not found" << '\n'; return nullptr; }
map<string, Procedure*>* IRParser::parseProcs(Module* module){ map<string, Procedure*>* procedures = new map<string, Procedure*>(); NamedMDNode* inputsMD = module->getNamedMetadata(IRConstant::KEY_PROCEDURES); if (inputsMD != NULL){ for (unsigned i = 0, e = inputsMD->getNumOperands(); i != e; ++i) { //Parse a procedure Procedure* proc= parseProc(inputsMD->getOperand(i)); if (proc != NULL){ // Insert procedure in case of success procedures->insert(pair<string, Procedure*>(proc->getName(), proc)); } } } return procedures; }
map<string, Port*>* IRParser::parsePorts(string key, Module* module){ map<string, Port*>* ports = new map<string, Port*>(); NamedMDNode* inputsMD = module->getNamedMetadata(key); if (inputsMD == NULL) { return ports; } for (unsigned i = 0, e = inputsMD->getNumOperands(); i != e; ++i) { Port* port = parsePort(inputsMD->getOperand(i)); if(key == IRConstant::KEY_INPUTS){ port->setAccess(true, false); }else { port->setAccess(false, true); } ports->insert(pair<string,Port*>(port->getName(), port)); } return ports; }
void DevirtModule::buildBitSets( std::vector<VTableBits> &Bits, DenseMap<Metadata *, std::set<BitSetInfo>> &BitSets) { NamedMDNode *BitSetNM = M.getNamedMetadata("llvm.bitsets"); if (!BitSetNM) return; DenseMap<GlobalVariable *, VTableBits *> GVToBits; Bits.reserve(BitSetNM->getNumOperands()); for (auto Op : BitSetNM->operands()) { auto OpConstMD = dyn_cast_or_null<ConstantAsMetadata>(Op->getOperand(1)); if (!OpConstMD) continue; auto BitSetID = Op->getOperand(0).get(); Constant *OpConst = OpConstMD->getValue(); if (auto GA = dyn_cast<GlobalAlias>(OpConst)) OpConst = GA->getAliasee(); auto OpGlobal = dyn_cast<GlobalVariable>(OpConst); if (!OpGlobal) continue; uint64_t Offset = cast<ConstantInt>( cast<ConstantAsMetadata>(Op->getOperand(2))->getValue()) ->getZExtValue(); VTableBits *&BitsPtr = GVToBits[OpGlobal]; if (!BitsPtr) { Bits.emplace_back(); Bits.back().GV = OpGlobal; Bits.back().ObjectSize = M.getDataLayout().getTypeAllocSize( OpGlobal->getInitializer()->getType()); BitsPtr = &Bits.back(); } BitSets[BitSetID].insert({BitsPtr, Offset}); } }
// destructively move the contents of src into dest // this assumes that the targets of the two modules are the same // including the DataLayout and ModuleFlags (for example) // and that there is no module-level assembly static void jl_merge_module(Module *dest, std::unique_ptr<Module> src) { assert(dest != src.get()); for (Module::global_iterator I = src->global_begin(), E = src->global_end(); I != E;) { GlobalVariable *sG = &*I; GlobalValue *dG = dest->getNamedValue(sG->getName()); ++I; // Replace a declaration with the definition: if (dG) { if (sG->isDeclaration()) { sG->replaceAllUsesWith(dG); sG->eraseFromParent(); continue; } else { dG->replaceAllUsesWith(sG); dG->eraseFromParent(); } } // Reparent the global variable: sG->removeFromParent(); dest->getGlobalList().push_back(sG); // Comdat is owned by the Module, recreate it in the new parent: addComdat(sG); } for (Module::iterator I = src->begin(), E = src->end(); I != E;) { Function *sG = &*I; GlobalValue *dG = dest->getNamedValue(sG->getName()); ++I; // Replace a declaration with the definition: if (dG) { if (sG->isDeclaration()) { sG->replaceAllUsesWith(dG); sG->eraseFromParent(); continue; } else { dG->replaceAllUsesWith(sG); dG->eraseFromParent(); } } // Reparent the global variable: sG->removeFromParent(); dest->getFunctionList().push_back(sG); // Comdat is owned by the Module, recreate it in the new parent: addComdat(sG); } for (Module::alias_iterator I = src->alias_begin(), E = src->alias_end(); I != E;) { GlobalAlias *sG = &*I; GlobalValue *dG = dest->getNamedValue(sG->getName()); ++I; if (dG) { if (!dG->isDeclaration()) { // aliases are always definitions, so this test is reversed from the above two sG->replaceAllUsesWith(dG); sG->eraseFromParent(); continue; } else { dG->replaceAllUsesWith(sG); dG->eraseFromParent(); } } sG->removeFromParent(); dest->getAliasList().push_back(sG); } // metadata nodes need to be explicitly merged not just copied // so there are special passes here for each known type of metadata NamedMDNode *sNMD = src->getNamedMetadata("llvm.dbg.cu"); if (sNMD) { NamedMDNode *dNMD = dest->getOrInsertNamedMetadata("llvm.dbg.cu"); #ifdef LLVM35 for (NamedMDNode::op_iterator I = sNMD->op_begin(), E = sNMD->op_end(); I != E; ++I) { dNMD->addOperand(*I); } #else for (unsigned i = 0, l = sNMD->getNumOperands(); i < l; i++) { dNMD->addOperand(sNMD->getOperand(i)); } #endif } }
Function *GCOVProfiler::insertCounterWriteout( ArrayRef<std::pair<GlobalVariable *, MDNode *> > CountersBySP) { FunctionType *WriteoutFTy = FunctionType::get(Type::getVoidTy(*Ctx), false); Function *WriteoutF = M->getFunction("__llvm_gcov_writeout"); if (!WriteoutF) WriteoutF = Function::Create(WriteoutFTy, GlobalValue::InternalLinkage, "__llvm_gcov_writeout", M); WriteoutF->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); WriteoutF->addFnAttr(Attribute::NoInline); if (Options.NoRedZone) WriteoutF->addFnAttr(Attribute::NoRedZone); BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", WriteoutF); IRBuilder<> Builder(BB); Constant *StartFile = getStartFileFunc(); Constant *EmitFunction = getEmitFunctionFunc(); Constant *EmitArcs = getEmitArcsFunc(); Constant *SummaryInfo = getSummaryInfoFunc(); Constant *EndFile = getEndFileFunc(); NamedMDNode *CUNodes = M->getNamedMetadata("llvm.dbg.cu"); if (!CUNodes) { Builder.CreateRetVoid(); return WriteoutF; } // Collect the relevant data into a large constant data structure that we can // walk to write out everything. StructType *StartFileCallArgsTy = StructType::create( {Builder.getInt8PtrTy(), Builder.getInt8PtrTy(), Builder.getInt32Ty()}); StructType *EmitFunctionCallArgsTy = StructType::create( {Builder.getInt32Ty(), Builder.getInt8PtrTy(), Builder.getInt32Ty(), Builder.getInt8Ty(), Builder.getInt32Ty()}); StructType *EmitArcsCallArgsTy = StructType::create( {Builder.getInt32Ty(), Builder.getInt64Ty()->getPointerTo()}); StructType *FileInfoTy = StructType::create({StartFileCallArgsTy, Builder.getInt32Ty(), EmitFunctionCallArgsTy->getPointerTo(), EmitArcsCallArgsTy->getPointerTo()}); Constant *Zero32 = Builder.getInt32(0); // Build an explicit array of two zeros for use in ConstantExpr GEP building. Constant *TwoZero32s[] = {Zero32, Zero32}; SmallVector<Constant *, 8> FileInfos; for (int i : llvm::seq<int>(0, CUNodes->getNumOperands())) { auto *CU = cast<DICompileUnit>(CUNodes->getOperand(i)); // Skip module skeleton (and module) CUs. if (CU->getDWOId()) continue; std::string FilenameGcda = mangleName(CU, GCovFileType::GCDA); uint32_t CfgChecksum = FileChecksums.empty() ? 0 : FileChecksums[i]; auto *StartFileCallArgs = ConstantStruct::get( StartFileCallArgsTy, {Builder.CreateGlobalStringPtr(FilenameGcda), Builder.CreateGlobalStringPtr(ReversedVersion), Builder.getInt32(CfgChecksum)}); SmallVector<Constant *, 8> EmitFunctionCallArgsArray; SmallVector<Constant *, 8> EmitArcsCallArgsArray; for (int j : llvm::seq<int>(0, CountersBySP.size())) { auto *SP = cast_or_null<DISubprogram>(CountersBySP[j].second); uint32_t FuncChecksum = Funcs.empty() ? 0 : Funcs[j]->getFuncChecksum(); EmitFunctionCallArgsArray.push_back(ConstantStruct::get( EmitFunctionCallArgsTy, {Builder.getInt32(j), Options.FunctionNamesInData ? Builder.CreateGlobalStringPtr(getFunctionName(SP)) : Constant::getNullValue(Builder.getInt8PtrTy()), Builder.getInt32(FuncChecksum), Builder.getInt8(Options.UseCfgChecksum), Builder.getInt32(CfgChecksum)})); GlobalVariable *GV = CountersBySP[j].first; unsigned Arcs = cast<ArrayType>(GV->getValueType())->getNumElements(); EmitArcsCallArgsArray.push_back(ConstantStruct::get( EmitArcsCallArgsTy, {Builder.getInt32(Arcs), ConstantExpr::getInBoundsGetElementPtr( GV->getValueType(), GV, TwoZero32s)})); } // Create global arrays for the two emit calls. int CountersSize = CountersBySP.size(); assert(CountersSize == (int)EmitFunctionCallArgsArray.size() && "Mismatched array size!"); assert(CountersSize == (int)EmitArcsCallArgsArray.size() && "Mismatched array size!"); auto *EmitFunctionCallArgsArrayTy = ArrayType::get(EmitFunctionCallArgsTy, CountersSize); auto *EmitFunctionCallArgsArrayGV = new GlobalVariable( *M, EmitFunctionCallArgsArrayTy, /*isConstant*/ true, GlobalValue::InternalLinkage, ConstantArray::get(EmitFunctionCallArgsArrayTy, EmitFunctionCallArgsArray), Twine("__llvm_internal_gcov_emit_function_args.") + Twine(i)); auto *EmitArcsCallArgsArrayTy = ArrayType::get(EmitArcsCallArgsTy, CountersSize); EmitFunctionCallArgsArrayGV->setUnnamedAddr( GlobalValue::UnnamedAddr::Global); auto *EmitArcsCallArgsArrayGV = new GlobalVariable( *M, EmitArcsCallArgsArrayTy, /*isConstant*/ true, GlobalValue::InternalLinkage, ConstantArray::get(EmitArcsCallArgsArrayTy, EmitArcsCallArgsArray), Twine("__llvm_internal_gcov_emit_arcs_args.") + Twine(i)); EmitArcsCallArgsArrayGV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); FileInfos.push_back(ConstantStruct::get( FileInfoTy, {StartFileCallArgs, Builder.getInt32(CountersSize), ConstantExpr::getInBoundsGetElementPtr(EmitFunctionCallArgsArrayTy, EmitFunctionCallArgsArrayGV, TwoZero32s), ConstantExpr::getInBoundsGetElementPtr( EmitArcsCallArgsArrayTy, EmitArcsCallArgsArrayGV, TwoZero32s)})); } // If we didn't find anything to actually emit, bail on out. if (FileInfos.empty()) { Builder.CreateRetVoid(); return WriteoutF; } // To simplify code, we cap the number of file infos we write out to fit // easily in a 32-bit signed integer. This gives consistent behavior between // 32-bit and 64-bit systems without requiring (potentially very slow) 64-bit // operations on 32-bit systems. It also seems unreasonable to try to handle // more than 2 billion files. if ((int64_t)FileInfos.size() > (int64_t)INT_MAX) FileInfos.resize(INT_MAX); // Create a global for the entire data structure so we can walk it more // easily. auto *FileInfoArrayTy = ArrayType::get(FileInfoTy, FileInfos.size()); auto *FileInfoArrayGV = new GlobalVariable( *M, FileInfoArrayTy, /*isConstant*/ true, GlobalValue::InternalLinkage, ConstantArray::get(FileInfoArrayTy, FileInfos), "__llvm_internal_gcov_emit_file_info"); FileInfoArrayGV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); // Create the CFG for walking this data structure. auto *FileLoopHeader = BasicBlock::Create(*Ctx, "file.loop.header", WriteoutF); auto *CounterLoopHeader = BasicBlock::Create(*Ctx, "counter.loop.header", WriteoutF); auto *FileLoopLatch = BasicBlock::Create(*Ctx, "file.loop.latch", WriteoutF); auto *ExitBB = BasicBlock::Create(*Ctx, "exit", WriteoutF); // We always have at least one file, so just branch to the header. Builder.CreateBr(FileLoopHeader); // The index into the files structure is our loop induction variable. Builder.SetInsertPoint(FileLoopHeader); PHINode *IV = Builder.CreatePHI(Builder.getInt32Ty(), /*NumReservedValues*/ 2); IV->addIncoming(Builder.getInt32(0), BB); auto *FileInfoPtr = Builder.CreateInBoundsGEP(FileInfoArrayGV, {Builder.getInt32(0), IV}); auto *StartFileCallArgsPtr = Builder.CreateStructGEP(FileInfoPtr, 0); Builder.CreateCall( StartFile, {Builder.CreateLoad(Builder.CreateStructGEP(StartFileCallArgsPtr, 0)), Builder.CreateLoad(Builder.CreateStructGEP(StartFileCallArgsPtr, 1)), Builder.CreateLoad(Builder.CreateStructGEP(StartFileCallArgsPtr, 2))}); auto *NumCounters = Builder.CreateLoad(Builder.CreateStructGEP(FileInfoPtr, 1)); auto *EmitFunctionCallArgsArray = Builder.CreateLoad(Builder.CreateStructGEP(FileInfoPtr, 2)); auto *EmitArcsCallArgsArray = Builder.CreateLoad(Builder.CreateStructGEP(FileInfoPtr, 3)); auto *EnterCounterLoopCond = Builder.CreateICmpSLT(Builder.getInt32(0), NumCounters); Builder.CreateCondBr(EnterCounterLoopCond, CounterLoopHeader, FileLoopLatch); Builder.SetInsertPoint(CounterLoopHeader); auto *JV = Builder.CreatePHI(Builder.getInt32Ty(), /*NumReservedValues*/ 2); JV->addIncoming(Builder.getInt32(0), FileLoopHeader); auto *EmitFunctionCallArgsPtr = Builder.CreateInBoundsGEP(EmitFunctionCallArgsArray, {JV}); Builder.CreateCall( EmitFunction, {Builder.CreateLoad(Builder.CreateStructGEP(EmitFunctionCallArgsPtr, 0)), Builder.CreateLoad(Builder.CreateStructGEP(EmitFunctionCallArgsPtr, 1)), Builder.CreateLoad(Builder.CreateStructGEP(EmitFunctionCallArgsPtr, 2)), Builder.CreateLoad(Builder.CreateStructGEP(EmitFunctionCallArgsPtr, 3)), Builder.CreateLoad( Builder.CreateStructGEP(EmitFunctionCallArgsPtr, 4))}); auto *EmitArcsCallArgsPtr = Builder.CreateInBoundsGEP(EmitArcsCallArgsArray, {JV}); Builder.CreateCall( EmitArcs, {Builder.CreateLoad(Builder.CreateStructGEP(EmitArcsCallArgsPtr, 0)), Builder.CreateLoad(Builder.CreateStructGEP(EmitArcsCallArgsPtr, 1))}); auto *NextJV = Builder.CreateAdd(JV, Builder.getInt32(1)); auto *CounterLoopCond = Builder.CreateICmpSLT(NextJV, NumCounters); Builder.CreateCondBr(CounterLoopCond, CounterLoopHeader, FileLoopLatch); JV->addIncoming(NextJV, CounterLoopHeader); Builder.SetInsertPoint(FileLoopLatch); Builder.CreateCall(SummaryInfo, {}); Builder.CreateCall(EndFile, {}); auto *NextIV = Builder.CreateAdd(IV, Builder.getInt32(1)); auto *FileLoopCond = Builder.CreateICmpSLT(NextIV, Builder.getInt32(FileInfos.size())); Builder.CreateCondBr(FileLoopCond, FileLoopHeader, ExitBB); IV->addIncoming(NextIV, FileLoopLatch); Builder.SetInsertPoint(ExitBB); Builder.CreateRetVoid(); return WriteoutF; }
std::unique_ptr<StructInfo> StructInfo::getFromGlobalPointer(Module *module, llvm::StringRef name) { GlobalVariable *var = module->getGlobalVariable(name, false); if (!var || !var->getType() || !var->getType()->isPointerTy()) { assert(false); llvm::errs() << "StructInfo: Cannot get global variable " << name << ", or it is not a pointer." << '\n'; return nullptr; } PointerType *varDeref = dyn_cast<PointerType>(var->getType()->getElementType()); if (!varDeref || !varDeref->getElementType()) { assert(false); llvm::errs() << "StructInfo: Pointer not valid." << '\n'; return nullptr; } StructType *structType = dyn_cast<StructType>(varDeref->getElementType()); if (!structType) { assert(false); llvm::errs() << "StructInfo: Cannot get struct type." << '\n'; return nullptr; } NamedMDNode *mdCuNodes = module->getNamedMetadata("llvm.dbg.cu"); if (!mdCuNodes) { assert(false); llvm::errs() << "StructInfo: Cannot find metadata." << '\n'; return nullptr; } std::shared_ptr<DITypeIdentifierMap> typeIdentifierMap(new DITypeIdentifierMap(generateDITypeIdentifierMap(mdCuNodes))); DICompositeType *diStructType = nullptr; for ( unsigned i = 0; i < mdCuNodes->getNumOperands() && !diStructType; ++i ) { DICompileUnit diCu(mdCuNodes->getOperand(i)); for ( unsigned j = 0; j < diCu.getGlobalVariables().getNumElements(); ++j ) { DIGlobalVariable diGlobalVar(diCu.getGlobalVariables().getElement(j)); if (diGlobalVar.getName() != name) { continue; } //Go through pointers until we reach a structure DIType diStructType(diGlobalVar.getType()); while (diStructType.isDerivedType() && !diStructType.isCompositeType()) { diStructType = std::unique_ptr<DIDerivedType>(new DIDerivedType(diStructType))->getTypeDerivedFrom().resolve(*typeIdentifierMap); } if (!diStructType.isCompositeType()) { llvm::errs() << "StructInfo: Global variable " << name << " does not point to a composite type: " << diStructType.getName() << '\n'; assert(false); return nullptr; } return std::unique_ptr<StructInfo>(new StructInfo( module, structType, new DICompositeType(diStructType), typeIdentifierMap)); } } assert(false); llvm::errs() << "StructInfo: Did not find global variable " << name << " in debug information." << '\n'; return nullptr; }
/// Merge the linker flags in Src into the Dest module. Error IRLinker::linkModuleFlagsMetadata() { // If the source module has no module flags, we are done. const NamedMDNode *SrcModFlags = SrcM->getModuleFlagsMetadata(); if (!SrcModFlags) return Error::success(); // If the destination module doesn't have module flags yet, then just copy // over the source module's flags. NamedMDNode *DstModFlags = DstM.getOrInsertModuleFlagsMetadata(); if (DstModFlags->getNumOperands() == 0) { for (unsigned I = 0, E = SrcModFlags->getNumOperands(); I != E; ++I) DstModFlags->addOperand(SrcModFlags->getOperand(I)); return Error::success(); } // First build a map of the existing module flags and requirements. DenseMap<MDString *, std::pair<MDNode *, unsigned>> Flags; SmallSetVector<MDNode *, 16> Requirements; for (unsigned I = 0, E = DstModFlags->getNumOperands(); I != E; ++I) { MDNode *Op = DstModFlags->getOperand(I); ConstantInt *Behavior = mdconst::extract<ConstantInt>(Op->getOperand(0)); MDString *ID = cast<MDString>(Op->getOperand(1)); if (Behavior->getZExtValue() == Module::Require) { Requirements.insert(cast<MDNode>(Op->getOperand(2))); } else { Flags[ID] = std::make_pair(Op, I); } } // Merge in the flags from the source module, and also collect its set of // requirements. for (unsigned I = 0, E = SrcModFlags->getNumOperands(); I != E; ++I) { MDNode *SrcOp = SrcModFlags->getOperand(I); ConstantInt *SrcBehavior = mdconst::extract<ConstantInt>(SrcOp->getOperand(0)); MDString *ID = cast<MDString>(SrcOp->getOperand(1)); MDNode *DstOp; unsigned DstIndex; std::tie(DstOp, DstIndex) = Flags.lookup(ID); unsigned SrcBehaviorValue = SrcBehavior->getZExtValue(); // If this is a requirement, add it and continue. if (SrcBehaviorValue == Module::Require) { // If the destination module does not already have this requirement, add // it. if (Requirements.insert(cast<MDNode>(SrcOp->getOperand(2)))) { DstModFlags->addOperand(SrcOp); } continue; } // If there is no existing flag with this ID, just add it. if (!DstOp) { Flags[ID] = std::make_pair(SrcOp, DstModFlags->getNumOperands()); DstModFlags->addOperand(SrcOp); continue; } // Otherwise, perform a merge. ConstantInt *DstBehavior = mdconst::extract<ConstantInt>(DstOp->getOperand(0)); unsigned DstBehaviorValue = DstBehavior->getZExtValue(); // If either flag has override behavior, handle it first. if (DstBehaviorValue == Module::Override) { // Diagnose inconsistent flags which both have override behavior. if (SrcBehaviorValue == Module::Override && SrcOp->getOperand(2) != DstOp->getOperand(2)) return stringErr("linking module flags '" + ID->getString() + "': IDs have conflicting override values"); continue; } else if (SrcBehaviorValue == Module::Override) { // Update the destination flag to that of the source. DstModFlags->setOperand(DstIndex, SrcOp); Flags[ID].first = SrcOp; continue; } // Diagnose inconsistent merge behavior types. if (SrcBehaviorValue != DstBehaviorValue) return stringErr("linking module flags '" + ID->getString() + "': IDs have conflicting behaviors"); auto replaceDstValue = [&](MDNode *New) { Metadata *FlagOps[] = {DstOp->getOperand(0), ID, New}; MDNode *Flag = MDNode::get(DstM.getContext(), FlagOps); DstModFlags->setOperand(DstIndex, Flag); Flags[ID].first = Flag; }; // Perform the merge for standard behavior types. switch (SrcBehaviorValue) { case Module::Require: case Module::Override: llvm_unreachable("not possible"); case Module::Error: { // Emit an error if the values differ. if (SrcOp->getOperand(2) != DstOp->getOperand(2)) return stringErr("linking module flags '" + ID->getString() + "': IDs have conflicting values"); continue; } case Module::Warning: { // Emit a warning if the values differ. if (SrcOp->getOperand(2) != DstOp->getOperand(2)) { emitWarning("linking module flags '" + ID->getString() + "': IDs have conflicting values"); } continue; } case Module::Append: { MDNode *DstValue = cast<MDNode>(DstOp->getOperand(2)); MDNode *SrcValue = cast<MDNode>(SrcOp->getOperand(2)); SmallVector<Metadata *, 8> MDs; MDs.reserve(DstValue->getNumOperands() + SrcValue->getNumOperands()); MDs.append(DstValue->op_begin(), DstValue->op_end()); MDs.append(SrcValue->op_begin(), SrcValue->op_end()); replaceDstValue(MDNode::get(DstM.getContext(), MDs)); break; } case Module::AppendUnique: { SmallSetVector<Metadata *, 16> Elts; MDNode *DstValue = cast<MDNode>(DstOp->getOperand(2)); MDNode *SrcValue = cast<MDNode>(SrcOp->getOperand(2)); Elts.insert(DstValue->op_begin(), DstValue->op_end()); Elts.insert(SrcValue->op_begin(), SrcValue->op_end()); replaceDstValue(MDNode::get(DstM.getContext(), makeArrayRef(Elts.begin(), Elts.end()))); break; } } } // Check all of the requirements. for (unsigned I = 0, E = Requirements.size(); I != E; ++I) { MDNode *Requirement = Requirements[I]; MDString *Flag = cast<MDString>(Requirement->getOperand(0)); Metadata *ReqValue = Requirement->getOperand(1); MDNode *Op = Flags[Flag].first; if (!Op || Op->getOperand(2) != ReqValue) return stringErr("linking module flags '" + Flag->getString() + "': does not have the required value"); } return Error::success(); }
/// linkModuleFlagsMetadata - Merge the linker flags in Src into the Dest /// module. bool ModuleLinker::linkModuleFlagsMetadata() { const NamedMDNode *SrcModFlags = SrcM->getModuleFlagsMetadata(); if (!SrcModFlags) return false; NamedMDNode *DstModFlags = DstM->getOrInsertModuleFlagsMetadata(); // If the destination module doesn't have module flags yet, then just copy // over the source module's flags. if (DstModFlags->getNumOperands() == 0) { for (unsigned I = 0, E = SrcModFlags->getNumOperands(); I != E; ++I) DstModFlags->addOperand(SrcModFlags->getOperand(I)); return false; } bool HasErr = false; // Otherwise, we have to merge them based on their behaviors. First, // categorize all of the nodes in the modules' module flags. If an error or // warning occurs, then emit the appropriate message(s). DenseMap<MDString*, MDNode*> ErrorNode; DenseMap<MDString*, MDNode*> WarningNode; DenseMap<MDString*, MDNode*> OverrideNode; DenseMap<MDString*, SmallSetVector<MDNode*, 8> > RequireNodes; SmallSetVector<MDString*, 16> SeenIDs; HasErr |= categorizeModuleFlagNodes(SrcModFlags, ErrorNode, WarningNode, OverrideNode, RequireNodes, SeenIDs); HasErr |= categorizeModuleFlagNodes(DstModFlags, ErrorNode, WarningNode, OverrideNode, RequireNodes, SeenIDs); // Check that there isn't both an error and warning node for a flag. for (SmallSetVector<MDString*, 16>::iterator I = SeenIDs.begin(), E = SeenIDs.end(); I != E; ++I) { MDString *ID = *I; if (ErrorNode[ID] && WarningNode[ID]) HasErr = emitError("linking module flags '" + ID->getString() + "': IDs have conflicting behaviors"); } // Early exit if we had an error. if (HasErr) return true; // Get the destination's module flags ready for new operands. DstModFlags->dropAllReferences(); // Add all of the module flags to the destination module. DenseMap<MDString*, SmallVector<MDNode*, 4> > AddedNodes; for (SmallSetVector<MDString*, 16>::iterator I = SeenIDs.begin(), E = SeenIDs.end(); I != E; ++I) { MDString *ID = *I; if (OverrideNode[ID]) { DstModFlags->addOperand(OverrideNode[ID]); AddedNodes[ID].push_back(OverrideNode[ID]); } else if (ErrorNode[ID]) { DstModFlags->addOperand(ErrorNode[ID]); AddedNodes[ID].push_back(ErrorNode[ID]); } else if (WarningNode[ID]) { DstModFlags->addOperand(WarningNode[ID]); AddedNodes[ID].push_back(WarningNode[ID]); } for (SmallSetVector<MDNode*, 8>::iterator II = RequireNodes[ID].begin(), IE = RequireNodes[ID].end(); II != IE; ++II) DstModFlags->addOperand(*II); } // Now check that all of the requirements have been satisfied. for (SmallSetVector<MDString*, 16>::iterator I = SeenIDs.begin(), E = SeenIDs.end(); I != E; ++I) { MDString *ID = *I; SmallSetVector<MDNode*, 8> &Set = RequireNodes[ID]; for (SmallSetVector<MDNode*, 8>::iterator II = Set.begin(), IE = Set.end(); II != IE; ++II) { MDNode *Node = *II; assert(isa<MDNode>(Node->getOperand(2)) && "Module flag's third operand must be an MDNode!"); MDNode *Val = cast<MDNode>(Node->getOperand(2)); MDString *ReqID = cast<MDString>(Val->getOperand(0)); Value *ReqVal = Val->getOperand(1); bool HasValue = false; for (SmallVectorImpl<MDNode*>::iterator RI = AddedNodes[ReqID].begin(), RE = AddedNodes[ReqID].end(); RI != RE; ++RI) { MDNode *ReqNode = *RI; if (ReqNode->getOperand(2) == ReqVal) { HasValue = true; break; } } if (!HasValue) HasErr = emitError("linking module flags '" + ReqID->getString() + "': does not have the required value"); } } return HasErr; }
/// PrepareMonoLSDA - Collect information needed by EmitMonoLSDA /// /// This function collects information available only during EndFunction which is needed /// by EmitMonoLSDA and stores it into EHFrameInfo. It is the same as the /// beginning of EmitExceptionTable. /// void DwarfMonoException::PrepareMonoLSDA(FunctionEHFrameInfo *EHFrameInfo) { const std::vector<const GlobalVariable *> &TypeInfos = MMI->getTypeInfos(); const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads(); const MachineFunction *MF = Asm->MF; // Sort the landing pads in order of their type ids. This is used to fold // duplicate actions. SmallVector<const LandingPadInfo *, 64> LandingPads; LandingPads.reserve(PadInfos.size()); for (unsigned i = 0, N = PadInfos.size(); i != N; ++i) LandingPads.push_back(&PadInfos[i]); std::sort(LandingPads.begin(), LandingPads.end(), [](const LandingPadInfo *L, const LandingPadInfo *R) { return L->TypeIds < R->TypeIds; }); // Invokes and nounwind calls have entries in PadMap (due to being bracketed // by try-range labels when lowered). Ordinary calls do not, so appropriate // try-ranges for them need be deduced when using DWARF exception handling. RangeMapType PadMap; for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) { const LandingPadInfo *LandingPad = LandingPads[i]; for (unsigned j = 0, E = LandingPad->BeginLabels.size(); j != E; ++j) { MCSymbol *BeginLabel = LandingPad->BeginLabels[j]; assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!"); PadRange P = { i, j }; PadMap[BeginLabel] = P; } } // Compute the call-site table. SmallVector<MonoCallSiteEntry, 64> CallSites; MCSymbol *LastLabel = 0; for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); I != E; ++I) { for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end(); MI != E; ++MI) { if (!MI->isLabel()) { continue; } MCSymbol *BeginLabel = MI->getOperand(0).getMCSymbol(); assert(BeginLabel && "Invalid label!"); RangeMapType::iterator L = PadMap.find(BeginLabel); if (L == PadMap.end()) continue; PadRange P = L->second; const LandingPadInfo *LandingPad = LandingPads[P.PadIndex]; assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] && "Inconsistent landing pad map!"); // Mono emits one landing pad for each CLR exception clause, // and the type info contains the clause index assert (LandingPad->TypeIds.size() == 1); assert (LandingPad->LandingPadLabel); LastLabel = LandingPad->EndLabels[P.RangeIndex]; MonoCallSiteEntry Site = {BeginLabel, LastLabel, LandingPad->LandingPadLabel, LandingPad->TypeIds [0]}; assert(Site.BeginLabel && Site.EndLabel && Site.PadLabel && "Invalid landing pad!"); // FIXME: This doesn't work because it includes ranges outside clauses #if 0 // Try to merge with the previous call-site. if (CallSites.size()) { MonoCallSiteEntry &Prev = CallSites.back(); if (Site.PadLabel == Prev.PadLabel && Site.TypeID == Prev.TypeID) { // Extend the range of the previous entry. Prev.EndLabel = Site.EndLabel; continue; } } #endif // Otherwise, create a new call-site. CallSites.push_back(Site); } } // // Compute a mapping from method names to their AOT method index // if (FuncIndexes.size () == 0) { const Module *m = MMI->getModule (); NamedMDNode *indexes = m->getNamedMetadata ("mono.function_indexes"); if (indexes) { for (unsigned int i = 0; i < indexes->getNumOperands (); ++i) { MDNode *n = indexes->getOperand (i); MDString *s = (MDString*)n->getOperand (0); ConstantInt *idx = (ConstantInt*)n->getOperand (1); FuncIndexes.GetOrCreateValue (s->getString (), (int)idx->getLimitedValue () + 1); } } } MonoEHFrameInfo *MonoEH = &EHFrameInfo->MonoEH; // Save information for EmitMonoLSDA MonoEH->MF = Asm->MF; MonoEH->FunctionNumber = Asm->getFunctionNumber(); MonoEH->CallSites.insert(MonoEH->CallSites.begin(), CallSites.begin(), CallSites.end()); MonoEH->TypeInfos = TypeInfos; MonoEH->PadInfos = PadInfos; MonoEH->MonoMethodIdx = FuncIndexes.lookup (Asm->MF->getFunction ()->getName ()) - 1; //outs()<<"A:"<<Asm->MF->getFunction()->getName() << " " << MonoEH->MonoMethodIdx << "\n"; int ThisSlot = Asm->MF->getMonoInfo()->getThisStackSlot(); if (ThisSlot != -1) { unsigned FrameReg; MonoEH->ThisOffset = Asm->MF->getTarget ().getSubtargetImpl ()->getFrameLowering ()->getFrameIndexReference (*Asm->MF, ThisSlot, FrameReg); MonoEH->FrameReg = Asm->MF->getTarget ().getSubtargetImpl ()->getRegisterInfo ()->getDwarfRegNum (FrameReg, true); } else { MonoEH->FrameReg = -1; } }