void LTOCodeGenerator::applyScopeRestrictions() { if (ScopeRestrictionsDone) return; Module *mergedModule = Linker.getModule(); // Start off with a verification pass. PassManager passes; passes.add(createVerifierPass()); // mark which symbols can not be internalized Mangler Mangler(TargetMach); std::vector<const char*> MustPreserveList; SmallPtrSet<GlobalValue*, 8> AsmUsed; std::vector<StringRef> Libcalls; TargetLibraryInfo TLI(Triple(TargetMach->getTargetTriple())); accumulateAndSortLibcalls(Libcalls, TLI, TargetMach->getTargetLowering()); for (Module::iterator f = mergedModule->begin(), e = mergedModule->end(); f != e; ++f) applyRestriction(*f, Libcalls, MustPreserveList, AsmUsed, Mangler); for (Module::global_iterator v = mergedModule->global_begin(), e = mergedModule->global_end(); v != e; ++v) applyRestriction(*v, Libcalls, MustPreserveList, AsmUsed, Mangler); for (Module::alias_iterator a = mergedModule->alias_begin(), e = mergedModule->alias_end(); a != e; ++a) applyRestriction(*a, Libcalls, MustPreserveList, AsmUsed, Mangler); GlobalVariable *LLVMCompilerUsed = mergedModule->getGlobalVariable("llvm.compiler.used"); findUsedValues(LLVMCompilerUsed, AsmUsed); if (LLVMCompilerUsed) LLVMCompilerUsed->eraseFromParent(); if (!AsmUsed.empty()) { llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(Context); std::vector<Constant*> asmUsed2; for (SmallPtrSet<GlobalValue*, 16>::const_iterator i = AsmUsed.begin(), e = AsmUsed.end(); i !=e; ++i) { GlobalValue *GV = *i; Constant *c = ConstantExpr::getBitCast(GV, i8PTy); asmUsed2.push_back(c); } llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, asmUsed2.size()); LLVMCompilerUsed = new llvm::GlobalVariable(*mergedModule, ATy, false, llvm::GlobalValue::AppendingLinkage, llvm::ConstantArray::get(ATy, asmUsed2), "llvm.compiler.used"); LLVMCompilerUsed->setSection("llvm.metadata"); } passes.add(createInternalizePass(MustPreserveList)); // apply scope restrictions passes.run(*mergedModule); ScopeRestrictionsDone = true; }
void InstrProfiling::lowerCoverageData(GlobalVariable *CoverageData) { CoverageData->setSection(getCoverageSection()); CoverageData->setAlignment(8); Constant *Init = CoverageData->getInitializer(); // We're expecting { i32, i32, i32, i32, [n x { i8*, i32, i32 }], [m x i8] } // for some C. If not, the frontend's given us something broken. assert(Init->getNumOperands() == 6 && "bad number of fields in coverage map"); assert(isa<ConstantArray>(Init->getAggregateElement(4)) && "invalid function list in coverage map"); ConstantArray *Records = cast<ConstantArray>(Init->getAggregateElement(4)); for (unsigned I = 0, E = Records->getNumOperands(); I < E; ++I) { Constant *Record = Records->getOperand(I); Value *V = const_cast<Value *>(Record->getOperand(0))->stripPointerCasts(); assert(isa<GlobalVariable>(V) && "Missing reference to function name"); GlobalVariable *Name = cast<GlobalVariable>(V); // If we have region counters for this name, we've already handled it. auto It = RegionCounters.find(Name); if (It != RegionCounters.end()) continue; // Move the name variable to the right section. Name->setSection(getNameSection()); Name->setAlignment(1); } }
void InstrProfiling::emitUses() { if (UsedVars.empty()) return; GlobalVariable *LLVMUsed = M->getGlobalVariable("llvm.used"); std::vector<Constant *> MergedVars; if (LLVMUsed) { // Collect the existing members of llvm.used. ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer()); for (unsigned I = 0, E = Inits->getNumOperands(); I != E; ++I) MergedVars.push_back(Inits->getOperand(I)); LLVMUsed->eraseFromParent(); } Type *i8PTy = Type::getInt8PtrTy(M->getContext()); // Add uses for our data. for (auto *Value : UsedVars) MergedVars.push_back( ConstantExpr::getBitCast(cast<Constant>(Value), i8PTy)); // Recreate llvm.used. ArrayType *ATy = ArrayType::get(i8PTy, MergedVars.size()); LLVMUsed = new GlobalVariable(*M, ATy, false, GlobalValue::AppendingLinkage, ConstantArray::get(ATy, MergedVars), "llvm.used"); LLVMUsed->setSection("llvm.metadata"); }
void LTOCodeGenerator::applyScopeRestrictions() { if (_scopeRestrictionsDone) return; Module *mergedModule = _linker.getModule(); // Start off with a verification pass. PassManager passes; passes.add(createVerifierPass()); // mark which symbols can not be internalized MCContext Context(*_target->getMCAsmInfo(), *_target->getRegisterInfo(),NULL); Mangler mangler(Context, *_target->getTargetData()); std::vector<const char*> mustPreserveList; SmallPtrSet<GlobalValue*, 8> asmUsed; for (Module::iterator f = mergedModule->begin(), e = mergedModule->end(); f != e; ++f) applyRestriction(*f, mustPreserveList, asmUsed, mangler); for (Module::global_iterator v = mergedModule->global_begin(), e = mergedModule->global_end(); v != e; ++v) applyRestriction(*v, mustPreserveList, asmUsed, mangler); for (Module::alias_iterator a = mergedModule->alias_begin(), e = mergedModule->alias_end(); a != e; ++a) applyRestriction(*a, mustPreserveList, asmUsed, mangler); GlobalVariable *LLVMCompilerUsed = mergedModule->getGlobalVariable("llvm.compiler.used"); findUsedValues(LLVMCompilerUsed, asmUsed); if (LLVMCompilerUsed) LLVMCompilerUsed->eraseFromParent(); llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(_context); std::vector<Constant*> asmUsed2; for (SmallPtrSet<GlobalValue*, 16>::const_iterator i = asmUsed.begin(), e = asmUsed.end(); i !=e; ++i) { GlobalValue *GV = *i; Constant *c = ConstantExpr::getBitCast(GV, i8PTy); asmUsed2.push_back(c); } llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, asmUsed2.size()); LLVMCompilerUsed = new llvm::GlobalVariable(*mergedModule, ATy, false, llvm::GlobalValue::AppendingLinkage, llvm::ConstantArray::get(ATy, asmUsed2), "llvm.compiler.used"); LLVMCompilerUsed->setSection("llvm.metadata"); // Add prerequisite passes needed by SAFECode PassManagerBuilder().populateLTOPassManager(passes, /*Internalize=*/ false, !DisableInline); passes.add(createInternalizePass(mustPreserveList)); // apply scope restrictions passes.run(*mergedModule); _scopeRestrictionsDone = true; }
void LTOCodeGenerator::applyScopeRestrictions() { if (ScopeRestrictionsDone || !ShouldInternalize) return; // Start off with a verification pass. legacy::PassManager passes; passes.add(createVerifierPass()); // mark which symbols can not be internalized Mangler Mangler; std::vector<const char*> MustPreserveList; SmallPtrSet<GlobalValue*, 8> AsmUsed; std::vector<StringRef> Libcalls; TargetLibraryInfoImpl TLII(Triple(TargetMach->getTargetTriple())); TargetLibraryInfo TLI(TLII); accumulateAndSortLibcalls(Libcalls, TLI, *MergedModule, *TargetMach); for (Function &f : *MergedModule) applyRestriction(f, Libcalls, MustPreserveList, AsmUsed, Mangler); for (GlobalVariable &v : MergedModule->globals()) applyRestriction(v, Libcalls, MustPreserveList, AsmUsed, Mangler); for (GlobalAlias &a : MergedModule->aliases()) applyRestriction(a, Libcalls, MustPreserveList, AsmUsed, Mangler); GlobalVariable *LLVMCompilerUsed = MergedModule->getGlobalVariable("llvm.compiler.used"); findUsedValues(LLVMCompilerUsed, AsmUsed); if (LLVMCompilerUsed) LLVMCompilerUsed->eraseFromParent(); if (!AsmUsed.empty()) { llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(Context); std::vector<Constant*> asmUsed2; for (auto *GV : AsmUsed) { Constant *c = ConstantExpr::getBitCast(GV, i8PTy); asmUsed2.push_back(c); } llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, asmUsed2.size()); LLVMCompilerUsed = new llvm::GlobalVariable(*MergedModule, ATy, false, llvm::GlobalValue::AppendingLinkage, llvm::ConstantArray::get(ATy, asmUsed2), "llvm.compiler.used"); LLVMCompilerUsed->setSection("llvm.metadata"); } passes.add(createInternalizePass(MustPreserveList)); // apply scope restrictions passes.run(*MergedModule); ScopeRestrictionsDone = true; }
bool SancusModuleCreator::handleData(GlobalVariable& gv) { SancusModuleInfo info = getSancusModuleInfo(&gv); if (!info.isInSm) return false; if (gv.hasCommonLinkage()) gv.setLinkage(GlobalValue::WeakAnyLinkage); gv.setSection(info.getDataSection()); return true; }
void SancusModuleCreator::createFunctionTable(Module& m) { LLVMContext& ctx = m.getContext(); // struct SmFunctionInfo // { // void* address; // unsigned arg_length; // unsigned ret_regs; // }; Type* funcInfoFields[] = {voidPtrTy, wordTy, wordTy}; StructType* funcInfoTy = StructType::get(ctx, funcInfoFields, /*isPacked=*/true); // create a global SM function table for every SM and initialize it // initializers for the funcs[] array. // map from section name to initializer std::map<std::string, std::vector<Constant*>> funcsEls; for (Function* f : entries) { SancusModuleInfo info = getSancusModuleInfo(f); assert(info.isEntry && "Asking function table for non-entry"); // initializer for the SmFunctionInfo struct FunctionCcInfo ccInfo(f); Constant* funcFields[] = {ConstantExpr::getBitCast(f, voidPtrTy), ConstantInt::get(wordTy, ccInfo.argsLength), ConstantInt::get(wordTy, ccInfo.retRegsUsage)}; funcsEls[info.getTableSection()] .push_back(ConstantStruct::get(funcInfoTy, funcFields)); } for (const auto& it : funcsEls) { // struct SmFunctionInfo funcs[]; ArrayType* funcsTy = ArrayType::get(funcInfoTy, it.second.size()); Constant* funcsInit = ConstantArray::get(funcsTy, it.second); GlobalVariable* table = new GlobalVariable(m, funcsTy, /*isConstant=*/true, GlobalVariable::InternalLinkage, funcsInit); table->setSection(it.first); table->setAlignment(2); } }
// Convert string to global value. Use existing global if possible. Constant* ConvertMetadataStringToGV(const char *str) { Constant *Init = ConstantArray::get(std::string(str)); // Use cached string if it exists. static std::map<Constant*, GlobalVariable*> StringCSTCache; GlobalVariable *&Slot = StringCSTCache[Init]; if (Slot) return Slot; // Create a new string global. GlobalVariable *GV = new GlobalVariable(Init->getType(), true, GlobalVariable::InternalLinkage, Init, ".str", TheModule); GV->setSection("llvm.metadata"); Slot = GV; return GV; }
GlobalVariable * InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) { GlobalVariable *Name = Inc->getName(); auto It = RegionCounters.find(Name); if (It != RegionCounters.end()) return It->second; // Move the name variable to the right section. Place them in a COMDAT group // if the associated function is a COMDAT. This will make sure that // only one copy of counters of the COMDAT function will be emitted after // linking. Function *Fn = Inc->getParent()->getParent(); Comdat *ProfileVarsComdat = nullptr; if (Fn->hasComdat()) ProfileVarsComdat = M->getOrInsertComdat(StringRef(getVarName(Inc, "vars"))); Name->setSection(getNameSection()); Name->setAlignment(1); Name->setComdat(ProfileVarsComdat); uint64_t NumCounters = Inc->getNumCounters()->getZExtValue(); LLVMContext &Ctx = M->getContext(); ArrayType *CounterTy = ArrayType::get(Type::getInt64Ty(Ctx), NumCounters); // Create the counters variable. auto *Counters = new GlobalVariable(*M, CounterTy, false, Name->getLinkage(), Constant::getNullValue(CounterTy), getVarName(Inc, "counters")); Counters->setVisibility(Name->getVisibility()); Counters->setSection(getCountersSection()); Counters->setAlignment(8); Counters->setComdat(ProfileVarsComdat); RegionCounters[Inc->getName()] = Counters; // Create data variable. auto *NameArrayTy = Name->getType()->getPointerElementType(); auto *Int32Ty = Type::getInt32Ty(Ctx); auto *Int64Ty = Type::getInt64Ty(Ctx); auto *Int8PtrTy = Type::getInt8PtrTy(Ctx); auto *Int64PtrTy = Type::getInt64PtrTy(Ctx); Type *DataTypes[] = {Int32Ty, Int32Ty, Int64Ty, Int8PtrTy, Int64PtrTy}; auto *DataTy = StructType::get(Ctx, makeArrayRef(DataTypes)); Constant *DataVals[] = { ConstantInt::get(Int32Ty, NameArrayTy->getArrayNumElements()), ConstantInt::get(Int32Ty, NumCounters), ConstantInt::get(Int64Ty, Inc->getHash()->getZExtValue()), ConstantExpr::getBitCast(Name, Int8PtrTy), ConstantExpr::getBitCast(Counters, Int64PtrTy)}; auto *Data = new GlobalVariable(*M, DataTy, true, Name->getLinkage(), ConstantStruct::get(DataTy, DataVals), getVarName(Inc, "data")); Data->setVisibility(Name->getVisibility()); Data->setSection(getDataSection()); Data->setAlignment(8); Data->setComdat(ProfileVarsComdat); // Mark the data variable as used so that it isn't stripped out. UsedVars.push_back(Data); return Counters; }
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(); }
GlobalVariable * InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) { GlobalVariable *NamePtr = Inc->getName(); auto It = ProfileDataMap.find(NamePtr); PerFunctionProfileData PD; if (It != ProfileDataMap.end()) { if (It->second.RegionCounters) return It->second.RegionCounters; PD = It->second; } // Move the name variable to the right section. Place them in a COMDAT group // if the associated function is a COMDAT. This will make sure that // only one copy of counters of the COMDAT function will be emitted after // linking. Function *Fn = Inc->getParent()->getParent(); Comdat *ProfileVarsComdat = nullptr; if (Fn->hasComdat()) ProfileVarsComdat = getOrCreateProfileComdat(*M, Inc); NamePtr->setSection(getNameSection()); NamePtr->setAlignment(1); NamePtr->setComdat(ProfileVarsComdat); uint64_t NumCounters = Inc->getNumCounters()->getZExtValue(); LLVMContext &Ctx = M->getContext(); ArrayType *CounterTy = ArrayType::get(Type::getInt64Ty(Ctx), NumCounters); // Create the counters variable. auto *CounterPtr = new GlobalVariable(*M, CounterTy, false, NamePtr->getLinkage(), Constant::getNullValue(CounterTy), getVarName(Inc, getInstrProfCountersVarPrefix())); CounterPtr->setVisibility(NamePtr->getVisibility()); CounterPtr->setSection(getCountersSection()); CounterPtr->setAlignment(8); CounterPtr->setComdat(ProfileVarsComdat); // Create data variable. auto *Int8PtrTy = Type::getInt8PtrTy(Ctx); auto *Int16Ty = Type::getInt16Ty(Ctx); auto *Int16ArrayTy = ArrayType::get(Int16Ty, IPVK_Last+1); Type *DataTypes[] = { #define INSTR_PROF_DATA(Type, LLVMType, Name, Init) LLVMType, #include "llvm/ProfileData/InstrProfData.inc" }; auto *DataTy = StructType::get(Ctx, makeArrayRef(DataTypes)); Constant *FunctionAddr = shouldRecordFunctionAddr(Fn) ? ConstantExpr::getBitCast(Fn, Int8PtrTy) : ConstantPointerNull::get(Int8PtrTy); Constant *Int16ArrayVals[IPVK_Last+1]; for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) Int16ArrayVals[Kind] = ConstantInt::get(Int16Ty, PD.NumValueSites[Kind]); Constant *DataVals[] = { #define INSTR_PROF_DATA(Type, LLVMType, Name, Init) Init, #include "llvm/ProfileData/InstrProfData.inc" }; auto *Data = new GlobalVariable(*M, DataTy, false, NamePtr->getLinkage(), ConstantStruct::get(DataTy, DataVals), getVarName(Inc, getInstrProfDataVarPrefix())); Data->setVisibility(NamePtr->getVisibility()); Data->setSection(getDataSection()); Data->setAlignment(INSTR_PROF_DATA_ALIGNMENT); Data->setComdat(ProfileVarsComdat); PD.RegionCounters = CounterPtr; PD.DataVar = Data; ProfileDataMap[NamePtr] = PD; // Mark the data variable as used so that it isn't stripped out. UsedVars.push_back(Data); return CounterPtr; }
/// 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); }