/// CreateGlobalString - Make a new global variable with an initializer that /// has array of i8 type filled in with the nul terminated string value /// specified. If Name is specified, it is the name of the global variable /// created. Value *IRBuilderBase::CreateGlobalString(const char *Str, const Twine &Name) { Constant *StrConstant = ConstantArray::get(Context, Str, true); Module &M = *BB->getParent()->getParent(); GlobalVariable *GV = new GlobalVariable(M, StrConstant->getType(), true, GlobalValue::InternalLinkage, StrConstant, "", 0, false); GV->setName(Name); return GV; }
/// CreateGlobalString - Make a new global variable with an initializer that /// has array of i8 type filled in with the nul terminated string value /// specified. If Name is specified, it is the name of the global variable /// created. Value *IRBuilderBase::CreateGlobalString(StringRef Str, const Twine &Name) { Constant *StrConstant = ConstantDataArray::getString(Context, Str); Module &M = *BB->getParent()->getParent(); GlobalVariable *GV = new GlobalVariable(M, StrConstant->getType(), true, GlobalValue::PrivateLinkage, StrConstant); GV->setName(Name); GV->setUnnamedAddr(true); return GV; }
static void defineFuncArray(Module &M, const char *LlvmArrayName, const char *StartSymbol, const char *EndSymbol) { std::vector<Constant*> Funcs; GlobalVariable *Array = M.getNamedGlobal(LlvmArrayName); if (Array) { readFuncList(Array, &Funcs); // No code should be referencing global_ctors/global_dtors, // because this symbol is internal to LLVM. Array->eraseFromParent(); } Type *FuncTy = FunctionType::get(Type::getVoidTy(M.getContext()), false); Type *FuncPtrTy = FuncTy->getPointerTo(); ArrayType *ArrayTy = ArrayType::get(FuncPtrTy, Funcs.size()); GlobalVariable *NewArray = new GlobalVariable(M, ArrayTy, /* isConstant= */ true, GlobalValue::InternalLinkage, ConstantArray::get(ArrayTy, Funcs)); setGlobalVariableValue(M, StartSymbol, NewArray); // We do this last so that LLVM gives NewArray the name // "__{init,fini}_array_start" without adding any suffixes to // disambiguate from the original GlobalVariable's name. This is // not essential -- it just makes the output easier to understand // when looking at symbols for debugging. NewArray->setName(StartSymbol); // We replace "__{init,fini}_array_end" with the address of the end // of NewArray. This removes the name "__{init,fini}_array_end" // from the output, which is not ideal for debugging. Ideally we // would convert "__{init,fini}_array_end" to being a GlobalAlias // that points to the end of the array. However, unfortunately LLVM // does not generate correct code when a GlobalAlias contains a // GetElementPtr ConstantExpr. Constant *NewArrayEnd = ConstantExpr::getGetElementPtr(ArrayTy, NewArray, ConstantInt::get(M.getContext(), APInt(32, 1))); setGlobalVariableValue(M, EndSymbol, NewArrayEnd); }
bool GenericToNVVM::runOnModule(Module &M) { // Create a clone of each global variable that has the default address space. // The clone is created with the global address space specifier, and the pair // of original global variable and its clone is placed in the GVMap for later // use. for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E;) { GlobalVariable *GV = &*I++; if (GV->getType()->getAddressSpace() == llvm::ADDRESS_SPACE_GENERIC && !llvm::isTexture(*GV) && !llvm::isSurface(*GV) && !llvm::isSampler(*GV) && !GV->getName().startswith("llvm.")) { GlobalVariable *NewGV = new GlobalVariable( M, GV->getValueType(), GV->isConstant(), GV->getLinkage(), GV->hasInitializer() ? GV->getInitializer() : nullptr, "", GV, GV->getThreadLocalMode(), llvm::ADDRESS_SPACE_GLOBAL); NewGV->copyAttributesFrom(GV); GVMap[GV] = NewGV; } } // Return immediately, if every global variable has a specific address space // specifier. if (GVMap.empty()) { return false; } // Walk through the instructions in function defitinions, and replace any use // of original global variables in GVMap with a use of the corresponding // copies in GVMap. If necessary, promote constants to instructions. for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { if (I->isDeclaration()) { continue; } IRBuilder<> Builder(I->getEntryBlock().getFirstNonPHIOrDbg()); for (Function::iterator BBI = I->begin(), BBE = I->end(); BBI != BBE; ++BBI) { for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE; ++II) { for (unsigned i = 0, e = II->getNumOperands(); i < e; ++i) { Value *Operand = II->getOperand(i); if (isa<Constant>(Operand)) { II->setOperand( i, remapConstant(&M, &*I, cast<Constant>(Operand), Builder)); } } } } ConstantToValueMap.clear(); } // Copy GVMap over to a standard value map. ValueToValueMapTy VM; for (auto I = GVMap.begin(), E = GVMap.end(); I != E; ++I) VM[I->first] = I->second; // Walk through the metadata section and update the debug information // associated with the global variables in the default address space. for (NamedMDNode &I : M.named_metadata()) { remapNamedMDNode(VM, &I); } // Walk through the global variable initializers, and replace any use of // original global variables in GVMap with a use of the corresponding copies // in GVMap. The copies need to be bitcast to the original global variable // types, as we cannot use cvta in global variable initializers. for (GVMapTy::iterator I = GVMap.begin(), E = GVMap.end(); I != E;) { GlobalVariable *GV = I->first; GlobalVariable *NewGV = I->second; // Remove GV from the map so that it can be RAUWed. Note that // DenseMap::erase() won't invalidate any iterators but this one. auto Next = std::next(I); GVMap.erase(I); I = Next; Constant *BitCastNewGV = ConstantExpr::getPointerCast(NewGV, GV->getType()); // At this point, the remaining uses of GV should be found only in global // variable initializers, as other uses have been already been removed // while walking through the instructions in function definitions. GV->replaceAllUsesWith(BitCastNewGV); std::string Name = GV->getName(); GV->eraseFromParent(); NewGV->setName(Name); } assert(GVMap.empty() && "Expected it to be empty by now"); return true; }
void MetadataTransform(CallSite &CS, const TargetData *TD) { Instruction *I = CS.getInstruction(); Module *M = I->getParent()->getParent()->getParent(); LLVMContext &Ctx = I->getContext(); unsigned argIdx = 0; if (CS.arg_size() < 2) report_fatal_error(I, "_SYS_lti_metadata requires at least two args"); // Parse the 'key' parameter ConstantInt *CI = dyn_cast<ConstantInt>(CS.getArgument(argIdx++)); if (!CI) report_fatal_error(I, "Metadata key must be a constant integer."); uint16_t key = CI->getZExtValue(); if (key != CI->getZExtValue()) report_fatal_error(I, "Metadata key argument is too large."); // Parse the 'fmt' parameter std::string fmt; if (!GetConstantStringInfo(CS.getArgument(argIdx++), fmt)) report_fatal_error(I, "Metadata format must be a constant string."); if (fmt.size() != CS.arg_size() - 2) report_fatal_error(I, "Length of metadata format must match number of parameters"); if (fmt.size() == 0) report_fatal_error(I, "Empty metadata values are not supported"); /* * Parse every other parameter according to the format string */ SmallVector<Constant*, 8> Members; unsigned align = 1; for (std::string::iterator FI = fmt.begin(), FE = fmt.end(); FI != FE; ++FI, argIdx++) { Constant *Arg = dyn_cast<Constant>(CS.getArgument(argIdx)); Constant *C; if (!Arg) report_fatal_error(I, "Metadata argument " + Twine(argIdx+1) + " is not constant"); /* * First, non-integer types */ switch (*FI) { case 's': { std::string str; if (!GetConstantStringInfo(Arg, str)) report_fatal_error(I, "Metadata formatter 's' requires a constant string"); Members.push_back(ConstantArray::get(Ctx, str, false)); continue; } } /* * Integer types */ if (Arg->getType()->isPointerTy()) Arg = ConstantExpr::getPointerCast(Arg, Type::getInt32Ty(Ctx)); if (!Arg->getType()->isIntegerTy()) report_fatal_error(I, "Metadata argument " + Twine(argIdx+1) + " can't be converted to an integer type."); switch (*FI) { case 'b': C = ConstantExpr::getIntegerCast(Arg, Type::getInt8Ty(Ctx), true); break; case 'B': C = ConstantExpr::getIntegerCast(Arg, Type::getInt8Ty(Ctx), false); break; case 'h': C = ConstantExpr::getIntegerCast(Arg, Type::getInt16Ty(Ctx), true); break; case 'H': C = ConstantExpr::getIntegerCast(Arg, Type::getInt16Ty(Ctx), false); break; case 'i': C = ConstantExpr::getIntegerCast(Arg, Type::getInt32Ty(Ctx), true); break; case 'I': C = ConstantExpr::getIntegerCast(Arg, Type::getInt32Ty(Ctx), false); break; default: report_fatal_error(I, "Unsupported format character '" + Twine(*FI) + "' in metadata"); } align = std::max(align, TD->getABITypeAlignment(C->getType())); Members.push_back(C); } Constant *Struct = ConstantStruct::getAnon(Members); /* * Install this metadata item as a global variable in a special section */ GlobalVariable *GV = new GlobalVariable(*M, Struct->getType(), true, GlobalValue::ExternalLinkage, Struct, "", 0, false); GV->setAlignment(align); GV->setName(SVMDecorations::META + Twine(key) + SVMDecorations::SEPARATOR); GV->setSection(".metadata"); // Remove the original _SYS_lti_metadata() call I->eraseFromParent(); }
static PointerType *buildTlsTemplate(Module &M, std::vector<VarInfo> *TlsVars) { std::vector<Type*> FieldBssTypes; std::vector<Type*> FieldInitTypes; std::vector<Constant*> FieldInitValues; PassState State(&M); for (Module::global_iterator GV = M.global_begin(); GV != M.global_end(); ++GV) { if (GV->isThreadLocal()) { if (!GV->hasInitializer()) { // Since this is a whole-program transformation, "extern" TLS // variables are not allowed at this point. report_fatal_error(std::string("TLS variable without an initializer: ") + GV->getName()); } if (!GV->getInitializer()->isNullValue()) { addVarToTlsTemplate(&State, &FieldInitTypes, &FieldInitValues, GV); VarInfo Info; Info.TlsVar = GV; Info.IsBss = false; Info.TemplateIndex = FieldInitTypes.size() - 1; TlsVars->push_back(Info); } } } // Handle zero-initialized TLS variables in a second pass, because // these should follow non-zero-initialized TLS variables. for (Module::global_iterator GV = M.global_begin(); GV != M.global_end(); ++GV) { if (GV->isThreadLocal() && GV->getInitializer()->isNullValue()) { addVarToTlsTemplate(&State, &FieldBssTypes, NULL, GV); VarInfo Info; Info.TlsVar = GV; Info.IsBss = true; Info.TemplateIndex = FieldBssTypes.size() - 1; TlsVars->push_back(Info); } } // Add final alignment padding so that // (struct tls_struct *) __nacl_read_tp() - 1 // gives the correct, aligned start of the TLS variables given the // x86-style layout we are using. This requires some more bytes to // be memset() to zero at runtime. This wastage doesn't seem // important gives that we're not trying to optimize packing by // reordering to put similarly-aligned variables together. padToAlignment(&State, &FieldBssTypes, NULL, State.Alignment); // We create the TLS template structs as "packed" because we insert // alignment padding ourselves, and LLVM's implicit insertion of // padding would interfere with ours. tls_bss_template can start at // a non-aligned address immediately following the last field in // tls_init_template. StructType *InitTemplateType = StructType::create(M.getContext(), "tls_init_template"); InitTemplateType->setBody(FieldInitTypes, /*isPacked=*/true); StructType *BssTemplateType = StructType::create(M.getContext(), "tls_bss_template"); BssTemplateType->setBody(FieldBssTypes, /*isPacked=*/true); StructType *TemplateType = StructType::create(M.getContext(), "tls_struct"); SmallVector<Type*, 2> TemplateTopFields; TemplateTopFields.push_back(InitTemplateType); TemplateTopFields.push_back(BssTemplateType); TemplateType->setBody(TemplateTopFields, /*isPacked=*/true); PointerType *TemplatePtrType = PointerType::get(TemplateType, 0); // We define the following symbols, which are the same as those // defined by NaCl's original customized binutils linker scripts: // __tls_template_start // __tls_template_tdata_end // __tls_template_end // We also define __tls_template_alignment, which was not defined by // the original linker scripts. const char *StartSymbol = "__tls_template_start"; Constant *TemplateData = ConstantStruct::get(InitTemplateType, FieldInitValues); GlobalVariable *TemplateDataVar = new GlobalVariable(M, InitTemplateType, /*isConstant=*/true, GlobalValue::InternalLinkage, TemplateData); setGlobalVariableValue(M, StartSymbol, TemplateDataVar); TemplateDataVar->setName(StartSymbol); Constant *TdataEnd = ConstantExpr::getGetElementPtr( TemplateDataVar, ConstantInt::get(M.getContext(), APInt(32, 1))); setGlobalVariableValue(M, "__tls_template_tdata_end", TdataEnd); Constant *TotalEnd = ConstantExpr::getGetElementPtr( ConstantExpr::getBitCast(TemplateDataVar, TemplatePtrType), ConstantInt::get(M.getContext(), APInt(32, 1))); setGlobalVariableValue(M, "__tls_template_end", TotalEnd); const char *AlignmentSymbol = "__tls_template_alignment"; Type *i32 = Type::getInt32Ty(M.getContext()); GlobalVariable *AlignmentVar = new GlobalVariable( M, i32, /*isConstant=*/true, GlobalValue::InternalLinkage, ConstantInt::get(M.getContext(), APInt(32, State.Alignment))); setGlobalVariableValue(M, AlignmentSymbol, AlignmentVar); AlignmentVar->setName(AlignmentSymbol); return TemplatePtrType; }