void WorklessInstrument::SetupGlobals(Module * pModule) { assert(pModule->getGlobalVariable("SAMPLE_RATE")==NULL); this->SAMPLE_RATE = new GlobalVariable(*pModule, this->IntType, false, GlobalValue::CommonLinkage, 0, "SAMPLE_RATE"); this->SAMPLE_RATE->setAlignment(4); this->SAMPLE_RATE->setInitializer(this->ConstantInt0); assert(pModule->getGlobalVariable("PC_SAMPLE_RATE")==NULL); this->PC_SAMPLE_RATE = new GlobalVariable(*pModule, this->CharStarType, false, GlobalValue::CommonLinkage, 0, "PC_SAMPLE_RATE"); this->PC_SAMPLE_RATE->setAlignment(8); this->PC_SAMPLE_RATE->setInitializer(this->ConstantNULL); assert(pModule->getGlobalVariable("numGlobalCounter")==NULL); this->numGlobalCounter = new GlobalVariable( *pModule , this->LongType, false, GlobalValue::ExternalLinkage, 0, "numGlobalCounter"); this->numGlobalCounter->setAlignment(8); this->numGlobalCounter->setInitializer(this->ConstantLong0); /* assert(pModule->getGlobalVariable("numInstances")==NULL); this->numInstances = new GlobalVariable(*pModule, this->LongType, false, GlobalVariable::ExternalLinkage, 0, "numInstances"); this->numInstances->setAlignment(8); this->numInstances->setInitializer(this->ConstantLong0); */ assert(pModule->getGlobalVariable("CURRENT_SAMPLE") == NULL); this->CURRENT_SAMPLE = new GlobalVariable(*pModule, this->LongType, false, GlobalValue::ExternalLinkage, 0, "CURRENT_SAMPLE"); this->CURRENT_SAMPLE->setAlignment(8); this->CURRENT_SAMPLE->setInitializer(this->ConstantLong0); //"SAMPLE_RATE" string ArrayType* ArrayTy12 = ArrayType::get(IntegerType::get(pModule->getContext(), 8), 12); GlobalVariable * pArrayStr = new GlobalVariable(*pModule, ArrayTy12, true, GlobalValue::PrivateLinkage, 0, ""); pArrayStr->setAlignment(1); Constant * ConstArray = ConstantDataArray::getString(pModule->getContext(), "SAMPLE_RATE", true); vector<Constant *> vecIndex; vecIndex.push_back(this->ConstantInt0); vecIndex.push_back(this->ConstantInt0); this->SAMPLE_RATE_ptr = ConstantExpr::getGetElementPtr(pArrayStr, vecIndex); pArrayStr->setInitializer(ConstArray); //"" ArrayType * ArrayTy17 = ArrayType::get(IntegerType::get(pModule->getContext(), 8), 17); pArrayStr = new GlobalVariable(*pModule, ArrayTy17, true, GlobalValue::PrivateLinkage, 0, ""); pArrayStr->setAlignment(1); ConstArray = ConstantDataArray::getString(pModule->getContext(), "SAMPLE_RATE: %d\x0A", true); vecIndex.clear(); vecIndex.push_back(this->ConstantInt0); vecIndex.push_back(this->ConstantInt0); this->Output_Format_String = ConstantExpr::getGetElementPtr(pArrayStr, vecIndex); pArrayStr->setInitializer(ConstArray); }
void Connection::unsetFifo(){ //Get GV of the port GlobalVariable* srcVar = srcPort->getFifoVar(); GlobalVariable* dstVar = tgtPort->getFifoVar(); //Remove GV initializer srcVar->setInitializer(NULL); dstVar->setInitializer(NULL); //Delete the fifo if (fifo != NULL){ delete fifo; fifo = NULL; } }
Constant *LLVMFormula::getGlobalVariableFor (double *ptr) { // Thanks to the unladen-swallow project for this snippet, which was almost // impossible to figure out from the LLVM docs! // See if the JIT already knows about this global GlobalVariable *result = const_cast<GlobalVariable *>( cast_or_null<GlobalVariable>( engine->getGlobalValueAtAddress (ptr))); if (result && result->hasInitializer ()) return result; Constant *initializer = ConstantFP::get (Type::getDoubleTy (getGlobalContext ()), *ptr); if (result == NULL) { // Make a global variable result = new GlobalVariable (*module, initializer->getType (), false, GlobalVariable::InternalLinkage, NULL, ""); // Link the global variable to the right address engine->addGlobalMapping (result, ptr); } assert (!result->hasInitializer ()); // Add the initial value result->setInitializer (initializer); return result; }
static GlobalVariable *getAiVar(Function &F, const CallInst *CI) { const ConstantExpr *GEP = dyn_cast<const ConstantExpr>(CI->getOperand(1)); assert(GEP && GEP->getOpcode() == Instruction::GetElementPtr); const GlobalVariable *strVar = dyn_cast<const GlobalVariable>(GEP->getOperand(0)); assert(strVar && strVar->hasInitializer()); const ConstantDataArray *str = dyn_cast<const ConstantDataArray>(strVar->getInitializer()); assert(str && str->isCString()); std::string id = str->getAsCString(); char *cstr = new char[11 + id.size() + 1]; strcpy(cstr, "__ai_state_"); /* len=11 */ strcpy(cstr + 11, id.c_str()); for (size_t i = 11; i < 11 + id.size(); i++) if (cstr[i] != '_' && !isupper(cstr[i]) && !islower(cstr[i])) cstr[i] = 'X'; Type *intType = TypeBuilder<int, false>::get(F.getContext()); GlobalVariable *glob = dyn_cast<GlobalVariable>(F.getParent()->getOrInsertGlobal(cstr, intType)); delete cstr; glob->setInitializer(ConstantInt::get( TypeBuilder<int, false>::get(F.getContext()), 0)); return glob; }
// global variables to pointers are pretty common, // so this method is available as a convenience for emitting them. // for other types, the formula for implementation is straightforward: // (see stringConstPtr, for an alternative example to the code below) // // if in imaging_mode, emit a GlobalVariable with the same name and an initializer to the shadow_module // making it valid for emission and reloading in the sysimage // // then add a global mapping to the current value (usually from calloc'd space) // to the execution engine to make it valid for the current session (with the current value) void* jl_emit_and_add_to_shadow(GlobalVariable *gv, void *gvarinit) { PointerType *T = cast<PointerType>(gv->getType()->getElementType()); // pointer is the only supported type here GlobalVariable *shadowvar = NULL; #if defined(USE_MCJIT) || defined(USE_ORCJIT) if (imaging_mode) #endif shadowvar = global_proto(gv, shadow_output); if (shadowvar) { shadowvar->setInitializer(ConstantPointerNull::get(T)); shadowvar->setLinkage(GlobalVariable::InternalLinkage); addComdat(shadowvar); if (imaging_mode && gvarinit) { // make the pointer valid for future sessions jl_sysimg_gvars.push_back(ConstantExpr::getBitCast(shadowvar, T_psize)); jl_value_llvm gv_struct; gv_struct.gv = global_proto(gv); gv_struct.index = jl_sysimg_gvars.size(); jl_value_to_llvm[gvarinit] = gv_struct; } } // make the pointer valid for this session #if defined(USE_MCJIT) || defined(USE_ORCJIT) void *slot = calloc(1, sizeof(void*)); jl_ExecutionEngine->addGlobalMapping(gv, slot); return slot; #else return jl_ExecutionEngine->getPointerToGlobal(shadowvar); #endif }
bool Prepare::handleAsm(Function &F, CallInst *CI) { const InlineAsm *IA = cast<InlineAsm>(CI->getCalledValue()); std::string ASM = IA->getAsmString(); std::string CONS = IA->getConstraintString(); // BasicBlock *BB = CI->getParent(); if ((ASM.empty() && !CI->getNumArgOperands()) || /* a barrier */ !ASM.compare(0, 6, "1:\tud2") || !ASM.compare("lfence") || !ASM.compare("mfence") || !ASM.compare("sfence")) { /* errs() << ASM << " (" << F.getName() << "): " << ASM.empty() << " " << !ASM.compare(0, 6, "1:\tud2") << " " << !ASM.compare("lfence") << " " << !ASM.compare("mfence") << " " << !ASM.compare("sfence"); BB->dump();*/ CI->eraseFromParent(); return true; } else if (ASM.empty() && CI->getNumArgOperands() == 1) { /* reloc hide */ ReplaceInstWithInst(CI, CastInst::CreatePointerCast(CI->getArgOperand(0), CI->getType())); return true; } else if (!ASM.compare("movs %gs:${1:c},$0") || /* reading pda */ !ASM.compare("movl %gs:${1:c},$0") || !ASM.compare("movq %gs:${1:c},$0")) { const ConstantInt *param = dyn_cast<ConstantInt>(CI->getArgOperand(0)); if (param) { const APInt ¶mVal = param->getValue(); Module *M = F.getParent(); if (paramVal == 0) { /* current */ ReplaceInstWithInst(CI, new LoadInst( M->getOrInsertGlobal("__ai_current_singleton", CI->getType()))); return true; } else { /* others, let's fake it with global var */ GlobalVariable *GV = dyn_cast<GlobalVariable>( M->getOrInsertGlobal("__ai_pda_" + paramVal.toString(10, false), CI->getType())); GV->setInitializer(Constant::getNullValue(CI->getType())); if (CI->getType()->isPointerTy()) errs() << "Warn ptr type => we set it to point to NULL\n"; ReplaceInstWithInst(CI, new LoadInst(GV)); return true; } } } else if (!ASM.compare(0, 16, "call __put_user_") || !ASM.compare(0, 16, "call __get_user_") ) { BasicBlock::iterator it(CI); ReplaceInstWithValue(CI->getParent()->getInstList(), it, Constant::getNullValue(CI->getType())); return true; } errs() << "ASM str (" << F.getName() << "): " << ASM << " from:\n"; CI->dump(); errs() << "===========\n"; return false; }
static bool addTableDataSection(NativeModulePtr natMod, Module *M, VA &newVA, const T& table) { list<DataSection> &globaldata = natMod->getData(); list<DataSection>::const_iterator git = globaldata.begin(); // ensure we make this the last data section newVA = 0; while( git != globaldata.end() ) { const DataSection &dt = *git; uint64_t extent = dt.getBase() + dt.getSize(); if(newVA < extent) { newVA = extent; } git++; } // skip a few newVA += 4; // create a new data section from the table DataSection *ds = tableToDataSection(newVA, table); // add to global data section list globaldata.push_back(*ds); // create the GlobalVariable string bufferName = "data_0x" + to_string<VA>(newVA, hex); StructType *st_opaque = StructType::create(M->getContext()); GlobalVariable *gv = new GlobalVariable(*M, st_opaque, true, GlobalVariable::InternalLinkage, NULL, bufferName); vector<Type*> data_section_types; vector<Constant*> secContents; dataSectionToTypesContents(globaldata, *ds, M, secContents, data_section_types, false); st_opaque->setBody(data_section_types, true); Constant *cst = ConstantStruct::get(st_opaque, secContents); gv->setAlignment(4); gv->setInitializer(cst); return true; }
virtual Value * materializeValueFor(Value * V) { if(Function * fn = dyn_cast<Function>(V)) { assert(fn->getParent() == src); Function * newfn = dest->getFunction(fn->getName()); if(!newfn) { newfn = Function::Create(fn->getFunctionType(),fn->getLinkage(), fn->getName(),dest); newfn->copyAttributesFrom(fn); } if(!fn->isDeclaration() && newfn->isDeclaration() && copyGlobal(fn,data)) { for(Function::arg_iterator II = newfn->arg_begin(), I = fn->arg_begin(), E = fn->arg_end(); I != E; ++I, ++II) { II->setName(I->getName()); VMap[I] = II; } VMap[fn] = newfn; SmallVector<ReturnInst*,8> Returns; CloneFunctionInto(newfn, fn, VMap, true, Returns, "", NULL, NULL, this); } return newfn; } else if(GlobalVariable * GV = dyn_cast<GlobalVariable>(V)) { GlobalVariable * newGV = dest->getGlobalVariable(GV->getName(),true); if(!newGV) { newGV = new GlobalVariable(*dest,GV->getType()->getElementType(),GV->isConstant(),GV->getLinkage(),NULL,GV->getName(),NULL,GlobalVariable::NotThreadLocal,GV->getType()->getAddressSpace()); newGV->copyAttributesFrom(GV); if(!GV->isDeclaration()) { if(!copyGlobal(GV,data)) { newGV->setExternallyInitialized(true); } else if(GV->hasInitializer()) { Value * C = MapValue(GV->getInitializer(),VMap,RF_None,NULL,this); newGV->setInitializer(cast<Constant>(C)); } } } return newGV; } else if(MDNode * MD = dyn_cast<MDNode>(V)) { DISubprogram SP(MD); if(DI != NULL && SP.isSubprogram()) { if(Function * OF = SP.getFunction()) { Function * F = cast<Function>(MapValue(OF,VMap,RF_None,NULL,this)); DISubprogram NSP = DI->createFunction(SP.getContext(), SP.getName(), SP.getLinkageName(), DI->createFile(SP.getFilename(),SP.getDirectory()), SP.getLineNumber(), SP.getType(), SP.isLocalToUnit(), SP.isDefinition(), SP.getScopeLineNumber(),SP.getFlags(),SP.isOptimized(), F); return NSP; } /* fallthrough */ } /* fallthrough */ } return NULL; }
void StorageSoa::addAddress(int idx) { GlobalVariable *val = new GlobalVariable( /*Type=*/IntegerType::get(32), /*isConstant=*/false, /*Linkage=*/GlobalValue::ExternalLinkage, /*Initializer=*/0, // has initializer, specified below /*Name=*/name("address"), currentModule()); val->setInitializer(Constant::getNullValue(IntegerType::get(32))); debug_printf("adding to %d\n", idx); m_addresses[idx] = val; }
// linkGlobalInits - Update the initializers in the Dest module now that all // globals that may be referenced are in Dest. void ModuleLinker::linkGlobalInits() { // Loop over all of the globals in the src module, mapping them over as we go for (Module::const_global_iterator I = SrcM->global_begin(), E = SrcM->global_end(); I != E; ++I) { // Only process initialized GV's or ones not already in dest. if (!I->hasInitializer() || DoNotLinkFromSource.count(I)) continue; // Grab destination global variable. GlobalVariable *DGV = cast<GlobalVariable>(ValueMap[I]); // Figure out what the initializer looks like in the dest module. DGV->setInitializer(MapValue(I->getInitializer(), ValueMap, RF_None, &TypeMap)); } }
bool runOnFunction(Function &F) override { if (F.hasFnAttribute("emit_llvm")) { Module *M = F.getParent(); static Regex R("4func.*$"); GlobalVariable *GV = M->getGlobalVariable(R.sub("2irE", F.getName()), true); if (GV != NULL) { string S; raw_string_ostream SO(S); F.print(SO); Constant *CDA = ConstantDataArray::getString(M->getContext(), SO.str()); GV->setInitializer(ConstantExpr::getBitCast(new GlobalVariable(*M, CDA->getType(), true, GV->getLinkage(), CDA), Type::getInt8PtrTy(M->getContext()))); return true; } } return false; }
void Mapper::mapAppendingVariable(GlobalVariable &GV, Constant *InitPrefix, bool IsOldCtorDtor, ArrayRef<Constant *> NewMembers) { SmallVector<Constant *, 16> Elements; if (InitPrefix) { unsigned NumElements = cast<ArrayType>(InitPrefix->getType())->getNumElements(); for (unsigned I = 0; I != NumElements; ++I) Elements.push_back(InitPrefix->getAggregateElement(I)); } PointerType *VoidPtrTy; Type *EltTy; if (IsOldCtorDtor) { // FIXME: This upgrade is done during linking to support the C API. See // also IRLinker::linkAppendingVarProto() in IRMover.cpp. VoidPtrTy = Type::getInt8Ty(GV.getContext())->getPointerTo(); auto &ST = *cast<StructType>(NewMembers.front()->getType()); Type *Tys[3] = {ST.getElementType(0), ST.getElementType(1), VoidPtrTy}; EltTy = StructType::get(GV.getContext(), Tys, false); } for (auto *V : NewMembers) { Constant *NewV; if (IsOldCtorDtor) { auto *S = cast<ConstantStruct>(V); auto *E1 = cast<Constant>(mapValue(S->getOperand(0))); auto *E2 = cast<Constant>(mapValue(S->getOperand(1))); Constant *Null = Constant::getNullValue(VoidPtrTy); NewV = ConstantStruct::get(cast<StructType>(EltTy), E1, E2, Null); } else { NewV = cast_or_null<Constant>(mapValue(V)); } Elements.push_back(NewV); } GV.setInitializer(ConstantArray::get( cast<ArrayType>(GV.getType()->getElementType()), Elements)); }
void llvm::InsertProfilingShutdownCall(Function *Callee, Module *Mod) { // llvm.global_dtors is an array of type { i32, void ()* }. Prepare those // types. Type *GlobalDtorElems[2] = { Type::getInt32Ty(Mod->getContext()), FunctionType::get(Type::getVoidTy(Mod->getContext()), false)->getPointerTo() }; StructType *GlobalDtorElemTy = StructType::get(Mod->getContext(), GlobalDtorElems, false); // Construct the new element we'll be adding. Constant *Elem[2] = { ConstantInt::get(Type::getInt32Ty(Mod->getContext()), 65535), ConstantExpr::getBitCast(Callee, GlobalDtorElems[1]) }; // If llvm.global_dtors exists, make a copy of the things in its list and // delete it, to replace it with one that has a larger array type. std::vector<Constant *> dtors; if (GlobalVariable *GlobalDtors = Mod->getNamedGlobal("llvm.global_dtors")) { if (ConstantArray *InitList = dyn_cast<ConstantArray>(GlobalDtors->getInitializer())) { for (unsigned i = 0, e = InitList->getType()->getNumElements(); i != e; ++i) dtors.push_back(cast<Constant>(InitList->getOperand(i))); } GlobalDtors->eraseFromParent(); } // Build up llvm.global_dtors with our new item in it. GlobalVariable *GlobalDtors = new GlobalVariable( *Mod, ArrayType::get(GlobalDtorElemTy, 1), false, GlobalValue::AppendingLinkage, NULL, "llvm.global_dtors"); dtors.push_back(ConstantStruct::get(GlobalDtorElemTy, Elem)); GlobalDtors->setInitializer(ConstantArray::get( cast<ArrayType>(GlobalDtors->getType()->getElementType()), dtors)); }
llvm::Constant * CodeGenerator::genGlobalVar(const VariableDefn * var) { // Global variables never set the IRValue field, because that field has a different value // depending on what module we are compiling. DASSERT(var->defnType() == Defn::Var); DASSERT(var->irValue() == NULL); DASSERT(var->storageClass() == Storage_Global || var->storageClass() == Storage_Static); DASSERT_OBJ(var->passes().isFinished(VariableDefn::InitializerPass), var); GlobalVariable * gv = irModule_->getGlobalVariable(var->linkageName()); if (gv != NULL) { return gv; } const Type * varType = var->type().unqualified(); DASSERT(varType != NULL); // Create the global variable GlobalValue::LinkageTypes linkType = Function::ExternalLinkage; if (var->isSynthetic()) { linkType = Function::LinkOnceAnyLinkage; } // The reason that this is irType instead of irEmbeddedType is because LLVM always turns // the type of a global variable into a pointer anyway. llvm::Type * irType = varType->irEmbeddedType(); gv = new GlobalVariable(*irModule_, irType, false, linkType, NULL, var->linkageName(), NULL, var->isThreadLocal()); // Only supply an initialization expression if the variable was // defined in this module - otherwise, it's an external declaration. if (var->module() == module_ || var->isSynthetic()) { addStaticRoot(gv, varType); if (debug_) { genDIGlobalVariable(var, gv); } // If it has an initialization expression const Expr * initExpr = var->initValue(); if (initExpr != NULL) { if (initExpr->isConstant()) { Constant * initValue = genConstExpr(initExpr); if (initValue == NULL) { return NULL; } if (varType->isReferenceType()) { initValue = new GlobalVariable( *irModule_, initValue->getType(), false, linkType, initValue, var->linkageName() + ".init"); initValue = llvm::ConstantExpr::getPointerCast(initValue, varType->irEmbeddedType()); } gv->setInitializer(initValue); } else { genModuleInitFunc(); // Add it to the module init function BasicBlock * savePoint = builder_.GetInsertBlock(); builder_.SetInsertPoint(moduleInitBlock_); // Generate the expression. Value * initValue = genExpr(initExpr); if (initValue != NULL) { gv->setInitializer(llvm::Constant::getNullValue(irType)); builder_.CreateStore(initValue, gv); } if (savePoint != NULL) { builder_.SetInsertPoint(savePoint); } } } else if (!var->isExtern()) { // No initializer, so set the value to zerofill. gv->setInitializer(llvm::Constant::getNullValue(irType)); } } return gv; }
bool LowerEmuTLS::addEmuTlsVar(Module &M, const GlobalVariable *GV) { LLVMContext &C = M.getContext(); PointerType *VoidPtrType = Type::getInt8PtrTy(C); std::string EmuTlsVarName = ("__emutls_v." + GV->getName()).str(); GlobalVariable *EmuTlsVar = M.getNamedGlobal(EmuTlsVarName); if (EmuTlsVar) return false; // It has been added before. const DataLayout &DL = M.getDataLayout(); Constant *NullPtr = ConstantPointerNull::get(VoidPtrType); // Get non-zero initializer from GV's initializer. const Constant *InitValue = nullptr; if (GV->hasInitializer()) { InitValue = GV->getInitializer(); const ConstantInt *InitIntValue = dyn_cast<ConstantInt>(InitValue); // When GV's init value is all 0, omit the EmuTlsTmplVar and let // the emutls library function to reset newly allocated TLS variables. if (isa<ConstantAggregateZero>(InitValue) || (InitIntValue && InitIntValue->isZero())) InitValue = nullptr; } // Create the __emutls_v. symbol, whose type has 4 fields: // word size; // size of GV in bytes // word align; // alignment of GV // void *ptr; // initialized to 0; set at run time per thread. // void *templ; // 0 or point to __emutls_t.* // sizeof(word) should be the same as sizeof(void*) on target. IntegerType *WordType = DL.getIntPtrType(C); PointerType *InitPtrType = InitValue ? PointerType::getUnqual(InitValue->getType()) : VoidPtrType; Type *ElementTypes[4] = {WordType, WordType, VoidPtrType, InitPtrType}; ArrayRef<Type*> ElementTypeArray(ElementTypes, 4); StructType *EmuTlsVarType = StructType::create(ElementTypeArray); EmuTlsVar = cast<GlobalVariable>( M.getOrInsertGlobal(EmuTlsVarName, EmuTlsVarType)); copyLinkageVisibility(M, GV, EmuTlsVar); // Define "__emutls_t.*" and "__emutls_v.*" only if GV is defined. if (!GV->hasInitializer()) return true; Type *GVType = GV->getValueType(); unsigned GVAlignment = GV->getAlignment(); if (!GVAlignment) { // When LLVM IL declares a variable without alignment, use // the ABI default alignment for the type. GVAlignment = DL.getABITypeAlignment(GVType); } // Define "__emutls_t.*" if there is InitValue GlobalVariable *EmuTlsTmplVar = nullptr; if (InitValue) { std::string EmuTlsTmplName = ("__emutls_t." + GV->getName()).str(); EmuTlsTmplVar = dyn_cast_or_null<GlobalVariable>( M.getOrInsertGlobal(EmuTlsTmplName, GVType)); assert(EmuTlsTmplVar && "Failed to create emualted TLS initializer"); EmuTlsTmplVar->setConstant(true); EmuTlsTmplVar->setInitializer(const_cast<Constant*>(InitValue)); EmuTlsTmplVar->setAlignment(GVAlignment); copyLinkageVisibility(M, GV, EmuTlsTmplVar); } // Define "__emutls_v.*" with initializer and alignment. Constant *ElementValues[4] = { ConstantInt::get(WordType, DL.getTypeStoreSize(GVType)), ConstantInt::get(WordType, GVAlignment), NullPtr, EmuTlsTmplVar ? EmuTlsTmplVar : NullPtr }; ArrayRef<Constant*> ElementValueArray(ElementValues, 4); EmuTlsVar->setInitializer( ConstantStruct::get(EmuTlsVarType, ElementValueArray)); unsigned MaxAlignment = std::max( DL.getABITypeAlignment(WordType), DL.getABITypeAlignment(VoidPtrType)); EmuTlsVar->setAlignment(MaxAlignment); return true; }
std::unique_ptr<Module> llvm::CloneModule( const Module *M, ValueToValueMapTy &VMap, std::function<bool(const GlobalValue *)> ShouldCloneDefinition) { // First off, we need to create the new module. std::unique_ptr<Module> New = llvm::make_unique<Module>(M->getModuleIdentifier(), M->getContext()); New->setDataLayout(M->getDataLayout()); New->setTargetTriple(M->getTargetTriple()); New->setModuleInlineAsm(M->getModuleInlineAsm()); // Loop over all of the global variables, making corresponding globals in the // new module. Here we add them to the VMap and to the new Module. We // don't worry about attributes or initializers, they will come later. // for (Module::const_global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) { GlobalVariable *GV = new GlobalVariable(*New, I->getValueType(), I->isConstant(), I->getLinkage(), (Constant*) nullptr, I->getName(), (GlobalVariable*) nullptr, I->getThreadLocalMode(), I->getType()->getAddressSpace()); GV->copyAttributesFrom(&*I); VMap[&*I] = GV; } // Loop over the functions in the module, making external functions as before for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) { Function *NF = Function::Create(cast<FunctionType>(I->getValueType()), I->getLinkage(), I->getName(), New.get()); NF->copyAttributesFrom(&*I); VMap[&*I] = NF; } // Loop over the aliases in the module for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end(); I != E; ++I) { if (!ShouldCloneDefinition(&*I)) { // An alias cannot act as an external reference, so we need to create // either a function or a global variable depending on the value type. // FIXME: Once pointee types are gone we can probably pick one or the // other. GlobalValue *GV; if (I->getValueType()->isFunctionTy()) GV = Function::Create(cast<FunctionType>(I->getValueType()), GlobalValue::ExternalLinkage, I->getName(), New.get()); else GV = new GlobalVariable( *New, I->getValueType(), false, GlobalValue::ExternalLinkage, (Constant *)nullptr, I->getName(), (GlobalVariable *)nullptr, I->getThreadLocalMode(), I->getType()->getAddressSpace()); VMap[&*I] = GV; // We do not copy attributes (mainly because copying between different // kinds of globals is forbidden), but this is generally not required for // correctness. continue; } auto *GA = GlobalAlias::create(I->getValueType(), I->getType()->getPointerAddressSpace(), I->getLinkage(), I->getName(), New.get()); GA->copyAttributesFrom(&*I); VMap[&*I] = GA; } // Now that all of the things that global variable initializer can refer to // have been created, loop through and copy the global variable referrers // over... We also set the attributes on the global now. // for (Module::const_global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) { GlobalVariable *GV = cast<GlobalVariable>(VMap[&*I]); if (!ShouldCloneDefinition(&*I)) { // Skip after setting the correct linkage for an external reference. GV->setLinkage(GlobalValue::ExternalLinkage); continue; } if (I->hasInitializer()) GV->setInitializer(MapValue(I->getInitializer(), VMap)); } // Similarly, copy over function bodies now... // for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) { Function *F = cast<Function>(VMap[&*I]); if (!ShouldCloneDefinition(&*I)) { // Skip after setting the correct linkage for an external reference. F->setLinkage(GlobalValue::ExternalLinkage); // Personality function is not valid on a declaration. F->setPersonalityFn(nullptr); continue; } if (!I->isDeclaration()) { Function::arg_iterator DestI = F->arg_begin(); for (Function::const_arg_iterator J = I->arg_begin(); J != I->arg_end(); ++J) { DestI->setName(J->getName()); VMap[&*J] = &*DestI++; } SmallVector<ReturnInst*, 8> Returns; // Ignore returns cloned. CloneFunctionInto(F, &*I, VMap, /*ModuleLevelChanges=*/true, Returns); } if (I->hasPersonalityFn()) F->setPersonalityFn(MapValue(I->getPersonalityFn(), VMap)); } // And aliases for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end(); I != E; ++I) { // We already dealt with undefined aliases above. if (!ShouldCloneDefinition(&*I)) continue; GlobalAlias *GA = cast<GlobalAlias>(VMap[&*I]); if (const Constant *C = I->getAliasee()) GA->setAliasee(MapValue(C, VMap)); } // And named metadata.... for (Module::const_named_metadata_iterator I = M->named_metadata_begin(), E = M->named_metadata_end(); I != E; ++I) { const NamedMDNode &NMD = *I; NamedMDNode *NewNMD = New->getOrInsertNamedMetadata(NMD.getName()); for (unsigned i = 0, e = NMD.getNumOperands(); i != e; ++i) NewNMD->addOperand(MapMetadata(NMD.getOperand(i), VMap)); } return New; }
/// emit_global_to_llvm - Emit the specified VAR_DECL or aggregate CONST_DECL to /// LLVM as a global variable. This function implements the end of /// assemble_variable. void emit_global_to_llvm(tree decl) { if (errorcount || sorrycount) return; // FIXME: Support alignment on globals: DECL_ALIGN. // FIXME: DECL_PRESERVE_P indicates the var is marked with attribute 'used'. // Global register variables don't turn into LLVM GlobalVariables. if (TREE_CODE(decl) == VAR_DECL && DECL_REGISTER(decl)) return; timevar_push(TV_LLVM_GLOBALS); // Get or create the global variable now. GlobalVariable *GV = cast<GlobalVariable>(DECL_LLVM(decl)); // Convert the initializer over. Constant *Init; if (DECL_INITIAL(decl) == 0 || DECL_INITIAL(decl) == error_mark_node) { // This global should be zero initialized. Reconvert the type in case the // forward def of the global and the real def differ in type (e.g. declared // as 'int A[]', and defined as 'int A[100]'). Init = Constant::getNullValue(ConvertType(TREE_TYPE(decl))); } else { assert((TREE_CONSTANT(DECL_INITIAL(decl)) || TREE_CODE(DECL_INITIAL(decl)) == STRING_CST) && "Global initializer should be constant!"); // Temporarily set an initializer for the global, so we don't infinitely // recurse. If we don't do this, we can hit cases where we see "oh a global // with an initializer hasn't been initialized yet, call emit_global_to_llvm // on it". When constructing the initializer it might refer to itself. // this can happen for things like void *G = &G; // GV->setInitializer(UndefValue::get(GV->getType()->getElementType())); Init = TreeConstantToLLVM::Convert(DECL_INITIAL(decl)); } // If we had a forward definition that has a type that disagrees with our // initializer, insert a cast now. This sort of thing occurs when we have a // global union, and the LLVM type followed a union initializer that is // different from the union element used for the type. if (GV->getType()->getElementType() != Init->getType()) { GV->removeFromParent(); GlobalVariable *NGV = new GlobalVariable(Init->getType(), GV->isConstant(), GlobalValue::ExternalLinkage, 0, GV->getName(), TheModule); GV->replaceAllUsesWith(ConstantExpr::getBitCast(NGV, GV->getType())); delete GV; SET_DECL_LLVM(decl, NGV); GV = NGV; } // Set the initializer. GV->setInitializer(Init); // Set thread local (TLS) if (TREE_CODE(decl) == VAR_DECL && DECL_THREAD_LOCAL(decl)) GV->setThreadLocal(true); // Set the linkage. if (!TREE_PUBLIC(decl)) { GV->setLinkage(GlobalValue::InternalLinkage); } else if (DECL_WEAK(decl) || DECL_ONE_ONLY(decl) || (DECL_COMMON(decl) && // DECL_COMMON is only meaningful if no init (!DECL_INITIAL(decl) || DECL_INITIAL(decl) == error_mark_node))) { // llvm-gcc also includes DECL_VIRTUAL_P here. GV->setLinkage(GlobalValue::WeakLinkage); } else if (DECL_COMDAT(decl)) { GV->setLinkage(GlobalValue::LinkOnceLinkage); } #ifdef TARGET_ADJUST_LLVM_LINKAGE TARGET_ADJUST_LLVM_LINKAGE(GV,decl); #endif /* TARGET_ADJUST_LLVM_LINKAGE */ // Handle visibility style if (TREE_PUBLIC(decl)) { if (DECL_VISIBILITY(decl) == VISIBILITY_HIDDEN) GV->setVisibility(GlobalValue::HiddenVisibility); else if (DECL_VISIBILITY(decl) == VISIBILITY_PROTECTED) GV->setVisibility(GlobalValue::ProtectedVisibility); } // Set the section for the global. if (TREE_CODE(decl) == VAR_DECL || TREE_CODE(decl) == CONST_DECL) { if (DECL_SECTION_NAME(decl)) { GV->setSection(TREE_STRING_POINTER(DECL_SECTION_NAME(decl))); #ifdef LLVM_IMPLICIT_TARGET_GLOBAL_VAR_SECTION } else if (const char *Section = LLVM_IMPLICIT_TARGET_GLOBAL_VAR_SECTION(decl)) { GV->setSection(Section); #endif } // Set the alignment for the global if one of the following condition is met // 1) DECL_ALIGN_UNIT does not match alignment as per ABI specification // 2) DECL_ALIGN is set by user. if (DECL_ALIGN_UNIT(decl)) { unsigned TargetAlign = getTargetData().getABITypeAlignment(GV->getType()->getElementType()); if (DECL_USER_ALIGN(decl) || TargetAlign != DECL_ALIGN_UNIT(decl)) GV->setAlignment(DECL_ALIGN_UNIT(decl)); } // Handle used decls if (DECL_PRESERVE_P (decl)) { const Type *SBP= PointerType::get(Type::Int8Ty); AttributeUsedGlobals.push_back(ConstantExpr::getBitCast(GV, SBP)); } // Add annotate attributes for globals if (DECL_ATTRIBUTES(decl)) AddAnnotateAttrsToGlobal(GV, decl); } if (TheDebugInfo) TheDebugInfo->EmitGlobalVariable(GV, decl); timevar_pop(TV_LLVM_GLOBALS); }
Module *llvm::CloneModule(const Module *M, ValueToValueMapTy &VMap) { // First off, we need to create the new module. Module *New = new Module(M->getModuleIdentifier(), M->getContext()); New->setDataLayout(M->getDataLayout()); New->setTargetTriple(M->getTargetTriple()); New->setModuleInlineAsm(M->getModuleInlineAsm()); // Loop over all of the global variables, making corresponding globals in the // new module. Here we add them to the VMap and to the new Module. We // don't worry about attributes or initializers, they will come later. // for (Module::const_global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) { GlobalVariable *GV = new GlobalVariable(*New, I->getType()->getElementType(), I->isConstant(), I->getLinkage(), (Constant*) nullptr, I->getName(), (GlobalVariable*) nullptr, I->getThreadLocalMode(), I->getType()->getAddressSpace()); GV->copyAttributesFrom(I); VMap[I] = GV; } // Loop over the functions in the module, making external functions as before for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) { Function *NF = Function::Create(cast<FunctionType>(I->getType()->getElementType()), I->getLinkage(), I->getName(), New); NF->copyAttributesFrom(I); VMap[I] = NF; } // Loop over the aliases in the module for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end(); I != E; ++I) { auto *PTy = cast<PointerType>(I->getType()); auto *GA = GlobalAlias::create(PTy->getElementType(), PTy->getAddressSpace(), I->getLinkage(), I->getName(), New); GA->copyAttributesFrom(I); VMap[I] = GA; } // Now that all of the things that global variable initializer can refer to // have been created, loop through and copy the global variable referrers // over... We also set the attributes on the global now. // for (Module::const_global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) { GlobalVariable *GV = cast<GlobalVariable>(VMap[I]); if (I->hasInitializer()) GV->setInitializer(MapValue(I->getInitializer(), VMap)); } // Similarly, copy over function bodies now... // for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) { Function *F = cast<Function>(VMap[I]); if (!I->isDeclaration()) { Function::arg_iterator DestI = F->arg_begin(); for (Function::const_arg_iterator J = I->arg_begin(); J != I->arg_end(); ++J) { DestI->setName(J->getName()); VMap[J] = DestI++; } SmallVector<ReturnInst*, 8> Returns; // Ignore returns cloned. CloneFunctionInto(F, I, VMap, /*ModuleLevelChanges=*/true, Returns); } } // And aliases for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end(); I != E; ++I) { GlobalAlias *GA = cast<GlobalAlias>(VMap[I]); if (const Constant *C = I->getAliasee()) GA->setAliasee(cast<GlobalObject>(MapValue(C, VMap))); } // And named metadata.... for (Module::const_named_metadata_iterator I = M->named_metadata_begin(), E = M->named_metadata_end(); I != E; ++I) { const NamedMDNode &NMD = *I; NamedMDNode *NewNMD = New->getOrInsertNamedMetadata(NMD.getName()); for (unsigned i = 0, e = NMD.getNumOperands(); i != e; ++i) NewNMD->addOperand(MapValue(NMD.getOperand(i), VMap)); } return New; }
Module *llvm::CloneModule(const Module *M, ValueToValueMapTy &VMap) { // First off, we need to create the new module... Module *New = new Module(M->getModuleIdentifier(), M->getContext()); New->setDataLayout(M->getDataLayout()); New->setTargetTriple(M->getTargetTriple()); New->setModuleInlineAsm(M->getModuleInlineAsm()); // Copy all of the type symbol table entries over. const TypeSymbolTable &TST = M->getTypeSymbolTable(); for (TypeSymbolTable::const_iterator TI = TST.begin(), TE = TST.end(); TI != TE; ++TI) New->addTypeName(TI->first, TI->second); // Copy all of the dependent libraries over. for (Module::lib_iterator I = M->lib_begin(), E = M->lib_end(); I != E; ++I) New->addLibrary(*I); // Loop over all of the global variables, making corresponding globals in the // new module. Here we add them to the VMap and to the new Module. We // don't worry about attributes or initializers, they will come later. // for (Module::const_global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) { GlobalVariable *GV = new GlobalVariable(*New, I->getType()->getElementType(), false, GlobalValue::ExternalLinkage, 0, I->getName()); GV->setAlignment(I->getAlignment()); VMap[I] = GV; } // Loop over the functions in the module, making external functions as before for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) { Function *NF = Function::Create(cast<FunctionType>(I->getType()->getElementType()), GlobalValue::ExternalLinkage, I->getName(), New); NF->copyAttributesFrom(I); VMap[I] = NF; } // Loop over the aliases in the module for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end(); I != E; ++I) VMap[I] = new GlobalAlias(I->getType(), GlobalAlias::ExternalLinkage, I->getName(), NULL, New); // Now that all of the things that global variable initializer can refer to // have been created, loop through and copy the global variable referrers // over... We also set the attributes on the global now. // for (Module::const_global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) { GlobalVariable *GV = cast<GlobalVariable>(VMap[I]); if (I->hasInitializer()) GV->setInitializer(cast<Constant>(MapValue(I->getInitializer(), VMap))); GV->setLinkage(I->getLinkage()); GV->setThreadLocal(I->isThreadLocal()); GV->setConstant(I->isConstant()); } // Similarly, copy over function bodies now... // for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) { Function *F = cast<Function>(VMap[I]); if (!I->isDeclaration()) { Function::arg_iterator DestI = F->arg_begin(); for (Function::const_arg_iterator J = I->arg_begin(); J != I->arg_end(); ++J) { DestI->setName(J->getName()); VMap[J] = DestI++; } SmallVector<ReturnInst*, 8> Returns; // Ignore returns cloned. CloneFunctionInto(F, I, VMap, Returns); } F->setLinkage(I->getLinkage()); } // And aliases for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end(); I != E; ++I) { GlobalAlias *GA = cast<GlobalAlias>(VMap[I]); GA->setLinkage(I->getLinkage()); if (const Constant* C = I->getAliasee()) GA->setAliasee(cast<Constant>(MapValue(C, VMap))); } // And named metadata.... for (Module::const_named_metadata_iterator I = M->named_metadata_begin(), E = M->named_metadata_end(); I != E; ++I) { const NamedMDNode &NMD = *I; SmallVector<MDNode*, 4> MDs; for (unsigned i = 0, e = NMD.getNumOperands(); i != e; ++i) MDs.push_back(cast<MDNode>(MapValue(NMD.getOperand(i), VMap))); NamedMDNode::Create(New->getContext(), NMD.getName(), MDs.data(), MDs.size(), New); } // Update metadata attach with instructions. for (Module::iterator MI = New->begin(), ME = New->end(); MI != ME; ++MI) for (Function::iterator FI = MI->begin(), FE = MI->end(); FI != FE; ++FI) for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ++BI) { SmallVector<std::pair<unsigned, MDNode *>, 4 > MDs; BI->getAllMetadata(MDs); for (SmallVector<std::pair<unsigned, MDNode *>, 4>::iterator MDI = MDs.begin(), MDE = MDs.end(); MDI != MDE; ++MDI) { Value *MappedValue = MapValue(MDI->second, VMap); if (MDI->second != MappedValue && MappedValue) BI->setMetadata(MDI->first, cast<MDNode>(MappedValue)); } } return New; }
/// SplitFunctionsOutOfModule - Given a module and a list of functions in the /// module, split the functions OUT of the specified module, and place them in /// the new module. Module * llvm::SplitFunctionsOutOfModule(Module *M, const std::vector<Function*> &F, ValueToValueMapTy &VMap) { // Make sure functions & globals are all external so that linkage // between the two modules will work. for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) I->setLinkage(GlobalValue::ExternalLinkage); for (Module::global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) { if (I->hasName() && I->getName()[0] == '\01') I->setName(I->getName().substr(1)); I->setLinkage(GlobalValue::ExternalLinkage); } ValueToValueMapTy NewVMap; Module *New = CloneModule(M, NewVMap); // Remove the Test functions from the Safe module std::set<Function *> TestFunctions; for (unsigned i = 0, e = F.size(); i != e; ++i) { Function *TNOF = cast<Function>(VMap[F[i]]); DEBUG(errs() << "Removing function "); DEBUG(WriteAsOperand(errs(), TNOF, false)); DEBUG(errs() << "\n"); TestFunctions.insert(cast<Function>(NewVMap[TNOF])); DeleteFunctionBody(TNOF); // Function is now external in this module! } // Remove the Safe functions from the Test module for (Module::iterator I = New->begin(), E = New->end(); I != E; ++I) if (!TestFunctions.count(I)) DeleteFunctionBody(I); // Try to split the global initializers evenly for (Module::global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) { GlobalVariable *GV = cast<GlobalVariable>(NewVMap[I]); if (Function *TestFn = globalInitUsesExternalBA(I)) { if (Function *SafeFn = globalInitUsesExternalBA(GV)) { errs() << "*** Error: when reducing functions, encountered " "the global '"; WriteAsOperand(errs(), GV, false); errs() << "' with an initializer that references blockaddresses " "from safe function '" << SafeFn->getName() << "' and from test function '" << TestFn->getName() << "'.\n"; exit(1); } I->setInitializer(0); // Delete the initializer to make it external } else { // If we keep it in the safe module, then delete it in the test module GV->setInitializer(0); } } // Make sure that there is a global ctor/dtor array in both halves of the // module if they both have static ctor/dtor functions. SplitStaticCtorDtor("llvm.global_ctors", M, New, NewVMap); SplitStaticCtorDtor("llvm.global_dtors", M, New, NewVMap); return New; }
Module *llvm::CloneModule(const Module *M, DenseMap<const Value*, Value*> &ValueMap) { // First off, we need to create the new module... Module *New = new Module(M->getModuleIdentifier()); New->setDataLayout(M->getDataLayout()); New->setTargetTriple(M->getTargetTriple()); New->setModuleInlineAsm(M->getModuleInlineAsm()); // Copy all of the type symbol table entries over. const TypeSymbolTable &TST = M->getTypeSymbolTable(); for (TypeSymbolTable::const_iterator TI = TST.begin(), TE = TST.end(); TI != TE; ++TI) New->addTypeName(TI->first, TI->second); // Copy all of the dependent libraries over. for (Module::lib_iterator I = M->lib_begin(), E = M->lib_end(); I != E; ++I) New->addLibrary(*I); // Loop over all of the global variables, making corresponding globals in the // new module. Here we add them to the ValueMap and to the new Module. We // don't worry about attributes or initializers, they will come later. // for (Module::const_global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) { GlobalVariable *GV = new GlobalVariable(I->getType()->getElementType(), false, GlobalValue::ExternalLinkage, 0, I->getName(), New); GV->setAlignment(I->getAlignment()); ValueMap[I] = GV; } // Loop over the functions in the module, making external functions as before for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) { Function *NF = Function::Create(cast<FunctionType>(I->getType()->getElementType()), GlobalValue::ExternalLinkage, I->getName(), New); NF->copyAttributesFrom(I); ValueMap[I] = NF; } // Loop over the aliases in the module for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end(); I != E; ++I) ValueMap[I] = new GlobalAlias(I->getType(), GlobalAlias::ExternalLinkage, I->getName(), NULL, New); // Now that all of the things that global variable initializer can refer to // have been created, loop through and copy the global variable referrers // over... We also set the attributes on the global now. // for (Module::const_global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) { GlobalVariable *GV = cast<GlobalVariable>(ValueMap[I]); if (I->hasInitializer()) GV->setInitializer(cast<Constant>(MapValue(I->getInitializer(), ValueMap))); GV->setLinkage(I->getLinkage()); GV->setThreadLocal(I->isThreadLocal()); GV->setConstant(I->isConstant()); } // Similarly, copy over function bodies now... // for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) { Function *F = cast<Function>(ValueMap[I]); if (!I->isDeclaration()) { Function::arg_iterator DestI = F->arg_begin(); for (Function::const_arg_iterator J = I->arg_begin(); J != I->arg_end(); ++J) { DestI->setName(J->getName()); ValueMap[J] = DestI++; } std::vector<ReturnInst*> Returns; // Ignore returns cloned... CloneFunctionInto(F, I, ValueMap, Returns); } F->setLinkage(I->getLinkage()); } // And aliases for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end(); I != E; ++I) { GlobalAlias *GA = cast<GlobalAlias>(ValueMap[I]); GA->setLinkage(I->getLinkage()); if (const Constant* C = I->getAliasee()) GA->setAliasee(cast<Constant>(MapValue(C, ValueMap))); } return New; }
bool AArch64PromoteConstant::insertDefinitions( Constant *Cst, InsertionPointsPerFunc &InsPtsPerFunc) { // We will create one global variable per Module. DenseMap<Module *, GlobalVariable *> ModuleToMergedGV; bool HasChanged = false; // Traverse all insertion points in all the function. for (InsertionPointsPerFunc::iterator FctToInstPtsIt = InsPtsPerFunc.begin(), EndIt = InsPtsPerFunc.end(); FctToInstPtsIt != EndIt; ++FctToInstPtsIt) { InsertionPoints &InsertPts = FctToInstPtsIt->second; // Do more checking for debug purposes. #ifndef NDEBUG DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>( *FctToInstPtsIt->first).getDomTree(); #endif GlobalVariable *PromotedGV; assert(!InsertPts.empty() && "Empty uses does not need a definition"); Module *M = FctToInstPtsIt->first->getParent(); DenseMap<Module *, GlobalVariable *>::iterator MapIt = ModuleToMergedGV.find(M); if (MapIt == ModuleToMergedGV.end()) { PromotedGV = new GlobalVariable( *M, Cst->getType(), true, GlobalValue::InternalLinkage, nullptr, "_PromotedConst", nullptr, GlobalVariable::NotThreadLocal); PromotedGV->setInitializer(Cst); ModuleToMergedGV[M] = PromotedGV; DEBUG(dbgs() << "Global replacement: "); DEBUG(PromotedGV->print(dbgs())); DEBUG(dbgs() << '\n'); ++NumPromoted; HasChanged = true; } else { PromotedGV = MapIt->second; } for (InsertionPoints::iterator IPI = InsertPts.begin(), EndIPI = InsertPts.end(); IPI != EndIPI; ++IPI) { // Create the load of the global variable. IRBuilder<> Builder(IPI->first->getParent(), IPI->first); LoadInst *LoadedCst = Builder.CreateLoad(PromotedGV); DEBUG(dbgs() << "**********\n"); DEBUG(dbgs() << "New def: "); DEBUG(LoadedCst->print(dbgs())); DEBUG(dbgs() << '\n'); // Update the dominated uses. Users &DominatedUsers = IPI->second; for (Value::user_iterator Use : DominatedUsers) { #ifndef NDEBUG assert((DT.dominates(LoadedCst, cast<Instruction>(*Use)) || (isa<PHINode>(*Use) && DT.dominates(LoadedCst, findInsertionPoint(Use)))) && "Inserted definition does not dominate all its uses!"); #endif DEBUG(dbgs() << "Use to update " << Use.getOperandNo() << ":"); DEBUG(Use->print(dbgs())); DEBUG(dbgs() << '\n'); Use->setOperand(Use.getOperandNo(), LoadedCst); ++NumPromotedUses; } } } return HasChanged; }
/// Update the initializers in the Dest module now that all globals that may be /// referenced are in Dest. void IRLinker::linkGlobalInit(GlobalVariable &Dst, GlobalVariable &Src) { // Figure out what the initializer looks like in the dest module. Dst.setInitializer(MapValue(Src.getInitializer(), ValueMap, RF_MoveDistinctMDs, &TypeMap, &GValMaterializer)); }
void llvm::copyGVInitializer(GlobalVariable &New, const GlobalVariable &Orig, ValueToValueMapTy &VMap) { if (Orig.hasInitializer()) New.setInitializer(MapValue(Orig.getInitializer(), VMap)); }
bool OptimalEdgeProfiler::runOnModule(Module &M) { Function *Main = M.getFunction("main"); if (Main == 0) { errs() << "WARNING: cannot insert edge profiling into a module" << " with no main function!\n"; return false; // No main, no instrumentation! } // NumEdges counts all the edges that may be instrumented. Later on its // decided which edges to actually instrument, to achieve optimal profiling. // For the entry block a virtual edge (0,entry) is reserved, for each block // with no successors an edge (BB,0) is reserved. These edges are necessary // to calculate a truly optimal maximum spanning tree and thus an optimal // instrumentation. unsigned NumEdges = 0; for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { if (F->isDeclaration()) continue; // Reserve space for (0,entry) edge. ++NumEdges; for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { // Keep track of which blocks need to be instrumented. We don't want to // instrument blocks that are added as the result of breaking critical // edges! if (BB->getTerminator()->getNumSuccessors() == 0) { // Reserve space for (BB,0) edge. ++NumEdges; } else { NumEdges += BB->getTerminator()->getNumSuccessors(); } } } // In the profiling output a counter for each edge is reserved, but only few // are used. This is done to be able to read back in the profile without // calulating the maximum spanning tree again, instead each edge counter that // is not used is initialised with -1 to signal that this edge counter has to // be calculated from other edge counters on reading the profile info back // in. const Type *Int32 = Type::getInt32Ty(M.getContext()); const ArrayType *ATy = ArrayType::get(Int32, NumEdges); GlobalVariable *Counters = new GlobalVariable(M, ATy, false, GlobalValue::InternalLinkage, Constant::getNullValue(ATy), "OptEdgeProfCounters"); NumEdgesInserted = 0; std::vector<Constant*> Initializer(NumEdges); Constant* Zero = ConstantInt::get(Int32, 0); Constant* Uncounted = ConstantInt::get(Int32, ProfileInfoLoader::Uncounted); // Instrument all of the edges not in MST... unsigned i = 0; for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { if (F->isDeclaration()) continue; DEBUG(dbgs()<<"Working on "<<F->getNameStr()<<"\n"); // Calculate a Maximum Spanning Tree with the edge weights determined by // ProfileEstimator. ProfileEstimator also assign weights to the virtual // edges (0,entry) and (BB,0) (for blocks with no successors) and this // edges also participate in the maximum spanning tree calculation. // The third parameter of MaximumSpanningTree() has the effect that not the // actual MST is returned but the edges _not_ in the MST. ProfileInfo::EdgeWeights ECs = getAnalysis<ProfileInfo>(*F).getEdgeWeights(F); std::vector<ProfileInfo::EdgeWeight> EdgeVector(ECs.begin(), ECs.end()); MaximumSpanningTree<BasicBlock> MST (EdgeVector); std::stable_sort(MST.begin(),MST.end()); // Check if (0,entry) not in the MST. If not, instrument edge // (IncrementCounterInBlock()) and set the counter initially to zero, if // the edge is in the MST the counter is initialised to -1. BasicBlock *entry = &(F->getEntryBlock()); ProfileInfo::Edge edge = ProfileInfo::getEdge(0,entry); if (!std::binary_search(MST.begin(), MST.end(), edge)) { printEdgeCounter(edge,entry,i); IncrementCounterInBlock(entry, i, Counters); ++NumEdgesInserted; Initializer[i++] = (Zero); } else{ Initializer[i++] = (Uncounted); } // InsertedBlocks contains all blocks that were inserted for splitting an // edge, this blocks do not have to be instrumented. DenseSet<BasicBlock*> InsertedBlocks; for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { // Check if block was not inserted and thus does not have to be // instrumented. if (InsertedBlocks.count(BB)) continue; // Okay, we have to add a counter of each outgoing edge not in MST. If // the outgoing edge is not critical don't split it, just insert the // counter in the source or destination of the edge. Also, if the block // has no successors, the virtual edge (BB,0) is processed. TerminatorInst *TI = BB->getTerminator(); if (TI->getNumSuccessors() == 0) { ProfileInfo::Edge edge = ProfileInfo::getEdge(BB,0); if (!std::binary_search(MST.begin(), MST.end(), edge)) { printEdgeCounter(edge,BB,i); IncrementCounterInBlock(BB, i, Counters); ++NumEdgesInserted; Initializer[i++] = (Zero); } else{ Initializer[i++] = (Uncounted); } } for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) { BasicBlock *Succ = TI->getSuccessor(s); ProfileInfo::Edge edge = ProfileInfo::getEdge(BB,Succ); if (!std::binary_search(MST.begin(), MST.end(), edge)) { // If the edge is critical, split it. bool wasInserted = SplitCriticalEdge(TI, s, this); Succ = TI->getSuccessor(s); if (wasInserted) InsertedBlocks.insert(Succ); // Okay, we are guaranteed that the edge is no longer critical. If // we only have a single successor, insert the counter in this block, // otherwise insert it in the successor block. if (TI->getNumSuccessors() == 1) { // Insert counter at the start of the block printEdgeCounter(edge,BB,i); IncrementCounterInBlock(BB, i, Counters); ++NumEdgesInserted; } else { // Insert counter at the start of the block printEdgeCounter(edge,Succ,i); IncrementCounterInBlock(Succ, i, Counters); ++NumEdgesInserted; } Initializer[i++] = (Zero); } else { Initializer[i++] = (Uncounted); } } } } // Check if the number of edges counted at first was the number of edges we // considered for instrumentation. assert(i==NumEdges && "the number of edges in counting array is wrong"); // Assing the now completely defined initialiser to the array. Constant *init = ConstantArray::get(ATy, Initializer); Counters->setInitializer(init); // Add the initialization call to main. InsertProfilingInitCall(Main, "llvm_start_opt_edge_profiling", Counters); return true; }
/// If there were any appending global variables, link them together now. /// Return true on error. Constant *IRLinker::linkAppendingVarProto(GlobalVariable *DstGV, const GlobalVariable *SrcGV) { Type *EltTy = cast<ArrayType>(TypeMap.get(SrcGV->getType()->getElementType())) ->getElementType(); StringRef Name = SrcGV->getName(); bool IsNewStructor = false; bool IsOldStructor = false; if (Name == "llvm.global_ctors" || Name == "llvm.global_dtors") { if (cast<StructType>(EltTy)->getNumElements() == 3) IsNewStructor = true; else IsOldStructor = true; } PointerType *VoidPtrTy = Type::getInt8Ty(SrcGV->getContext())->getPointerTo(); if (IsOldStructor) { auto &ST = *cast<StructType>(EltTy); Type *Tys[3] = {ST.getElementType(0), ST.getElementType(1), VoidPtrTy}; EltTy = StructType::get(SrcGV->getContext(), Tys, false); } if (DstGV) { ArrayType *DstTy = cast<ArrayType>(DstGV->getType()->getElementType()); if (!SrcGV->hasAppendingLinkage() || !DstGV->hasAppendingLinkage()) { emitError( "Linking globals named '" + SrcGV->getName() + "': can only link appending global with another appending global!"); return nullptr; } // Check to see that they two arrays agree on type. if (EltTy != DstTy->getElementType()) { emitError("Appending variables with different element types!"); return nullptr; } if (DstGV->isConstant() != SrcGV->isConstant()) { emitError("Appending variables linked with different const'ness!"); return nullptr; } if (DstGV->getAlignment() != SrcGV->getAlignment()) { emitError( "Appending variables with different alignment need to be linked!"); return nullptr; } if (DstGV->getVisibility() != SrcGV->getVisibility()) { emitError( "Appending variables with different visibility need to be linked!"); return nullptr; } if (DstGV->hasUnnamedAddr() != SrcGV->hasUnnamedAddr()) { emitError( "Appending variables with different unnamed_addr need to be linked!"); return nullptr; } if (StringRef(DstGV->getSection()) != SrcGV->getSection()) { emitError( "Appending variables with different section name need to be linked!"); return nullptr; } } SmallVector<Constant *, 16> DstElements; if (DstGV) getArrayElements(DstGV->getInitializer(), DstElements); SmallVector<Constant *, 16> SrcElements; getArrayElements(SrcGV->getInitializer(), SrcElements); if (IsNewStructor) SrcElements.erase( std::remove_if(SrcElements.begin(), SrcElements.end(), [this](Constant *E) { auto *Key = dyn_cast<GlobalValue>( E->getAggregateElement(2)->stripPointerCasts()); if (!Key) return false; GlobalValue *DGV = getLinkedToGlobal(Key); return !shouldLink(DGV, *Key); }), SrcElements.end()); uint64_t NewSize = DstElements.size() + SrcElements.size(); ArrayType *NewType = ArrayType::get(EltTy, NewSize); // Create the new global variable. GlobalVariable *NG = new GlobalVariable( DstM, NewType, SrcGV->isConstant(), SrcGV->getLinkage(), /*init*/ nullptr, /*name*/ "", DstGV, SrcGV->getThreadLocalMode(), SrcGV->getType()->getAddressSpace()); NG->copyAttributesFrom(SrcGV); forceRenaming(NG, SrcGV->getName()); Constant *Ret = ConstantExpr::getBitCast(NG, TypeMap.get(SrcGV->getType())); // Stop recursion. ValueMap[SrcGV] = Ret; for (auto *V : SrcElements) { Constant *NewV; if (IsOldStructor) { auto *S = cast<ConstantStruct>(V); auto *E1 = MapValue(S->getOperand(0), ValueMap, RF_MoveDistinctMDs, &TypeMap, &GValMaterializer); auto *E2 = MapValue(S->getOperand(1), ValueMap, RF_MoveDistinctMDs, &TypeMap, &GValMaterializer); Value *Null = Constant::getNullValue(VoidPtrTy); NewV = ConstantStruct::get(cast<StructType>(EltTy), E1, E2, Null, nullptr); } else { NewV = MapValue(V, ValueMap, RF_MoveDistinctMDs, &TypeMap, &GValMaterializer); } DstElements.push_back(NewV); } NG->setInitializer(ConstantArray::get(NewType, DstElements)); // Replace any uses of the two global variables with uses of the new // global. if (DstGV) { DstGV->replaceAllUsesWith(ConstantExpr::getBitCast(NG, DstGV->getType())); DstGV->eraseFromParent(); } return Ret; }