| /* LLVM LOCAL begin (ENTIRE FILE!) */ |
| /* High-level LLVM backend interface |
| Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc. |
| Contributed by Chris Lattner (sabre@nondot.org) |
| |
| This file is part of GCC. |
| |
| GCC is free software; you can redistribute it and/or modify it under |
| the terms of the GNU General Public License as published by the Free |
| Software Foundation; either version 2, or (at your option) any later |
| version. |
| |
| GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
| WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with GCC; see the file COPYING. If not, write to the Free |
| Software Foundation, 59 Temple Place - Suite 330, Boston, MA |
| 02111-1307, USA. */ |
| |
| #include "llvm-internal.h" |
| #include "llvm-debug.h" |
| #include "llvm-file-ostream.h" |
| #include "llvm/Constants.h" |
| #include "llvm/DerivedTypes.h" |
| #include "llvm/LLVMContext.h" |
| #include "llvm/Module.h" |
| #include "llvm/PassManager.h" |
| #include "llvm/ValueSymbolTable.h" |
| #include "llvm/Analysis/LoopPass.h" |
| #include "llvm/Analysis/Verifier.h" |
| #include "llvm/Assembly/Writer.h" |
| #include "llvm/Assembly/PrintModulePass.h" |
| #include "llvm/Bitcode/ReaderWriter.h" |
| #include "llvm/CodeGen/RegAllocRegistry.h" |
| #include "llvm/MC/MCCodeGenInfo.h" |
| #include "llvm/MC/SubtargetFeature.h" |
| #include "llvm/Target/TargetData.h" |
| #include "llvm/Target/TargetLibraryInfo.h" |
| #include "llvm/Target/TargetLowering.h" |
| #include "llvm/Target/TargetMachine.h" |
| #include "llvm/Target/TargetOptions.h" |
| #include "llvm/Transforms/Scalar.h" |
| #include "llvm/Transforms/IPO.h" |
| #include "llvm/ADT/StringExtras.h" |
| #include "llvm/ADT/StringMap.h" |
| #include "llvm/Support/ManagedStatic.h" |
| #include "llvm/Support/MemoryBuffer.h" |
| #include "llvm/Support/system_error.h" |
| #include "llvm/Transforms/IPO/PassManagerBuilder.h" |
| #include "llvm/Support/FormattedStream.h" |
| #include "llvm/Support/Program.h" |
| #include "llvm/Support/TargetRegistry.h" |
| |
| #include <cassert> |
| extern "C" { |
| #include "config.h" |
| #include "system.h" |
| #include "coretypes.h" |
| #include "tm.h" |
| #include "except.h" |
| #include "flags.h" |
| #include "tree.h" |
| #include "diagnostic.h" |
| #include "output.h" |
| #include "target.h" |
| #include "toplev.h" |
| #include "timevar.h" |
| #include "function.h" |
| #include "tree-inline.h" |
| #include "langhooks.h" |
| #include "cgraph.h" |
| #include "params.h" |
| |
| // These are defined in c-common.c. The weak symbols are for linking non-c |
| // compilers. |
| #ifndef __MINGW32__ |
| int flag_no_builtin __attribute__ ((__weak__)) = 0; |
| int builtin_function_disabled_p(const char *name) __attribute__ ((__weak__)); |
| int builtin_function_disabled_p(const char *name) { return 0; } |
| #endif |
| } |
| |
| // Non-zero if -Oz is set. |
| extern "C" unsigned int optimize_size_z; |
| |
| // Non-zero if bytecode from PCH is successfully read. |
| int flag_llvm_pch_read; |
| |
| // Non-zero if libcalls should not be simplified. |
| int flag_no_simplify_libcalls; |
| |
| // Non-zero if red-zone is disabled. |
| static int flag_disable_red_zone = 0; |
| |
| // Non-zero if implicit floating point instructions are disabled. |
| static int flag_no_implicit_float = 0; |
| |
| // Global state for the LLVM backend. |
| Module *TheModule = 0; |
| DebugInfo *TheDebugInfo = 0; |
| TargetMachine *TheTarget = 0; |
| TargetFolder *TheFolder = 0; |
| TypeConverter *TheTypeConverter = 0; |
| |
| // A list of thunks to post-process. |
| std::vector<tree> Thunks; |
| |
| /// DisableLLVMOptimizations - Allow the user to specify: |
| /// "-mllvm -disable-llvm-optzns" on the llvm-gcc command line to force llvm |
| /// optimizations off. |
| static cl::opt<bool> DisableLLVMOptimizations("disable-llvm-optzns"); |
| |
| static cl::list<std::string> |
| MAttrs("mattr", |
| cl::CommaSeparated, |
| cl::desc("Target specific attributes (-mattr=help for details)"), |
| cl::value_desc("a1,+a2,-a3,...")); |
| |
| std::vector<std::pair<Constant*, int> > StaticCtors, StaticDtors; |
| SmallSetVector<Constant*, 32> AttributeUsedGlobals; |
| SmallSetVector<Constant*, 32> AttributeCompilerUsedGlobals; |
| std::vector<Constant*> AttributeAnnotateGlobals; |
| |
| /// PerFunctionPasses - This is the list of cleanup passes run per-function |
| /// as each is compiled. In cases where we are not doing IPO, it includes the |
| /// code generator. |
| static FunctionPassManager *PerFunctionPasses = 0; |
| static PassManager *PerModulePasses = 0; |
| static FunctionPassManager *CodeGenPasses = 0; |
| |
| static void createPerFunctionOptimizationPasses(); |
| static void createPerModuleOptimizationPasses(); |
| static void destroyOptimizationPasses(); |
| |
| //===----------------------------------------------------------------------===// |
| // Matching LLVM Values with GCC DECL trees |
| //===----------------------------------------------------------------------===// |
| // |
| // LLVMValues is a vector of LLVM Values. GCC tree nodes keep track of LLVM |
| // Values using this vector's index. It is easier to save and restore the index |
| // than the LLVM Value pointer while using PCH. |
| |
| // Collection of LLVM Values |
| static std::vector<Value*> LLVMValues; |
| typedef DenseMap<Value*, unsigned> LLVMValuesMapTy; |
| static LLVMValuesMapTy LLVMValuesMap; |
| |
| /// LocalLLVMValueIDs - This is the set of local IDs we have in our mapping, |
| /// this allows us to efficiently identify and remove them. Local IDs are IDs |
| /// for values that are local to the current function being processed. These do |
| /// not need to go into the PCH file, but DECL_LLVM still needs a valid index |
| /// while converting the function. Using "Local IDs" allows the IDs for |
| /// function-local decls to be recycled after the function is done. |
| static std::vector<unsigned> LocalLLVMValueIDs; |
| |
| /// llvm_set_decl - Remember the LLVM value for GCC tree node. |
| void llvm_set_decl(tree Tr, Value *V) { |
| |
| // If there is not any value then do not add new LLVMValues entry. |
| // However clear Tr index if it is non zero. |
| if (!V) { |
| if (GET_DECL_LLVM_INDEX(Tr)) |
| SET_DECL_LLVM_INDEX(Tr, 0); |
| return; |
| } |
| |
| unsigned &ValueSlot = LLVMValuesMap[V]; |
| if (ValueSlot) { |
| // Already in map |
| SET_DECL_LLVM_INDEX(Tr, ValueSlot); |
| return; |
| } |
| |
| LLVMValues.push_back(V); |
| unsigned Index = LLVMValues.size(); |
| SET_DECL_LLVM_INDEX(Tr, Index); |
| LLVMValuesMap[V] = Index; |
| |
| // Remember local values. |
| if (!isa<Constant>(V)) |
| LocalLLVMValueIDs.push_back(Index); |
| } |
| |
| /// llvm_set_decl_p - Return TRUE if there is a LLVM Value associate with GCC |
| /// tree node. |
| bool llvm_set_decl_p(tree Tr) { |
| unsigned Index = GET_DECL_LLVM_INDEX(Tr); |
| if (Index == 0) |
| return false; |
| |
| return LLVMValues[Index - 1] != 0; |
| } |
| |
| /// llvm_get_decl - Get LLVM Value for the GCC tree node based on LLVMValues |
| /// vector index. If there is not any value associated then use |
| /// make_decl_llvm() to make LLVM value. When GCC tree node is initialized, it |
| /// has 0 as the index value. This is why all recorded indices are offset by 1. |
| Value *llvm_get_decl(tree Tr) { |
| |
| unsigned Index = GET_DECL_LLVM_INDEX(Tr); |
| if (Index == 0) { |
| make_decl_llvm(Tr); |
| Index = GET_DECL_LLVM_INDEX(Tr); |
| |
| // If there was an error, we may have disabled creating LLVM values. |
| if (Index == 0) return 0; |
| } |
| assert((Index - 1) < LLVMValues.size() && "Invalid LLVM value index"); |
| assert(LLVMValues[Index - 1] && "Trying to use deleted LLVM value!"); |
| |
| return LLVMValues[Index - 1]; |
| } |
| |
| /// changeLLVMConstant - Replace Old with New everywhere, updating all maps |
| /// (except for AttributeAnnotateGlobals, which is a different kind of animal). |
| /// At this point we know that New is not in any of these maps. |
| void changeLLVMConstant(Constant *Old, Constant *New) { |
| assert(Old->use_empty() && "Old value has uses!"); |
| |
| if (AttributeUsedGlobals.count(Old)) { |
| AttributeUsedGlobals.remove(Old); |
| AttributeUsedGlobals.insert(New); |
| } |
| |
| if (AttributeCompilerUsedGlobals.count(Old)) { |
| AttributeCompilerUsedGlobals.remove(Old); |
| AttributeCompilerUsedGlobals.insert(New); |
| } |
| |
| for (unsigned i = 0, e = StaticCtors.size(); i != e; ++i) { |
| if (StaticCtors[i].first == Old) |
| StaticCtors[i].first = New; |
| } |
| |
| for (unsigned i = 0, e = StaticDtors.size(); i != e; ++i) { |
| if (StaticDtors[i].first == Old) |
| StaticDtors[i].first = New; |
| } |
| |
| assert(!LLVMValuesMap.count(New) && "New cannot be in the LLVMValues map!"); |
| |
| // Find Old in the table. |
| LLVMValuesMapTy::iterator I = LLVMValuesMap.find(Old); |
| if (I == LLVMValuesMap.end()) return; |
| |
| unsigned Idx = I->second-1; |
| assert(Idx < LLVMValues.size() && "Out of range index!"); |
| assert(LLVMValues[Idx] == Old && "Inconsistent LLVMValues mapping!"); |
| |
| LLVMValues[Idx] = New; |
| |
| // Remove the old value from the value map. |
| LLVMValuesMap.erase(I); |
| |
| // Insert the new value into the value map. We know that it can't already |
| // exist in the mapping. |
| if (New) |
| LLVMValuesMap[New] = Idx+1; |
| } |
| |
| /// readLLVMValues - Read LLVM Types string table |
| void readLLVMValues() { |
| GlobalValue *V = TheModule->getNamedGlobal("llvm.pch.values"); |
| if (!V) |
| return; |
| |
| GlobalVariable *GV = cast<GlobalVariable>(V); |
| ConstantStruct *ValuesFromPCH = cast<ConstantStruct>(GV->getOperand(0)); |
| |
| for (unsigned i = 0; i < ValuesFromPCH->getNumOperands(); ++i) { |
| Value *Va = ValuesFromPCH->getOperand(i); |
| |
| if (!Va) { |
| // If V is empty then insert NULL to represent empty entries. |
| LLVMValues.push_back(Va); |
| continue; |
| } |
| if (ConstantArray *CA = dyn_cast<ConstantArray>(Va)) { |
| std::string Str = CA->getAsString(); |
| Va = TheModule->getValueSymbolTable().lookup(Str); |
| } |
| assert (Va != NULL && "Invalid Value in LLVMValues string table"); |
| LLVMValues.push_back(Va); |
| } |
| |
| // Now, llvm.pch.values is not required so remove it from the symbol table. |
| GV->eraseFromParent(); |
| |
| if (TheDebugInfo) { |
| // Replace compile unit received from the PCH file. |
| NamedMDNode *NMD = TheModule->getOrInsertNamedMetadata("llvm.dbg.pch.cu"); |
| if (NMD->getNumOperands() == 1) { |
| MDNode *HeaderCUNode = NMD->getOperand(0); |
| Value *CUNode = TheDebugInfo->getCU(); |
| HeaderCUNode->replaceAllUsesWith(CUNode); |
| } |
| TheDebugInfo->replaceBasicTypesFromPCH(); |
| } |
| } |
| |
| /// writeLLVMValues - GCC tree's uses LLVMValues vector's index to reach LLVM |
| /// Values. Create a string table to hold these LLVM Values' names. This string |
| /// table will be used to recreate LTypes vector after loading PCH. |
| void writeLLVMValues() { |
| if (LLVMValues.empty()) |
| return; |
| |
| LLVMContext &Context = getGlobalContext(); |
| |
| std::vector<Constant *> ValuesForPCH; |
| for (std::vector<Value *>::iterator I = LLVMValues.begin(), |
| E = LLVMValues.end(); I != E; ++I) { |
| if (Constant *C = dyn_cast_or_null<Constant>(*I)) |
| ValuesForPCH.push_back(C); |
| else |
| // Non constant values, e.g. arguments, are not at global scope. |
| // When PCH is read, only global scope values are used. |
| ValuesForPCH.push_back(Constant::getNullValue(Type::getInt32Ty(Context))); |
| } |
| |
| // Create string table. |
| Constant *LLVMValuesTable = |
| ConstantStruct::getAnon(Context, ValuesForPCH, false); |
| |
| // Create variable to hold this string table. |
| GlobalVariable *GV = new GlobalVariable(*TheModule, LLVMValuesTable->getType(), |
| true, GlobalValue::ExternalLinkage, |
| LLVMValuesTable, |
| "llvm.pch.values"); |
| GV->setUnnamedAddr(true); |
| |
| if (TheDebugInfo && TheDebugInfo->getCU().Verify()) { |
| NamedMDNode *NMD = TheModule->getOrInsertNamedMetadata("llvm.dbg.pch.cu"); |
| NMD->addOperand(TheDebugInfo->getCU()); |
| } |
| } |
| |
| /// eraseLocalLLVMValues - drop all non-global values from the LLVM values map. |
| void eraseLocalLLVMValues() { |
| // Erase all the local values, these are stored in LocalLLVMValueIDs. |
| while (!LocalLLVMValueIDs.empty()) { |
| unsigned Idx = LocalLLVMValueIDs.back()-1; |
| LocalLLVMValueIDs.pop_back(); |
| |
| if (Value *V = LLVMValues[Idx]) { |
| assert(!isa<Constant>(V) && "Found global value"); |
| LLVMValuesMap.erase(V); |
| } |
| |
| if (Idx == LLVMValues.size()-1) |
| LLVMValues.pop_back(); |
| else |
| LLVMValues[Idx] = 0; |
| } |
| } |
| |
| /// handleVisibility - Forward decl visibility style to global. |
| void handleVisibility(tree decl, GlobalValue *GV) { |
| // If decl has visibility specified explicitely (via attribute) - honour |
| // it. Otherwise (e.g. visibility specified via -fvisibility=hidden) honour |
| // only if symbol is local. |
| if (TREE_PUBLIC(decl) && |
| (DECL_VISIBILITY_SPECIFIED(decl) || !DECL_EXTERNAL(decl))) { |
| if (DECL_VISIBILITY(decl) == VISIBILITY_HIDDEN) |
| GV->setVisibility(GlobalValue::HiddenVisibility); |
| else if (DECL_VISIBILITY(decl) == VISIBILITY_PROTECTED) |
| GV->setVisibility(GlobalValue::ProtectedVisibility); |
| else if (DECL_VISIBILITY(decl) == VISIBILITY_DEFAULT) |
| GV->setVisibility(Function::DefaultVisibility); |
| } |
| } |
| |
| #ifndef LLVM_TARGET_NAME |
| #error LLVM_TARGET_NAME macro not specified by GCC backend |
| #endif |
| |
| namespace llvm { |
| #define Declare2(TARG, MOD) extern "C" void LLVMInitialize ## TARG ## MOD() |
| #define Declare(T, M) Declare2(T, M) |
| Declare(LLVM_TARGET_NAME, TargetInfo); |
| Declare(LLVM_TARGET_NAME, Target); |
| Declare(LLVM_TARGET_NAME, TargetMC); |
| Declare(LLVM_TARGET_NAME, AsmPrinter); |
| #undef Declare |
| #undef Declare2 |
| } |
| |
| // GuessAtInliningThreshold - Figure out a reasonable threshold to pass llvm's |
| // inliner. gcc has many options that control inlining, but we have decided |
| // not to support anything like that for llvm-gcc. |
| static unsigned GuessAtInliningThreshold() { |
| if (optimize_size) |
| // Reduce inline limit. |
| return optimize_size_z ? 25 : 75; |
| |
| if (optimize >= 3) |
| return 275; |
| return 225; |
| } |
| |
| void llvm_initialize_backend(void) { |
| // Initialize the LLVM backend. |
| #define DoInit2(TARG, MOD) LLVMInitialize ## TARG ## MOD() |
| #define DoInit(T, M) DoInit2(T, M) |
| DoInit(LLVM_TARGET_NAME, TargetInfo); |
| DoInit(LLVM_TARGET_NAME, Target); |
| DoInit(LLVM_TARGET_NAME, TargetMC); |
| DoInit(LLVM_TARGET_NAME, AsmPrinter); |
| #undef DoInit |
| #undef DoInit2 |
| |
| Reloc::Model RelocModel = Reloc::Default; |
| CodeModel::Model CMModel = CodeModel::Default; |
| CodeGenOpt::Level OptLevel = CodeGenOpt::Default; // -O2, -Os, and -Oz |
| if (optimize == 0) |
| OptLevel = CodeGenOpt::None; |
| else if (optimize == 1) |
| OptLevel = CodeGenOpt::Less; |
| else if (optimize == 3) |
| // -O3 and above. |
| OptLevel = CodeGenOpt::Aggressive; |
| |
| // Initialize LLVM options. |
| std::vector<const char*> Args; |
| Args.push_back(progname); // program name |
| |
| // Allow targets to specify PIC options and other stuff to the corresponding |
| // LLVM backends. |
| #ifdef LLVM_SET_RED_ZONE_FLAG |
| LLVM_SET_RED_ZONE_FLAG(flag_disable_red_zone) |
| #endif |
| #ifdef LLVM_SET_TARGET_OPTIONS |
| LLVM_SET_TARGET_OPTIONS(Args); |
| #endif |
| #ifdef LLVM_SET_MACHINE_OPTIONS |
| LLVM_SET_MACHINE_OPTIONS(Args); |
| #endif |
| #ifdef LLVM_SET_IMPLICIT_FLOAT |
| LLVM_SET_IMPLICIT_FLOAT(flag_no_implicit_float) |
| #endif |
| #ifdef LLVM_SET_RELOC_MODEL |
| LLVM_SET_RELOC_MODEL(RelocModel); |
| #endif |
| #ifdef LLVM_SET_CODE_MODEL |
| LLVM_SET_CODE_MODEL(CMModel); |
| #endif |
| |
| if (time_report) |
| Args.push_back("--time-passes"); |
| if (flag_verbose_asm) |
| Args.push_back("--asm-verbose"); |
| if (flag_debug_pass_structure) |
| Args.push_back("--debug-pass=Structure"); |
| if (flag_debug_pass_arguments) |
| Args.push_back("--debug-pass=Arguments"); |
| if (!flag_schedule_insns) |
| Args.push_back("--pre-RA-sched=source"); |
| if (flag_function_sections) |
| Args.push_back("--ffunction-sections"); |
| if (flag_data_sections) |
| Args.push_back("--fdata-sections"); |
| if (flag_disable_debug_info_print) |
| Args.push_back("--disable-debug-info-print"); |
| |
| // If there are options that should be passed through to the LLVM backend |
| // directly from the command line, do so now. This is mainly for debugging |
| // purposes, and shouldn't really be for general use. |
| std::vector<std::string> ArgStrings; |
| |
| if (flag_inline_trees > 1) { |
| unsigned threshold = GuessAtInliningThreshold(); |
| std::string Arg("--inline-threshold="+utostr(threshold)); |
| ArgStrings.push_back(Arg); |
| } |
| |
| if (flag_limited_precision > 0) { |
| std::string Arg("--limit-float-precision="+utostr(flag_limited_precision)); |
| ArgStrings.push_back(Arg); |
| } |
| |
| if (flag_stack_protect > 0) { |
| std::string Arg("--stack-protector-buffer-size=" + |
| utostr(PARAM_VALUE(PARAM_SSP_BUFFER_SIZE))); |
| ArgStrings.push_back(Arg); |
| } |
| |
| if (flag_trap_funcname_string) { |
| std::string Arg("-trap-func="); |
| Arg += flag_trap_funcname_string; |
| ArgStrings.push_back(Arg); |
| } |
| |
| for (unsigned i = 0, e = ArgStrings.size(); i != e; ++i) |
| Args.push_back(ArgStrings[i].c_str()); |
| |
| std::vector<std::string> LLVM_Optns; // Avoid deallocation before opts parsed! |
| if (llvm_optns) { |
| llvm::SmallVector<llvm::StringRef, 16> Buf; |
| SplitString(llvm_optns, Buf); |
| for(unsigned i = 0, e = Buf.size(); i != e; ++i) { |
| LLVM_Optns.push_back(Buf[i]); |
| Args.push_back(LLVM_Optns.back().c_str()); |
| } |
| } |
| |
| Args.push_back(0); // Null terminator. |
| int pseudo_argc = Args.size()-1; |
| cl::ParseCommandLineOptions(pseudo_argc, (char**)&Args[0]); |
| |
| TheModule = new Module("", getGlobalContext()); |
| |
| // If the target wants to override the architecture, e.g. turning |
| // powerpc-darwin-... into powerpc64-darwin-... when -m64 is enabled, do so |
| // now. |
| std::string TargetTriple = TARGET_CANONICAL_NAME; |
| #ifdef LLVM_OVERRIDE_TARGET_ARCH |
| std::string Arch = LLVM_OVERRIDE_TARGET_ARCH(); |
| if (!Arch.empty()) { |
| std::string::size_type DashPos = TargetTriple.find('-'); |
| if (DashPos != std::string::npos)// If we have a sane t-t, replace the arch. |
| TargetTriple = Arch + TargetTriple.substr(DashPos); |
| } |
| #endif |
| #ifdef LLVM_OVERRIDE_TARGET_VERSION |
| char *NewTriple; |
| bool OverRidden = LLVM_OVERRIDE_TARGET_VERSION(TargetTriple.c_str(), |
| &NewTriple); |
| if (OverRidden) |
| TargetTriple = std::string(NewTriple); |
| #endif |
| TheModule->setTargetTriple(TargetTriple); |
| |
| TheTypeConverter = new TypeConverter(); |
| |
| // Create the TargetMachine we will be generating code with. |
| // FIXME: Figure out how to select the target and pass down subtarget info. |
| std::string Err; |
| const Target *TME = |
| TargetRegistry::lookupTarget(TargetTriple, Err); |
| if (!TME) { |
| errs() << "Did not get a target machine! Triplet is " << TargetTriple<<'\n'; |
| exit(1); |
| } |
| |
| // Figure out the subtarget feature string we pass to the target. |
| std::string FeatureStr; |
| SubtargetFeatures Features; |
| |
| // The target can set LLVM_SET_SUBTARGET_FEATURES to configure the LLVM |
| // backend. |
| std::string CPU; |
| #ifdef LLVM_SET_SUBTARGET_FEATURES |
| LLVM_SET_SUBTARGET_FEATURES(CPU, Features); |
| #endif |
| |
| // Handle -mattr options passed into llvm |
| for (unsigned i = 0; i != MAttrs.size(); ++i) |
| Features.AddFeature(MAttrs[i]); |
| FeatureStr = Features.getString(); |
| |
| TargetOptions Options; |
| #ifdef LLVM_SET_TARGET_MACHINE_OPTIONS |
| LLVM_SET_TARGET_MACHINE_OPTIONS(Options); |
| #endif |
| Options.UnsafeFPMath = fast_math_flags_set_p(); |
| Options.NoInfsFPMath = !flag_honor_infinites; |
| Options.NoNaNsFPMath = !flag_honor_nans; |
| Options.NoFramePointerElim = !flag_omit_frame_pointer; |
| Options.NoZerosInBSS = !flag_zero_initialized_in_bss; |
| TheTarget = TME->createTargetMachine(TargetTriple, CPU, FeatureStr, Options, |
| RelocModel, CMModel, OptLevel); |
| TheTarget->setMCUseLoc(false); |
| TheTarget->setMCUseCFI(false); |
| assert(TheTarget->getTargetData()->isBigEndian() == BYTES_BIG_ENDIAN); |
| |
| TheFolder = new TargetFolder(TheTarget->getTargetData()); |
| |
| // Install information about target datalayout stuff into the module for |
| // optimizer use. |
| TheModule->setDataLayout(TheTarget->getTargetData()-> |
| getStringRepresentation()); |
| |
| if (debug_info_level > DINFO_LEVEL_NONE) |
| TheDebugInfo = new DebugInfo(TheModule); |
| else |
| TheDebugInfo = 0; |
| } |
| |
| /// performLateBackendInitialization - Set backend options that may only be |
| /// known at codegen time. |
| void performLateBackendInitialization(void) { |
| for (Module::iterator I = TheModule->begin(), E = TheModule->end(); |
| I != E; ++I) |
| if (!I->isDeclaration()) { |
| if (flag_disable_red_zone) |
| I->addFnAttr(Attribute::NoRedZone); |
| if (flag_no_implicit_float) |
| I->addFnAttr(Attribute::NoImplicitFloat); |
| } |
| } |
| |
| void llvm_lang_dependent_init(const char *Name) { |
| if (TheDebugInfo) |
| TheDebugInfo->Initialize(); |
| if (Name) |
| TheModule->setModuleIdentifier(Name); |
| } |
| |
| oFILEstream *AsmOutStream = 0; |
| static formatted_raw_ostream *AsmOutRawStream = 0; |
| oFILEstream *AsmIntermediateOutStream = 0; |
| |
| /// llvm_pch_read - Read bytecode from PCH file. Initialize TheModule and setup |
| /// LTypes vector. |
| void llvm_pch_read(const unsigned char *Buffer, unsigned Size) { |
| std::string ModuleName = TheModule->getModuleIdentifier(); |
| |
| delete TheModule; |
| delete TheDebugInfo; |
| |
| clearTargetBuiltinCache(); |
| |
| MemoryBuffer *MB = MemoryBuffer::getNewMemBuffer(Size, ModuleName.c_str()); |
| memcpy((char*)MB->getBufferStart(), Buffer, Size); |
| |
| std::string ErrMsg; |
| TheModule = ParseBitcodeFile(MB, getGlobalContext(), &ErrMsg); |
| delete MB; |
| |
| if (debug_info_level > DINFO_LEVEL_NONE) { |
| TheDebugInfo = new DebugInfo(TheModule); |
| TheDebugInfo->Initialize(); |
| } |
| |
| if (!TheModule) { |
| errs() << "Error reading bytecodes from PCH file\n"; |
| errs() << ErrMsg << "\n"; |
| exit(1); |
| } |
| |
| if (PerFunctionPasses || PerModulePasses) { |
| destroyOptimizationPasses(); |
| |
| // Don't run codegen, when we should output PCH |
| if (flag_pch_file) |
| llvm_pch_write_init(); |
| } |
| |
| // Read LLVM Types string table |
| readLLVMTypesStringTable(); |
| readLLVMValues(); |
| |
| flag_llvm_pch_read = 1; |
| } |
| |
| // Initialize remainign llvm specific data structures after pch is loaded. |
| void llvm_post_pch_read() { |
| } |
| |
| /// llvm_pch_write_init - Initialize PCH writing. |
| void llvm_pch_write_init(void) { |
| timevar_push(TV_LLVM_INIT); |
| AsmOutStream = new oFILEstream(asm_out_file); |
| // FIXME: disentangle ostream madness here. Kill off ostream and FILE. |
| AsmOutRawStream = |
| new formatted_raw_ostream(*new raw_os_ostream(*AsmOutStream), |
| formatted_raw_ostream::DELETE_STREAM); |
| |
| PerModulePasses = new PassManager(); |
| PerModulePasses->add(new TargetData(*TheTarget->getTargetData())); |
| |
| // If writing to stdout, set binary mode. |
| if (asm_out_file == stdout) |
| sys::Program::ChangeStdoutToBinary(); |
| |
| // Emit an LLVM .bc file to the output. This is used when passed |
| // -emit-llvm -c to the GCC driver. |
| PerModulePasses->add(createBitcodeWriterPass(*AsmOutRawStream)); |
| |
| // Disable emission of .ident into the output file... which is completely |
| // wrong for llvm/.bc emission cases. |
| flag_no_ident = 1; |
| |
| flag_llvm_pch_read = 0; |
| |
| timevar_pop(TV_LLVM_INIT); |
| } |
| |
| static void destroyOptimizationPasses() { |
| delete PerFunctionPasses; |
| delete PerModulePasses; |
| delete CodeGenPasses; |
| |
| PerFunctionPasses = 0; |
| PerModulePasses = 0; |
| CodeGenPasses = 0; |
| } |
| |
| |
| static void createPerFunctionOptimizationPasses() { |
| if (PerFunctionPasses) |
| return; |
| |
| // Create and set up the per-function pass manager. |
| // FIXME: Move the code generator to be function-at-a-time. |
| PerFunctionPasses = |
| new FunctionPassManager(TheModule); |
| PerFunctionPasses->add(new TargetData(*TheTarget->getTargetData())); |
| |
| // Disable (partially) loop idiom pass with -fno-builtin*. |
| TargetLibraryInfo *TLI = |
| new TargetLibraryInfo(Triple(TheModule->getTargetTriple())); |
| #ifndef __MINGW32__ |
| if (flag_no_builtin) |
| TLI->disableAllFunctions(); |
| else { |
| if (builtin_function_disabled_p("memset")) |
| TLI->setUnavailable(LibFunc::memset); |
| if (builtin_function_disabled_p("memcpy")) |
| TLI->setUnavailable(LibFunc::memcpy); |
| } |
| #else |
| TLI->disableAllFunctions(); |
| #endif |
| PerFunctionPasses->add(TLI); |
| |
| // In -O0 if checking is disabled, we don't even have per-function passes. |
| bool HasPerFunctionPasses = false; |
| #ifdef ENABLE_CHECKING |
| PerFunctionPasses->add(createVerifierPass()); |
| HasPerFunctionPasses = true; |
| #endif |
| |
| if (optimize > 0 && !DisableLLVMOptimizations) { |
| HasPerFunctionPasses = true; |
| PerFunctionPasses->add(createCFGSimplificationPass()); |
| if (optimize == 1) |
| PerFunctionPasses->add(createPromoteMemoryToRegisterPass()); |
| else |
| PerFunctionPasses->add(createScalarReplAggregatesPass()); |
| PerFunctionPasses->add(createInstructionCombiningPass()); |
| } |
| |
| // If there are no module-level passes that have to be run, we codegen as |
| // each function is parsed. |
| // FIXME: We can't figure this out until we know there are no always-inline |
| // functions. |
| // FIXME: This is disabled right now until bugs can be worked out. Reenable |
| // this for fast -O0 compiles! |
| if (!emit_llvm_bc && !emit_llvm && 0) { |
| FunctionPassManager *PM = PerFunctionPasses; |
| HasPerFunctionPasses = true; |
| |
| CodeGenOpt::Level OptLevel = CodeGenOpt::Default; // -O2, -Os, and -Oz |
| if (optimize == 0) |
| OptLevel = CodeGenOpt::None; |
| else if (optimize == 1) |
| OptLevel = CodeGenOpt::Less; |
| else if (optimize == 3) |
| // -O3 and above. |
| OptLevel = CodeGenOpt::Aggressive; |
| |
| // Request that addPassesToEmitFile run the Verifier after running |
| // passes which modify the IR. |
| #ifndef NDEBUG |
| bool DisableVerify = false; |
| #else |
| bool DisableVerify = true; |
| #endif |
| |
| // Normal mode, emit a .s file by running the code generator. |
| // Note, this also adds codegenerator level optimization passes. |
| if (TheTarget->addPassesToEmitFile(*PM, *AsmOutRawStream, |
| TargetMachine::CGFT_AssemblyFile, |
| DisableVerify)) { |
| errs() << "Error interfacing to target machine!\n"; |
| exit(1); |
| } |
| } |
| |
| if (HasPerFunctionPasses) { |
| PerFunctionPasses->doInitialization(); |
| } else { |
| delete PerFunctionPasses; |
| PerFunctionPasses = 0; |
| } |
| } |
| |
| static void createPerModuleOptimizationPasses() { |
| if (PerModulePasses) |
| // llvm_pch_write_init has already created the per module passes. |
| return; |
| |
| // FIXME: AT -O0/O1, we should stream out functions at a time. |
| PerModulePasses = new PassManager(); |
| PerModulePasses->add(new TargetData(*TheTarget->getTargetData())); |
| |
| // Disable (partially) loop idiom pass with -fno-builtin*. |
| TargetLibraryInfo *TLI = |
| new TargetLibraryInfo(Triple(TheModule->getTargetTriple())); |
| #ifndef __MINGW32__ |
| if (flag_no_builtin) |
| TLI->disableAllFunctions(); |
| else { |
| if (builtin_function_disabled_p("memset")) |
| TLI->setUnavailable(LibFunc::memset); |
| if (builtin_function_disabled_p("memcpy")) |
| TLI->setUnavailable(LibFunc::memcpy); |
| } |
| #else |
| TLI->disableAllFunctions(); |
| #endif |
| PerModulePasses->add(TLI); |
| |
| bool HasPerModulePasses = false; |
| if (!DisableLLVMOptimizations) { |
| bool NeedAlwaysInliner = false; |
| llvm::Pass *InliningPass = 0; |
| if (flag_inline_trees > 1) { // respect -fno-inline-functions |
| InliningPass = createFunctionInliningPass(); // Inline small functions |
| } else { |
| // If full inliner is not run, check if always-inline is needed to handle |
| // functions that are marked as always_inline. |
| for (Module::iterator I = TheModule->begin(), E = TheModule->end(); |
| I != E; ++I) |
| if (I->getFnAttributes().hasAlwaysInlineAttr()) { |
| NeedAlwaysInliner = true; |
| break; |
| } |
| |
| if (NeedAlwaysInliner) |
| InliningPass = createAlwaysInlinerPass(); // Inline always_inline funcs |
| } |
| |
| HasPerModulePasses = true; |
| PassManagerBuilder Builder; |
| Builder.OptLevel = optimize; |
| Builder.SizeLevel = optimize_size; |
| Builder.Inliner = InliningPass; |
| Builder.DisableSimplifyLibCalls = flag_no_simplify_libcalls; |
| Builder.DisableUnrollLoops = !flag_unroll_loops; |
| Builder.DisableUnitAtATime = !flag_unit_at_a_time; |
| Builder.populateModulePassManager(*PerModulePasses); |
| } |
| |
| if (emit_llvm_bc) { |
| // Emit an LLVM .bc file to the output. This is used when passed |
| // -emit-llvm -c to the GCC driver. |
| PerModulePasses->add(createBitcodeWriterPass(*AsmOutRawStream)); |
| HasPerModulePasses = true; |
| } else if (emit_llvm) { |
| // Emit an LLVM .ll file to the output. This is used when passed |
| // -emit-llvm -S to the GCC driver. |
| PerModulePasses->add(createPrintModulePass(AsmOutRawStream)); |
| HasPerModulePasses = true; |
| } else { |
| // If there are passes we have to run on the entire module, we do codegen |
| // as a separate "pass" after that happens. |
| // However if there are no module-level passes that have to be run, we |
| // codegen as each function is parsed. |
| // FIXME: This is disabled right now until bugs can be worked out. Reenable |
| // this for fast -O0 compiles! |
| if (PerModulePasses || 1) { |
| FunctionPassManager *PM = CodeGenPasses = |
| new FunctionPassManager(TheModule); |
| PM->add(new TargetData(*TheTarget->getTargetData())); |
| |
| CodeGenOpt::Level OptLevel = CodeGenOpt::Default; |
| |
| switch (optimize) { |
| default: break; |
| case 0: OptLevel = CodeGenOpt::None; break; |
| case 3: OptLevel = CodeGenOpt::Aggressive; break; |
| } |
| |
| // Request that addPassesToEmitFile run the Verifier after running |
| // passes which modify the IR. |
| #ifndef NDEBUG |
| bool DisableVerify = false; |
| #else |
| bool DisableVerify = true; |
| #endif |
| |
| // Normal mode, emit a .s file by running the code generator. |
| // Note, this also adds codegenerator level optimization passes. |
| if (TheTarget->addPassesToEmitFile(*PM, *AsmOutRawStream, |
| TargetMachine::CGFT_AssemblyFile, |
| DisableVerify)) { |
| errs() << "Error interfacing to target machine!\n"; |
| exit(1); |
| } |
| } |
| } |
| |
| if (!HasPerModulePasses) { |
| delete PerModulePasses; |
| PerModulePasses = 0; |
| } |
| } |
| |
| /// llvm_asm_file_start - Start the .s file. |
| void llvm_asm_file_start(void) { |
| timevar_push(TV_LLVM_INIT); |
| AsmOutStream = new oFILEstream(asm_out_file); |
| // FIXME: disentangle ostream madness here. Kill off ostream and FILE. |
| AsmOutRawStream = |
| new formatted_raw_ostream(*new raw_os_ostream(*AsmOutStream), |
| formatted_raw_ostream::DELETE_STREAM); |
| flag_llvm_pch_read = 0; |
| |
| if (emit_llvm_bc || emit_llvm) |
| // Disable emission of .ident into the output file... which is completely |
| // wrong for llvm/.bc emission cases. |
| flag_no_ident = 1; |
| |
| // If writing to stdout, set binary mode. |
| if (asm_out_file == stdout) |
| sys::Program::ChangeStdoutToBinary(); |
| |
| AttributeUsedGlobals.clear(); |
| AttributeCompilerUsedGlobals.clear(); |
| timevar_pop(TV_LLVM_INIT); |
| } |
| |
| /// ConvertStructorsList - Convert a list of static ctors/dtors to an |
| /// initializer suitable for the llvm.global_[cd]tors globals. |
| static void CreateStructorsList(std::vector<std::pair<Constant*, int> > &Tors, |
| const char *Name) { |
| std::vector<Constant*> InitList; |
| std::vector<Constant*> StructInit; |
| StructInit.resize(2); |
| |
| LLVMContext &Context = getGlobalContext(); |
| |
| Type *FPTy = |
| FunctionType::get(Type::getVoidTy(Context), std::vector<Type*>(), false); |
| FPTy = FPTy->getPointerTo(); |
| |
| for (unsigned i = 0, e = Tors.size(); i != e; ++i) { |
| StructInit[0] = ConstantInt::get(Type::getInt32Ty(Context), Tors[i].second); |
| |
| // __attribute__(constructor) can be on a function with any type. Make sure |
| // the pointer is void()*. |
| StructInit[1] = TheFolder->CreateBitCast(Tors[i].first, FPTy); |
| InitList.push_back(ConstantStruct::getAnon(StructInit)); |
| } |
| Constant *Array = ConstantArray::get( |
| ArrayType::get(InitList[0]->getType(), InitList.size()), InitList); |
| GlobalVariable *GV = new GlobalVariable(*TheModule, Array->getType(), false, |
| GlobalValue::AppendingLinkage, |
| Array, Name); |
| GV->setUnnamedAddr(true); |
| } |
| |
| /// llvm_asm_file_end - Finish the .s file. |
| void llvm_asm_file_end(void) { |
| timevar_push(TV_LLVM_PERFILE); |
| LLVMContext &Context = getGlobalContext(); |
| |
| // Assign the correct linkage to the thunks now that we've set the linkage and |
| // visibility to their targets. |
| SmallPtrSet<tree, 4> ThunkOfThunk; |
| |
| for (std::vector<tree>::iterator |
| I = Thunks.begin(), E = Thunks.end(); I != E; ++I) { |
| tree thunk = *I; |
| tree thunk_target = lang_hooks.thunk_target(thunk); |
| |
| if (lang_hooks.function_is_thunk_p (thunk_target)) { |
| ThunkOfThunk.insert(thunk); |
| continue; |
| } |
| |
| Function *Thunk = cast<Function>(DECL_LLVM(thunk)); |
| const Function *ThunkTarget = cast<Function>(DECL_LLVM(thunk_target)); |
| |
| Thunk->setLinkage(ThunkTarget->getLinkage()); |
| Thunk->setVisibility(ThunkTarget->getVisibility()); |
| } |
| |
| // There's a situation where a thunk calls another thunk. In that case, we |
| // want to process first the thunk that calls a non-thunk. Then we process |
| // each thunk in turn until all thunks have been processed. |
| while (!ThunkOfThunk.empty()) |
| for (SmallPtrSet<tree, 4>::iterator |
| I = ThunkOfThunk.begin(), E = ThunkOfThunk.end(); I != E; ++I) { |
| tree thunk = *I; |
| tree thunk_target = lang_hooks.thunk_target(thunk); |
| |
| if (!ThunkOfThunk.count(thunk_target)) { |
| Function *Thunk = cast<Function>(DECL_LLVM(thunk)); |
| const Function *ThunkTarget = cast<Function>(DECL_LLVM(thunk_target)); |
| |
| Thunk->setLinkage(ThunkTarget->getLinkage()); |
| Thunk->setVisibility(ThunkTarget->getVisibility()); |
| ThunkOfThunk.erase(thunk); |
| break; |
| } |
| } |
| |
| performLateBackendInitialization(); |
| createPerFunctionOptimizationPasses(); |
| |
| if (flag_pch_file) { |
| writeLLVMTypesStringTable(); |
| writeLLVMValues(); |
| } |
| |
| // Add an llvm.global_ctors global if needed. |
| if (!StaticCtors.empty()) |
| CreateStructorsList(StaticCtors, "llvm.global_ctors"); |
| // Add an llvm.global_dtors global if needed. |
| if (!StaticDtors.empty()) |
| CreateStructorsList(StaticDtors, "llvm.global_dtors"); |
| |
| if (!AttributeUsedGlobals.empty()) { |
| std::vector<Constant *> AUGs; |
| Type *SBP= Type::getInt8PtrTy(Context); |
| for (SmallSetVector<Constant *,32>::iterator |
| AI = AttributeUsedGlobals.begin(), |
| AE = AttributeUsedGlobals.end(); AI != AE; ++AI) { |
| Constant *C = *AI; |
| AUGs.push_back(TheFolder->CreateBitCast(C, SBP)); |
| } |
| |
| ArrayType *AT = ArrayType::get(SBP, AUGs.size()); |
| Constant *Init = ConstantArray::get(AT, AUGs); |
| GlobalValue *gv = new GlobalVariable(*TheModule, AT, false, |
| GlobalValue::AppendingLinkage, Init, |
| "llvm.used"); |
| gv->setUnnamedAddr(true); |
| gv->setSection("llvm.metadata"); |
| AttributeUsedGlobals.clear(); |
| } |
| |
| if (!AttributeCompilerUsedGlobals.empty()) { |
| std::vector<Constant *> ACUGs; |
| Type *SBP= Type::getInt8PtrTy(Context); |
| for (SmallSetVector<Constant *,32>::iterator |
| AI = AttributeCompilerUsedGlobals.begin(), |
| AE = AttributeCompilerUsedGlobals.end(); AI != AE; ++AI) { |
| Constant *C = *AI; |
| ACUGs.push_back(TheFolder->CreateBitCast(C, SBP)); |
| } |
| |
| ArrayType *AT = ArrayType::get(SBP, ACUGs.size()); |
| Constant *Init = ConstantArray::get(AT, ACUGs); |
| GlobalValue *gv = new GlobalVariable(*TheModule, AT, false, |
| GlobalValue::AppendingLinkage, Init, |
| "llvm.compiler.used"); |
| gv->setUnnamedAddr(true); |
| gv->setSection("llvm.metadata"); |
| AttributeCompilerUsedGlobals.clear(); |
| } |
| |
| // Add llvm.global.annotations |
| if (!AttributeAnnotateGlobals.empty()) { |
| Constant *Array = ConstantArray::get( |
| ArrayType::get(AttributeAnnotateGlobals[0]->getType(), |
| AttributeAnnotateGlobals.size()), |
| AttributeAnnotateGlobals); |
| GlobalValue *gv = new GlobalVariable(*TheModule, Array->getType(), false, |
| GlobalValue::AppendingLinkage, Array, |
| "llvm.global.annotations"); |
| gv->setUnnamedAddr(true); |
| gv->setSection("llvm.metadata"); |
| AttributeAnnotateGlobals.clear(); |
| } |
| |
| // Finish off the per-function pass. |
| if (PerFunctionPasses) |
| PerFunctionPasses->doFinalization(); |
| |
| // Emit intermediate file before module level optimization passes are run. |
| if (flag_debug_llvm_module_opt) { |
| |
| static PassManager *IntermediatePM = new PassManager(); |
| IntermediatePM->add(new TargetData(*TheTarget->getTargetData())); |
| |
| char asm_intermediate_out_filename[MAXPATHLEN]; |
| strcpy(&asm_intermediate_out_filename[0], asm_file_name); |
| strcat(&asm_intermediate_out_filename[0],".0"); |
| FILE *asm_intermediate_out_file = fopen(asm_intermediate_out_filename, "w+b"); |
| AsmIntermediateOutStream = new oFILEstream(asm_intermediate_out_file); |
| raw_ostream *AsmIntermediateRawOutStream = |
| new raw_os_ostream(*AsmIntermediateOutStream); |
| if (emit_llvm_bc) |
| IntermediatePM->add(createBitcodeWriterPass(*AsmIntermediateRawOutStream)); |
| if (emit_llvm) |
| IntermediatePM->add(createPrintModulePass(AsmIntermediateRawOutStream)); |
| IntermediatePM->run(*TheModule); |
| AsmIntermediateRawOutStream->flush(); |
| delete AsmIntermediateRawOutStream; |
| AsmIntermediateRawOutStream = 0; |
| AsmIntermediateOutStream->flush(); |
| fflush(asm_intermediate_out_file); |
| delete AsmIntermediateOutStream; |
| AsmIntermediateOutStream = 0; |
| } |
| |
| // Run module-level optimizers, if any are present. |
| createPerModuleOptimizationPasses(); |
| if (PerModulePasses) |
| PerModulePasses->run(*TheModule); |
| |
| // Run the code generator, if present. |
| if (CodeGenPasses) { |
| CodeGenPasses->doInitialization(); |
| for (Module::iterator I = TheModule->begin(), E = TheModule->end(); |
| I != E; ++I) |
| if (!I->isDeclaration()) |
| CodeGenPasses->run(*I); |
| CodeGenPasses->doFinalization(); |
| } |
| |
| AsmOutRawStream->flush(); |
| AsmOutStream->flush(); |
| fflush(asm_out_file); |
| delete AsmOutRawStream; |
| AsmOutRawStream = 0; |
| delete AsmOutStream; |
| AsmOutStream = 0; |
| timevar_pop(TV_LLVM_PERFILE); |
| } |
| |
| // llvm_call_llvm_shutdown - Release LLVM global state. |
| void llvm_call_llvm_shutdown(void) { |
| #ifndef NDEBUG |
| delete PerModulePasses; |
| delete PerFunctionPasses; |
| delete CodeGenPasses; |
| delete TheModule; |
| llvm_shutdown(); |
| #endif |
| } |
| |
| /// llvm_emit_code_for_current_function - Top level interface for emitting a |
| /// function to the .s file. |
| void llvm_emit_code_for_current_function(tree fndecl) { |
| if (cfun->nonlocal_goto_save_area) |
| sorry("%Jnon-local gotos not supported by LLVM", fndecl); |
| |
| if (errorcount || sorrycount) { |
| TREE_ASM_WRITTEN(fndecl) = 1; |
| return; // Do not process broken code. |
| } |
| |
| timevar_push(TV_LLVM_FUNCS); |
| |
| // Convert the AST to raw/ugly LLVM code. |
| Function *Fn; |
| { |
| TreeToLLVM *Emitter = new TreeToLLVM(fndecl); |
| // FIXME: should we store TheTreeToLLVM right here (current in constructor)? |
| enum symbol_visibility vis = DECL_VISIBILITY (fndecl); |
| |
| if (vis != VISIBILITY_DEFAULT) |
| // "asm_out.visibility" emits an important warning if we're using a |
| // visibility that's not supported by the target. |
| targetm.asm_out.visibility(fndecl, vis); |
| |
| Fn = TheTreeToLLVM->EmitFunction(); |
| Emitter->~TreeToLLVM(); |
| } |
| |
| #if 0 |
| if (dump_file) { |
| fprintf (dump_file, |
| "\n\n;;\n;; Full LLVM generated for this function:\n;;\n"); |
| Fn->dump(); |
| } |
| #endif |
| |
| performLateBackendInitialization(); |
| createPerFunctionOptimizationPasses(); |
| |
| if (PerFunctionPasses) |
| PerFunctionPasses->run(*Fn); |
| |
| // TODO: Nuke the .ll code for the function at -O[01] if we don't want to |
| // inline it or something else. |
| |
| // There's no need to defer outputting this function any more; we |
| // know we want to output it. |
| DECL_DEFER_OUTPUT(fndecl) = 0; |
| |
| // Finally, we have written out this function! |
| TREE_ASM_WRITTEN(fndecl) = 1; |
| timevar_pop(TV_LLVM_FUNCS); |
| } |
| |
| /// emit_alias_to_llvm - Given decl and target emit alias to target. |
| void emit_alias_to_llvm(tree decl, tree target, tree target_decl) { |
| if (errorcount || sorrycount) { |
| TREE_ASM_WRITTEN(decl) = 1; |
| return; // Do not process broken code. |
| } |
| |
| timevar_push(TV_LLVM_GLOBALS); |
| |
| // Get or create LLVM global for our alias. |
| GlobalValue *V = cast<GlobalValue>(DECL_LLVM(decl)); |
| |
| GlobalValue *Aliasee = NULL; |
| |
| if (target_decl) |
| Aliasee = cast<GlobalValue>(DECL_LLVM(target_decl)); |
| else { |
| // This is something insane. Probably only LTHUNKs can be here |
| // Try to grab decl from IDENTIFIER_NODE |
| |
| // Query SymTab for aliasee |
| const char* AliaseeName = IDENTIFIER_POINTER(target); |
| Aliasee = |
| dyn_cast_or_null<GlobalValue>(TheModule-> |
| getValueSymbolTable().lookup(AliaseeName)); |
| |
| // Last resort. Query for name set via __asm__ |
| if (!Aliasee) { |
| std::string starred = std::string("\001") + AliaseeName; |
| Aliasee = |
| dyn_cast_or_null<GlobalValue>(TheModule-> |
| getValueSymbolTable().lookup(starred)); |
| } |
| |
| if (!Aliasee) { |
| if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))) { |
| if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) |
| Aliasee = new GlobalVariable(*TheModule, GV->getType(), |
| GV->isConstant(), |
| GlobalVariable::ExternalWeakLinkage, |
| NULL, AliaseeName); |
| else if (Function *F = dyn_cast<Function>(V)) |
| Aliasee = Function::Create(F->getFunctionType(), |
| Function::ExternalWeakLinkage, |
| AliaseeName, TheModule); |
| else |
| assert(0 && "Unsuported global value"); |
| Aliasee->setUnnamedAddr(true); |
| } else { |
| error ("%J%qD aliased to undefined symbol %qs", decl, decl, AliaseeName); |
| timevar_pop(TV_LLVM_GLOBALS); |
| return; |
| } |
| } |
| } |
| |
| GlobalValue::LinkageTypes Linkage; |
| |
| // A weak alias has TREE_PUBLIC set but not the other bits. |
| if (DECL_LLVM_PRIVATE(decl)) |
| Linkage = GlobalValue::PrivateLinkage; |
| else if (DECL_LLVM_LINKER_PRIVATE(decl)) |
| Linkage = GlobalValue::LinkerPrivateLinkage; |
| else if (DECL_LLVM_LINKER_PRIVATE_WEAK(decl)) |
| Linkage = GlobalValue::LinkerPrivateWeakLinkage; |
| else if (DECL_WEAK(decl)) |
| // The user may have explicitly asked for weak linkage - ignore flag_odr. |
| Linkage = GlobalValue::WeakAnyLinkage; |
| else if (!TREE_PUBLIC(decl)) |
| Linkage = GlobalValue::InternalLinkage; |
| else |
| Linkage = GlobalValue::ExternalLinkage; |
| |
| GlobalAlias* GA = new GlobalAlias(Aliasee->getType(), Linkage, "", |
| Aliasee, TheModule); |
| |
| handleVisibility(decl, GA); |
| |
| if (GA->getType()->canLosslesslyBitCastTo(V->getType())) |
| V->replaceAllUsesWith(ConstantExpr::getBitCast(GA, V->getType())); |
| else if (!V->use_empty()) { |
| error ("%J Alias %qD used with invalid type!", decl, decl); |
| timevar_pop(TV_LLVM_GLOBALS); |
| return; |
| } |
| |
| changeLLVMConstant(V, GA); |
| GA->takeName(V); |
| if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) |
| GV->eraseFromParent(); |
| else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) |
| GA->eraseFromParent(); |
| else if (Function *F = dyn_cast<Function>(V)) |
| F->eraseFromParent(); |
| else |
| assert(0 && "Unsuported global value"); |
| |
| TREE_ASM_WRITTEN(decl) = 1; |
| |
| timevar_pop(TV_LLVM_GLOBALS); |
| return; |
| } |
| |
| /// ConvertMetadataStringToGV - Convert string to global value. Use existing |
| /// global if possible. |
| Constant* ConvertMetadataStringToGV(const char *str) { |
| |
| Constant *Init = ConstantArray::get(getGlobalContext(), 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(*TheModule, Init->getType(), true, |
| GlobalVariable::PrivateLinkage, |
| Init, ".str"); |
| GV->setSection("llvm.metadata"); |
| GV->setUnnamedAddr(true); |
| Slot = GV; |
| return GV; |
| |
| } |
| |
| /// AddAnnotateAttrsToGlobal - Adds decls that have a annotate attribute to a |
| /// vector to be emitted later. |
| void AddAnnotateAttrsToGlobal(GlobalValue *GV, tree decl) { |
| LLVMContext &Context = getGlobalContext(); |
| |
| // Handle annotate attribute on global. |
| tree annotateAttr = lookup_attribute("annotate", DECL_ATTRIBUTES (decl)); |
| if (annotateAttr == 0) |
| return; |
| |
| // Get file and line number |
| Constant *lineNo = ConstantInt::get(Type::getInt32Ty(Context), |
| DECL_SOURCE_LINE(decl)); |
| Constant *file = ConvertMetadataStringToGV(DECL_SOURCE_FILE(decl)); |
| Type *SBP= Type::getInt8PtrTy(Context); |
| file = TheFolder->CreateBitCast(file, SBP); |
| |
| // There may be multiple annotate attributes. Pass return of lookup_attr |
| // to successive lookups. |
| while (annotateAttr) { |
| |
| // Each annotate attribute is a tree list. |
| // Get value of list which is our linked list of args. |
| tree args = TREE_VALUE(annotateAttr); |
| |
| // Each annotate attribute may have multiple args. |
| // Treat each arg as if it were a separate annotate attribute. |
| for (tree a = args; a; a = TREE_CHAIN(a)) { |
| // Each element of the arg list is a tree list, so get value |
| tree val = TREE_VALUE(a); |
| |
| // Assert its a string, and then get that string. |
| assert(TREE_CODE(val) == STRING_CST && |
| "Annotate attribute arg should always be a string"); |
| Constant *strGV = TreeConstantToLLVM::EmitLV_STRING_CST(val); |
| Constant *Element[4] = { |
| TheFolder->CreateBitCast(GV,SBP), |
| TheFolder->CreateBitCast(strGV,SBP), |
| file, |
| lineNo |
| }; |
| |
| AttributeAnnotateGlobals.push_back( |
| ConstantStruct::getAnon(Context, Element)); |
| } |
| |
| // Get next annotate attribute. |
| annotateAttr = TREE_CHAIN(annotateAttr); |
| if (annotateAttr) |
| annotateAttr = lookup_attribute("annotate", annotateAttr); |
| } |
| } |
| |
| /// reset_initializer_llvm - Change the initializer for a global variable. |
| void reset_initializer_llvm(tree decl) { |
| // If there were earlier errors we can get here when DECL_LLVM has not |
| // been set. Don't crash. |
| // We can also get here when DECL_LLVM has not been set for some object |
| // referenced in the initializer. Don't crash then either. |
| if (errorcount || sorrycount) |
| return; |
| |
| // Get or create the global variable now. |
| GlobalVariable *GV = cast<GlobalVariable>(DECL_LLVM(decl)); |
| |
| // Visibility may also have changed. |
| handleVisibility(decl, GV); |
| |
| // Convert the initializer over. |
| Constant *Init = TreeConstantToLLVM::Convert(DECL_INITIAL(decl)); |
| |
| // Set the initializer. |
| if (GV->getType()->getElementType() != Init->getType()) { |
| GV->removeFromParent(); |
| GlobalVariable *NGV = new GlobalVariable(*TheModule, Init->getType(), |
| GV->isConstant(), |
| GV->getLinkage(), 0, |
| GV->getName()); |
| NGV->setVisibility(GV->getVisibility()); |
| NGV->setSection(GV->getSection()); |
| NGV->setAlignment(GV->getAlignment()); |
| NGV->setLinkage(GV->getLinkage()); |
| GV->replaceAllUsesWith(TheFolder->CreateBitCast(NGV, GV->getType())); |
| changeLLVMConstant(GV, NGV); |
| delete GV; |
| SET_DECL_LLVM(decl, NGV); |
| GV = NGV; |
| } |
| GV->setInitializer(Init); |
| if (GV->hasHiddenVisibility() || GV->hasInternalLinkage() || |
| GV->hasPrivateLinkage()) |
| GV->setUnnamedAddr(true); |
| } |
| |
| /// reset_type_and_initializer_llvm - Change the type and initializer for |
| /// a global variable. |
| void reset_type_and_initializer_llvm(tree decl) { |
| // If there were earlier errors we can get here when DECL_LLVM has not |
| // been set. Don't crash. |
| // We can also get here when DECL_LLVM has not been set for some object |
| // referenced in the initializer. Don't crash then either. |
| if (errorcount || sorrycount) |
| return; |
| |
| // Get or create the global variable now. |
| GlobalVariable *GV = cast<GlobalVariable>(DECL_LLVM(decl)); |
| |
| // Visibility may also have changed. |
| handleVisibility(decl, GV); |
| |
| // Temporary to avoid infinite recursion (see comments emit_global_to_llvm) |
| GV->setInitializer(UndefValue::get(GV->getType()->getElementType())); |
| if (GV->hasHiddenVisibility() || GV->hasInternalLinkage() || |
| GV->hasPrivateLinkage()) |
| GV->setUnnamedAddr(true); |
| |
| // Convert the initializer over. |
| Constant *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(*TheModule, Init->getType(), |
| GV->isConstant(), |
| GV->getLinkage(), 0, |
| GV->getName()); |
| NGV->setVisibility(GV->getVisibility()); |
| NGV->setSection(GV->getSection()); |
| NGV->setAlignment(GV->getAlignment()); |
| NGV->setLinkage(GV->getLinkage()); |
| GV->replaceAllUsesWith(TheFolder->CreateBitCast(NGV, GV->getType())); |
| changeLLVMConstant(GV, NGV); |
| delete GV; |
| SET_DECL_LLVM(decl, NGV); |
| if (NGV->hasHiddenVisibility() || NGV->hasInternalLinkage() || |
| NGV->hasPrivateLinkage()) |
| NGV->setUnnamedAddr(true); |
| GV = NGV; |
| } |
| |
| // Set the initializer. |
| GV->setInitializer(Init); |
| } |
| |
| /// 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) { |
| TREE_ASM_WRITTEN(decl) = 1; |
| return; // Do not process broken code. |
| } |
| |
| // 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; |
| |
| // If tree nodes says defer output then do not emit global yet. |
| if (CODE_CONTAINS_STRUCT (TREE_CODE (decl), TS_DECL_WITH_VIS) |
| && (DECL_DEFER_OUTPUT(decl))) |
| return; |
| |
| // If we encounter a forward declaration then do not emit the global yet. |
| if (!TYPE_SIZE(TREE_TYPE(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())); |
| if (GV->hasHiddenVisibility() || GV->hasInternalLinkage() || |
| GV->hasPrivateLinkage()) |
| GV->setUnnamedAddr(true); |
| 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(*TheModule, Init->getType(), |
| GV->isConstant(), |
| GlobalValue::ExternalLinkage, 0, |
| GV->getName()); |
| GV->replaceAllUsesWith(TheFolder->CreateBitCast(NGV, GV->getType())); |
| changeLLVMConstant(GV, NGV); |
| delete GV; |
| SET_DECL_LLVM(decl, NGV); |
| GV = NGV; |
| } |
| |
| // Set the initializer. |
| GV->setInitializer(Init); |
| if (GV->hasHiddenVisibility() || GV->hasInternalLinkage() || |
| GV->hasPrivateLinkage()) |
| GV->setUnnamedAddr(true); |
| |
| // Set thread local (TLS) |
| if (TREE_CODE(decl) == VAR_DECL && DECL_THREAD_LOCAL_P(decl)) |
| GV->setThreadLocal(true); |
| |
| // Set the linkage. |
| GlobalValue::LinkageTypes Linkage; |
| |
| if (CODE_CONTAINS_STRUCT (TREE_CODE (decl), TS_DECL_WITH_VIS) |
| && DECL_LLVM_PRIVATE(decl)) { |
| Linkage = GlobalValue::PrivateLinkage; |
| } else if (CODE_CONTAINS_STRUCT (TREE_CODE (decl), TS_DECL_WITH_VIS) |
| && DECL_LLVM_LINKER_PRIVATE(decl)) { |
| Linkage = GlobalValue::LinkerPrivateLinkage; |
| } else if (CODE_CONTAINS_STRUCT (TREE_CODE (decl), TS_DECL_WITH_VIS) |
| && DECL_LLVM_LINKER_PRIVATE_WEAK(decl)) { |
| Linkage = GlobalValue::LinkerPrivateWeakLinkage; |
| } else if (!TREE_PUBLIC(decl)) { |
| Linkage = GlobalValue::InternalLinkage; |
| } else if (DECL_WEAK(decl)) { |
| // The user may have explicitly asked for weak linkage - ignore flag_odr. |
| Linkage = GlobalValue::WeakAnyLinkage; |
| } else if (DECL_ONE_ONLY(decl)) { |
| Linkage = GlobalValue::getWeakLinkage(flag_odr); |
| } else if (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. |
| Linkage = GlobalValue::CommonLinkage; |
| GV->setConstant(false); |
| } else if (DECL_COMDAT(decl)) { |
| Linkage = GlobalValue::getLinkOnceLinkage(flag_odr); |
| } else { |
| Linkage = GV->getLinkage(); |
| } |
| |
| // Allow loads from constants to be folded even if the constant has weak |
| // linkage. Do this by giving the constant weak_odr linkage rather than |
| // weak linkage. It is not clear whether this optimization is valid (see |
| // gcc bug 36685), but mainline gcc chooses to do it, and fold may already |
| // have done it, so we might as well join in with gusto. |
| if (GV->isConstant()) { |
| if (Linkage == GlobalValue::WeakAnyLinkage) |
| Linkage = GlobalValue::WeakODRLinkage; |
| else if (Linkage == GlobalValue::LinkOnceAnyLinkage) |
| Linkage = GlobalValue::LinkOnceODRLinkage; |
| } |
| GV->setLinkage(Linkage); |
| |
| #ifdef TARGET_ADJUST_LLVM_LINKAGE |
| TARGET_ADJUST_LLVM_LINKAGE(GV, decl); |
| #endif /* TARGET_ADJUST_LLVM_LINKAGE */ |
| |
| handleVisibility(decl, GV); |
| if (GV->hasHiddenVisibility() || GV->hasInternalLinkage() || |
| GV->hasPrivateLinkage()) |
| GV->setUnnamedAddr(true); |
| |
| // Set the section for the global. |
| if (TREE_CODE(decl) == VAR_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 is better than the alignment as per ABI specification |
| // 2) DECL_ALIGN is set by user. |
| if (DECL_ALIGN(decl)) { |
| unsigned TargetAlign = |
| getTargetData().getABITypeAlignment(GV->getType()->getElementType()); |
| if (DECL_USER_ALIGN(decl) || |
| 8 * TargetAlign < (unsigned)DECL_ALIGN(decl)) { |
| GV->setAlignment(DECL_ALIGN(decl) / 8); |
| } |
| #ifdef TARGET_ADJUST_CSTRING_ALIGN |
| else if (DECL_INITIAL(decl) != error_mark_node && // uninitialized? |
| DECL_INITIAL(decl) && |
| TREE_CODE(DECL_INITIAL(decl)) == STRING_CST) { |
| TARGET_ADJUST_CSTRING_ALIGN(GV); |
| } |
| #endif |
| } |
| |
| // Handle used decls |
| if (DECL_PRESERVE_P (decl)) { |
| if (DECL_LLVM_LINKER_PRIVATE (decl) || |
| DECL_LLVM_LINKER_PRIVATE_WEAK (decl)) |
| AttributeCompilerUsedGlobals.insert(GV); |
| else |
| AttributeUsedGlobals.insert(GV); |
| } |
| |
| // Add annotate attributes for globals |
| if (DECL_ATTRIBUTES(decl)) |
| AddAnnotateAttrsToGlobal(GV, decl); |
| |
| #ifdef LLVM_IMPLICIT_TARGET_GLOBAL_VAR_SECTION |
| } else if (TREE_CODE(decl) == CONST_DECL) { |
| if (const char *Section = |
| LLVM_IMPLICIT_TARGET_GLOBAL_VAR_SECTION(decl)) { |
| GV->setSection(Section); |
| |
| /* LLVM LOCAL - begin radar 6389998 */ |
| #ifdef TARGET_ADJUST_CFSTRING_NAME |
| TARGET_ADJUST_CFSTRING_NAME(GV, Section); |
| #endif |
| /* LLVM LOCAL - end radar 6389998 */ |
| } |
| #endif |
| } |
| |
| if (TheDebugInfo) { |
| if (flag_objc_abi == -1 || flag_objc_abi == 0 || |
| (!GV->getName().startswith("\01L_OBJC_") && |
| !GV->getName().startswith("\01l_OBJC_"))) |
| TheDebugInfo->EmitGlobalVariable(GV, decl); |
| } |
| |
| TREE_ASM_WRITTEN(decl) = 1; |
| timevar_pop(TV_LLVM_GLOBALS); |
| } |
| |
| |
| /// ValidateRegisterVariable - Check that a static "asm" variable is |
| /// well-formed. If not, emit error messages and return true. If so, return |
| /// false. |
| bool ValidateRegisterVariable(tree decl) { |
| int RegNumber = decode_reg_name(extractRegisterName(decl)); |
| Type *Ty = ConvertType(TREE_TYPE(decl)); |
| |
| if (errorcount || sorrycount) |
| return true; // Do not process broken code. |
| |
| /* Detect errors in declaring global registers. */ |
| if (RegNumber == -1) |
| error("%Jregister name not specified for %qD", decl, decl); |
| else if (RegNumber < 0) |
| error("%Jinvalid register name for %qD", decl, decl); |
| else if (TYPE_MODE(TREE_TYPE(decl)) == BLKmode) |
| error("%Jdata type of %qD isn%'t suitable for a register", decl, decl); |
| #if 0 // FIXME: enable this. |
| else if (!HARD_REGNO_MODE_OK(RegNumber, TYPE_MODE(TREE_TYPE(decl)))) |
| error("%Jregister specified for %qD isn%'t suitable for data type", |
| decl, decl); |
| #endif |
| else if (DECL_INITIAL(decl) != 0 && TREE_STATIC(decl)) |
| error("global register variable has initial value"); |
| else if (!Ty->isSingleValueType()) |
| sorry("%JLLVM cannot handle register variable %qD, report a bug", |
| decl, decl); |
| else { |
| if (TREE_THIS_VOLATILE(decl)) |
| warning(0, "volatile register variables don%'t work as you might wish"); |
| |
| return false; // Everything ok. |
| } |
| |
| return true; |
| } |
| |
| |
| /// make_decl_llvm - Create the DECL_RTL for a VAR_DECL or FUNCTION_DECL. DECL |
| /// should have static storage duration. In other words, it should not be an |
| /// automatic variable, including PARM_DECLs. |
| /// |
| /// There is, however, one exception: this function handles variables explicitly |
| /// placed in a particular register by the user. |
| /// |
| /// This function corresponds to make_decl_rtl in varasm.c, and is implicitly |
| /// called by DECL_LLVM if a decl doesn't have an LLVM set. |
| void make_decl_llvm(tree decl) { |
| #ifdef ENABLE_CHECKING |
| // Check that we are not being given an automatic variable. |
| // A weak alias has TREE_PUBLIC set but not the other bits. |
| if (TREE_CODE(decl) == PARM_DECL || TREE_CODE(decl) == RESULT_DECL |
| || (TREE_CODE(decl) == VAR_DECL && !TREE_STATIC(decl) && |
| !TREE_PUBLIC(decl) && !DECL_EXTERNAL(decl) && !DECL_REGISTER(decl))) |
| abort(); |
| // And that we were not given a type or a label. */ |
| else if (TREE_CODE(decl) == TYPE_DECL || TREE_CODE(decl) == LABEL_DECL) |
| abort (); |
| #endif |
| |
| LLVMContext &Context = getGlobalContext(); |
| |
| // For a duplicate declaration, we can be called twice on the |
| // same DECL node. Don't discard the LLVM already made. |
| if (DECL_LLVM_SET_P(decl)) return; |
| |
| if (errorcount || sorrycount) |
| return; // Do not process broken code. |
| |
| |
| // Global register variable with asm name, e.g.: |
| // register unsigned long esp __asm__("ebp"); |
| if (TREE_CODE(decl) != FUNCTION_DECL && DECL_REGISTER(decl)) { |
| // This just verifies that the variable is ok. The actual "load/store" |
| // code paths handle accesses to the variable. |
| ValidateRegisterVariable(decl); |
| return; |
| } |
| |
| timevar_push(TV_LLVM_GLOBALS); |
| |
| const char *Name = ""; |
| if (DECL_NAME(decl)) |
| if (tree AssemblerName = DECL_ASSEMBLER_NAME(decl)) |
| Name = IDENTIFIER_POINTER(AssemblerName); |
| |
| // Now handle ordinary static variables and functions (in memory). |
| // Also handle vars declared register invalidly. |
| if (Name[0] == 1) { |
| #ifdef REGISTER_PREFIX |
| if (strlen (REGISTER_PREFIX) != 0) { |
| int reg_number = decode_reg_name(Name); |
| if (reg_number >= 0 || reg_number == -3) |
| error("%Jregister name given for non-register variable %qD", |
| decl, decl); |
| } |
| #endif |
| } |
| |
| // Specifying a section attribute on a variable forces it into a |
| // non-.bss section, and thus it cannot be common. |
| if (TREE_CODE(decl) == VAR_DECL && DECL_SECTION_NAME(decl) != NULL_TREE && |
| DECL_INITIAL(decl) == NULL_TREE && DECL_COMMON(decl)) |
| DECL_COMMON(decl) = 0; |
| |
| // Variables can't be both common and weak. |
| if (TREE_CODE(decl) == VAR_DECL && DECL_WEAK(decl)) |
| DECL_COMMON(decl) = 0; |
| |
| // Okay, now we need to create an LLVM global variable or function for this |
| // object. Note that this is quite possibly a forward reference to the |
| // object, so its type may change later. |
| if (TREE_CODE(decl) == FUNCTION_DECL) { |
| assert(Name[0] && "Function with empty name!"); |
| // If this function has already been created, reuse the decl. This happens |
| // when we have something like __builtin_memset and memset in the same file. |
| Function *FnEntry = TheModule->getFunction(Name); |
| if (FnEntry == 0) { |
| CallingConv::ID CC; |
| AttrListPtr PAL; |
| FunctionType *Ty = |
| TheTypeConverter->ConvertFunctionType(TREE_TYPE(decl), decl, NULL, |
| CC, PAL); |
| FnEntry = Function::Create(Ty, Function::ExternalLinkage, Name, TheModule); |
| FnEntry->setCallingConv(CC); |
| FnEntry->setAttributes(PAL); |
| |
| // Check for external weak linkage. |
| if (DECL_EXTERNAL(decl) && DECL_WEAK(decl)) |
| FnEntry->setLinkage(Function::ExternalWeakLinkage); |
| |
| #ifdef TARGET_ADJUST_LLVM_LINKAGE |
| TARGET_ADJUST_LLVM_LINKAGE(FnEntry,decl); |
| #endif /* TARGET_ADJUST_LLVM_LINKAGE */ |
| |
| handleVisibility(decl, FnEntry); |
| |
| // If FnEntry got renamed, then there is already an object with this name |
| // in the symbol table. If this happens, the old one must be a forward |
| // decl, just replace it with a cast of the new one. |
| if (FnEntry->getName() != Name) { |
| GlobalVariable *G = TheModule->getGlobalVariable(Name, true); |
| assert(G && G->isDeclaration() && "A global turned into a function?"); |
| |
| // Replace any uses of "G" with uses of FnEntry. |
| Constant *GInNewType = TheFolder->CreateBitCast(FnEntry, G->getType()); |
| G->replaceAllUsesWith(GInNewType); |
| |
| // Update the decl that points to G. |
| changeLLVMConstant(G, GInNewType); |
| |
| // Now we can give GV the proper name. |
| FnEntry->takeName(G); |
| |
| // G is now dead, nuke it. |
| G->eraseFromParent(); |
| } |
| } |
| SET_DECL_LLVM(decl, FnEntry); |
| } else { |
| assert((TREE_CODE(decl) == VAR_DECL || |
| TREE_CODE(decl) == CONST_DECL) && "Not a function or var decl?"); |
| Type *Ty = ConvertType(TREE_TYPE(decl)); |
| GlobalVariable *GV ; |
| |
| // If we have "extern void foo", make the global have type {} instead of |
| // type void. |
| if (Ty->isVoidTy()) |
| Ty = StructType::get(Context); |
| |
| if (Name[0] == 0) { // Global has no name. |
| GV = new GlobalVariable(*TheModule, Ty, false, |
| GlobalValue::ExternalLinkage, 0, ""); |
| |
| // Check for external weak linkage. |
| if (DECL_EXTERNAL(decl) && DECL_WEAK(decl)) |
| GV->setLinkage(GlobalValue::ExternalWeakLinkage); |
| |
| #ifdef TARGET_ADJUST_LLVM_LINKAGE |
| TARGET_ADJUST_LLVM_LINKAGE(GV,decl); |
| #endif /* TARGET_ADJUST_LLVM_LINKAGE */ |
| |
| handleVisibility(decl, GV); |
| if (GV->hasHiddenVisibility() || GV->hasInternalLinkage() || |
| GV->hasPrivateLinkage()) |
| GV->setUnnamedAddr(true); |
| } else { |
| // If the global has a name, prevent multiple vars with the same name from |
| // being created. |
| GlobalVariable *GVE = TheModule->getGlobalVariable(Name, true); |
| |
| if (GVE == 0) { |
| GV = new GlobalVariable(*TheModule, Ty, false, |
| GlobalValue::ExternalLinkage, 0, Name); |
| |
| // Check for external weak linkage. |
| if (DECL_EXTERNAL(decl) && DECL_WEAK(decl)) |
| GV->setLinkage(GlobalValue::ExternalWeakLinkage); |
| |
| #ifdef TARGET_ADJUST_LLVM_LINKAGE |
| TARGET_ADJUST_LLVM_LINKAGE(GV,decl); |
| #endif /* TARGET_ADJUST_LLVM_LINKAGE */ |
| |
| handleVisibility(decl, GV); |
| |
| if (GV->hasHiddenVisibility() || GV->hasInternalLinkage() || |
| GV->hasPrivateLinkage()) |
| GV->setUnnamedAddr(true); |
| |
| // If GV got renamed, then there is already an object with this name in |
| // the symbol table. If this happens, the old one must be a forward |
| // decl, just replace it with a cast of the new one. |
| if (GV->getName() != Name) { |
| Function *F = TheModule->getFunction(Name); |
| assert(F && F->isDeclaration() && "A function turned into a global?"); |
| |
| // Replace any uses of "F" with uses of GV. |
| Constant *FInNewType = TheFolder->CreateBitCast(GV, F->getType()); |
| F->replaceAllUsesWith(FInNewType); |
| |
| // Update the decl that points to F. |
| changeLLVMConstant(F, FInNewType); |
| |
| // Now we can give GV the proper name. |
| GV->takeName(F); |
| |
| // F is now dead, nuke it. |
| F->eraseFromParent(); |
| } |
| |
| } else { |
| GV = GVE; // Global already created, reuse it. |
| } |
| } |
| |
| if ((TREE_READONLY(decl) && !TREE_SIDE_EFFECTS(decl)) || |
| TREE_CODE(decl) == CONST_DECL) { |
| if (DECL_EXTERNAL(decl)) { |
| // Mark external globals constant even though they could be marked |
| // non-constant in the defining translation unit. The definition of the |
| // global determines whether the global is ultimately constant or not, |
| // marking this constant will allow us to do some extra (legal) |
| // optimizations that we would otherwise not be able to do. (In C++, |
| // any global that is 'C++ const' may not be readonly: it could have a |
| // dynamic initializer. |
| // |
| GV->setConstant(true); |
| } else { |
| // Mark readonly globals with constant initializers constant. |
| if (DECL_INITIAL(decl) != error_mark_node && // uninitialized? |
| DECL_INITIAL(decl) && |
| (TREE_CONSTANT(DECL_INITIAL(decl)) || |
| TREE_CODE(DECL_INITIAL(decl)) == STRING_CST)) |
| GV->setConstant(true); |
| } |
| } |
| |
| // Set thread local (TLS) |
| if (TREE_CODE(decl) == VAR_DECL && DECL_THREAD_LOCAL_P(decl)) |
| GV->setThreadLocal(true); |
| |
| SET_DECL_LLVM(decl, GV); |
| } |
| timevar_pop(TV_LLVM_GLOBALS); |
| } |
| |
| /// llvm_get_decl_name - Used by varasm.c, returns the specified declaration's |
| /// name. |
| const char *llvm_get_decl_name(void *LLVM) { |
| if (LLVM) |
| if (const ValueName *VN = ((Value*)LLVM)->getValueName()) |
| return VN->getKeyData(); |
| return ""; |
| } |
| |
| /// llvm_mark_decl_weak - Used by varasm.c, called when a decl is found to be |
| /// weak, but it already had an llvm object created for it. This marks the LLVM |
| /// object weak as well. |
| void llvm_mark_decl_weak(tree decl) { |
| assert(DECL_LLVM_SET_P(decl) && DECL_WEAK(decl) && |
| isa<GlobalValue>(DECL_LLVM(decl)) && "Decl isn't marked weak!"); |
| GlobalValue *GV = cast<GlobalValue>(DECL_LLVM(decl)); |
| |
| // Do not mark something that is already known to be linkonce or internal. |
| // The user may have explicitly asked for weak linkage - ignore flag_odr. |
| if (GV->hasExternalLinkage()) { |
| GlobalValue::LinkageTypes Linkage; |
| if (GV->isDeclaration()) { |
| Linkage = GlobalValue::ExternalWeakLinkage; |
| } else { |
| Linkage = GlobalValue::WeakAnyLinkage; |
| // Allow loads from constants to be folded even if the constant has weak |
| // linkage. Do this by giving the constant weak_odr linkage rather than |
| // weak linkage. It is not clear whether this optimization is valid (see |
| // gcc bug 36685), but mainline gcc chooses to do it, and fold may already |
| // have done it, so we might as well join in with gusto. |
| if (GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) |
| if (GVar->isConstant()) |
| Linkage = GlobalValue::WeakODRLinkage; |
| } |
| GV->setLinkage(Linkage); |
| } |
| } |
| |
| /// llvm_emit_ctor_dtor - Called to emit static ctors/dtors to LLVM code. |
| /// fndecl is a 'void()' FUNCTION_DECL for the code, initprio is the init |
| /// priority, and isCtor indicates whether this is a ctor or dtor. |
| void llvm_emit_ctor_dtor(tree FnDecl, int InitPrio, int isCtor) { |
| mark_decl_referenced(FnDecl); // Inform cgraph that we used the global. |
| |
| if (errorcount || sorrycount) return; |
| |
| Constant *C = cast<Constant>(DECL_LLVM(FnDecl)); |
| (isCtor ? &StaticCtors:&StaticDtors)->push_back(std::make_pair(C, InitPrio)); |
| } |
| |
| void llvm_emit_typedef(tree decl) { |
| // Need hooks for debug info? |
| return; |
| } |
| |
| /// llvm_emit_file_scope_asm - Emit the specified string as a file-scope inline |
| /// asm block. |
| void llvm_emit_file_scope_asm(const char *string) { |
| if (TheModule->getModuleInlineAsm().empty()) |
| TheModule->setModuleInlineAsm(string); |
| else |
| TheModule->setModuleInlineAsm(TheModule->getModuleInlineAsm() + "\n" + |
| string); |
| } |
| |
| /// print_llvm - Print the specified LLVM chunk like an operand, called by |
| /// print-tree.c for tree dumps. |
| void print_llvm(FILE *file, void *LLVM) { |
| // FIXME: oFILEstream can probably be removed in favor of a new raw_ostream |
| // adaptor which would be simpler and more efficient. In the meantime, just |
| // adapt the adaptor. |
| oFILEstream FS(file); |
| raw_os_ostream FSS(FS); |
| FSS << "LLVM: "; |
| WriteAsOperand(FSS, (Value*)LLVM, true, TheModule); |
| } |
| |
| /// print_llvm_type - Print the specified LLVM type symbolically, called by |
| /// print-tree.c for tree dumps. |
| void print_llvm_type(FILE *file, void *LLVM) { |
| oFILEstream FS(file); |
| FS << "LLVM: "; |
| |
| // FIXME: oFILEstream can probably be removed in favor of a new raw_ostream |
| // adaptor which would be simpler and more efficient. In the meantime, just |
| // adapt the adaptor. |
| raw_os_ostream RO(FS); |
| RO << *(Type*)LLVM; |
| } |
| |
| /// extractRegisterName - Get a register name given its decl. In 4.2 unlike 4.0 |
| /// these names have been run through set_user_assembler_name which means they |
| /// may have a leading \1 at this point; compensate. |
| const char* extractRegisterName(tree decl) { |
| const char* Name = IDENTIFIER_POINTER(DECL_ASSEMBLER_NAME(decl)); |
| return (*Name == 1) ? Name + 1 : Name; |
| } |
| /* LLVM LOCAL end (ENTIRE FILE!) */ |