void TargetLoweringObjectFileELF::emitPersonalityValue(MCStreamer &Streamer, const TargetMachine &TM, const MCSymbol *Sym) const { SmallString<64> NameData("DW.ref."); NameData += Sym->getName(); MCSymbol *Label = getContext().GetOrCreateSymbol(NameData); Streamer.EmitSymbolAttribute(Label, MCSA_Hidden); Streamer.EmitSymbolAttribute(Label, MCSA_Weak); StringRef Prefix = ".data."; NameData.insert(NameData.begin(), Prefix.begin(), Prefix.end()); unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_GROUP; const MCSection *Sec = getContext().getELFSection(NameData, ELF::SHT_PROGBITS, Flags, SectionKind::getDataRel(), 0, Label->getName()); unsigned Size = TM.getTargetData()->getPointerSize(); Streamer.SwitchSection(Sec); Streamer.EmitValueToAlignment(TM.getTargetData()->getPointerABIAlignment()); Streamer.EmitSymbolAttribute(Label, MCSA_ELF_TypeObject); const MCExpr *E = MCConstantExpr::Create(Size, getContext()); Streamer.EmitELFSize(Label, E); Streamer.EmitLabel(Label); Streamer.EmitSymbolValue(Sym, Size); }
/// IsGlobalInSmallSection - Return true if this global address should be /// placed into small data/bss section. bool MipsTargetObjectFile:: IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM, SectionKind Kind) const { // Only use small section for non linux targets. const MipsSubtarget &Subtarget = TM.getSubtarget<MipsSubtarget>(); if (Subtarget.isLinux()) return false; // Only global variables, not functions. const GlobalVariable *GVA = dyn_cast<GlobalVariable>(GV); if (!GVA) return false; // We can only do this for datarel or BSS objects for now. if (!Kind.isBSS() && !Kind.isDataRel()) return false; // If this is a internal constant string, there is a special // section for it, but not in small data/bss. if (Kind.isMergeable1ByteCString()) return false; const Type *Ty = GV->getType()->getElementType(); return IsInSmallSection(TM.getTargetData()->getTypeAllocSize(Ty)); }
TargetAsmInfo::TargetAsmInfo(const TargetMachine &TM) { TLOF = &TM.getTargetLowering()->getObjFileLowering(); const TargetData &TD = *TM.getTargetData(); IsLittleEndian = TD.isLittleEndian(); PointerSize = TD.getPointerSize(); const TargetFrameInfo &TFI = *TM.getFrameInfo(); StackDir = TFI.getStackGrowthDirection(); TRI = TM.getRegisterInfo(); TFI.getInitialFrameState(InitialFrameState); }
// stolen from LDC and modified // based on llc (from LLVM) code, University of Illinois Open Source License int LLVMWriteNativeAsmToFile(LLVMTargetMachineRef TMRef, LLVMModuleRef MRef, const char* filename, int opt, int pic) { TargetMachine* TM = unwrap(TMRef); Module* M = unwrap(MRef); TargetMachine::setRelocationModel(pic ? Reloc::PIC_ : Reloc::Default); #if 0 printf("trying to write native asm for target: %s\n", TM->getTarget().getName()); #endif std::string Err; // Build up all of the passes that we want to do to the module. FunctionPassManager Passes(M); // Add TargetData if (const TargetData *TD = TM->getTargetData()) Passes.add(new TargetData(*TD)); else assert(0); // Passes.add(new TargetData(M)); // debug info doesn't work properly with OptLevel != None! CodeGenOpt::Level OLvl = CodeGenOpt::Default; if (opt) OLvl = CodeGenOpt::Aggressive; else OLvl = CodeGenOpt::None; // open output file raw_fd_ostream out(filename, Err, raw_fd_ostream::F_Binary); assert(Err.empty()); // add codegen passes formatted_raw_ostream fout(out); bool error = TM->addPassesToEmitFile(Passes, fout, TargetMachine::CGFT_AssemblyFile, OLvl); assert(error == false); // Target does not support generation of this file type! Passes.doInitialization(); // Run our queue of passes all at once now, efficiently. for (llvm::Module::iterator I = M->begin(), E = M->end(); I != E; ++I) if (!I->isDeclaration()) Passes.run(*I); Passes.doFinalization(); fout.flush(); return 1; }
int64_t TartGCPrinter::toInt(llvm::Constant * c, TargetMachine & tm) { if (llvm::ConstantExpr * ce = dyn_cast<llvm::ConstantExpr>(c)) { c = ConstantFoldConstantExpression(ce, tm.getTargetData()); if (c == ce) { ce->dump(); assert(false && "Constant could not be folded"); } return toInt(c, tm); } else if (ConstantInt * ci = dyn_cast<ConstantInt>(c)) { return ci->getValue().getSExtValue(); } else { c->dump(); assert(false && "Constant offset is not an integer expression"); } }
LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M, char* Filename, LLVMCodeGenFileType codegen, char** ErrorMessage) { TargetMachine* TM = unwrap(T); Module* Mod = unwrap(M); PassManager pass; std::string error; const TargetData* td = TM->getTargetData(); if (!td) { error = "No TargetData in TargetMachine"; *ErrorMessage = strdup(error.c_str()); return true; } pass.add(new TargetData(*td)); TargetMachine::CodeGenFileType ft; switch (codegen) { case LLVMAssemblyFile: ft = TargetMachine::CGFT_AssemblyFile; break; default: ft = TargetMachine::CGFT_ObjectFile; break; } raw_fd_ostream dest(Filename, error, raw_fd_ostream::F_Binary); formatted_raw_ostream destf(dest); if (!error.empty()) { *ErrorMessage = strdup(error.c_str()); return true; } if (TM->addPassesToEmitFile(pass, destf, ft)) { error = "No TargetData in TargetMachine"; *ErrorMessage = strdup(error.c_str()); return true; } pass.run(*Mod); destf.flush(); dest.flush(); return false; }
MachineFunction::MachineFunction(const Function *F, const TargetMachine &TM, unsigned FunctionNum, MachineModuleInfo &mmi) : Fn(F), Target(TM), Ctx(mmi.getContext()), MMI(mmi) { if (TM.getRegisterInfo()) RegInfo = new (Allocator) MachineRegisterInfo(*TM.getRegisterInfo()); else RegInfo = 0; MFInfo = 0; FrameInfo = new (Allocator) MachineFrameInfo(*TM.getFrameInfo()); if (Fn->hasFnAttr(Attribute::StackAlignment)) FrameInfo->setMaxAlignment(Attribute::getStackAlignmentFromAttrs( Fn->getAttributes().getFnAttributes())); ConstantPool = new (Allocator) MachineConstantPool(TM.getTargetData()); Alignment = TM.getTargetLowering()->getFunctionAlignment(F); FunctionNumber = FunctionNum; JumpTableInfo = 0; }
MachineFunction::MachineFunction(const Function *F, const TargetMachine &TM, unsigned FunctionNum, MachineModuleInfo &mmi, GCModuleInfo* gmi) : Fn(F), Target(TM), Ctx(mmi.getContext()), MMI(mmi), GMI(gmi) { if (TM.getRegisterInfo()) RegInfo = new (Allocator) MachineRegisterInfo(*TM.getRegisterInfo()); else RegInfo = 0; MFInfo = 0; FrameInfo = new (Allocator) MachineFrameInfo(*TM.getFrameLowering()); if (Fn->hasFnAttr(Attribute::StackAlignment)) FrameInfo->setMaxAlignment(Attribute::getStackAlignmentFromAttrs( Fn->getAttributes().getFnAttributes())); ConstantPool = new (Allocator) MachineConstantPool(TM.getTargetData()); Alignment = TM.getTargetLowering()->getMinFunctionAlignment(); // FIXME: Shouldn't use pref alignment if explicit alignment is set on Fn. if (!Fn->hasFnAttr(Attribute::OptimizeForSize)) Alignment = std::max(Alignment, TM.getTargetLowering()->getPrefFunctionAlignment()); FunctionNumber = FunctionNum; JumpTableInfo = 0; }
T3RASELFWriterInfo::T3RASELFWriterInfo(TargetMachine &TM) : TargetELFWriterInfo(TM.getTargetData()->getPointerSizeInBits() == 64, TM.getTargetData()->isLittleEndian()) { }
/// getKindForGlobal - This is a top-level target-independent classifier for /// a global variable. Given an global variable and information from TM, it /// classifies the global in a variety of ways that make various target /// implementations simpler. The target implementation is free to ignore this /// extra info of course. SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalValue *GV, const TargetMachine &TM){ assert(!GV->isDeclaration() && !GV->hasAvailableExternallyLinkage() && "Can only be used for global definitions"); Reloc::Model ReloModel = TM.getRelocationModel(); // Early exit - functions should be always in text sections. const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV); if (GVar == 0) return SectionKind::getText(); // Handle thread-local data first. if (GVar->isThreadLocal()) { if (isSuitableForBSS(GVar)) return SectionKind::getThreadBSS(); return SectionKind::getThreadData(); } // Variables with common linkage always get classified as common. if (GVar->hasCommonLinkage()) return SectionKind::getCommon(); // Variable can be easily put to BSS section. if (isSuitableForBSS(GVar)) { if (GVar->hasLocalLinkage()) return SectionKind::getBSSLocal(); else if (GVar->hasExternalLinkage()) return SectionKind::getBSSExtern(); return SectionKind::getBSS(); } Constant *C = GVar->getInitializer(); // If the global is marked constant, we can put it into a mergable section, // a mergable string section, or general .data if it contains relocations. if (GVar->isConstant()) { // If the initializer for the global contains something that requires a // relocation, then we may have to drop this into a wriable data section // even though it is marked const. switch (C->getRelocationInfo()) { default: assert(0 && "unknown relocation info kind"); case Constant::NoRelocation: // If initializer is a null-terminated string, put it in a "cstring" // section of the right width. if (const ArrayType *ATy = dyn_cast<ArrayType>(C->getType())) { if (const IntegerType *ITy = dyn_cast<IntegerType>(ATy->getElementType())) { if ((ITy->getBitWidth() == 8 || ITy->getBitWidth() == 16 || ITy->getBitWidth() == 32) && IsNullTerminatedString(C)) { if (ITy->getBitWidth() == 8) return SectionKind::getMergeable1ByteCString(); if (ITy->getBitWidth() == 16) return SectionKind::getMergeable2ByteCString(); assert(ITy->getBitWidth() == 32 && "Unknown width"); return SectionKind::getMergeable4ByteCString(); } } } // Otherwise, just drop it into a mergable constant section. If we have // a section for this size, use it, otherwise use the arbitrary sized // mergable section. switch (TM.getTargetData()->getTypeAllocSize(C->getType())) { case 4: return SectionKind::getMergeableConst4(); case 8: return SectionKind::getMergeableConst8(); case 16: return SectionKind::getMergeableConst16(); default: return SectionKind::getMergeableConst(); } case Constant::LocalRelocation: // In static relocation model, the linker will resolve all addresses, so // the relocation entries will actually be constants by the time the app // starts up. However, we can't put this into a mergable section, because // the linker doesn't take relocations into consideration when it tries to // merge entries in the section. if (ReloModel == Reloc::Static) return SectionKind::getReadOnly(); // Otherwise, the dynamic linker needs to fix it up, put it in the // writable data.rel.local section. return SectionKind::getReadOnlyWithRelLocal(); case Constant::GlobalRelocations: // In static relocation model, the linker will resolve all addresses, so // the relocation entries will actually be constants by the time the app // starts up. However, we can't put this into a mergable section, because // the linker doesn't take relocations into consideration when it tries to // merge entries in the section. if (ReloModel == Reloc::Static) return SectionKind::getReadOnly(); // Otherwise, the dynamic linker needs to fix it up, put it in the // writable data.rel section. return SectionKind::getReadOnlyWithRel(); } } // Okay, this isn't a constant. If the initializer for the global is going // to require a runtime relocation by the dynamic linker, put it into a more // specific section to improve startup time of the app. This coalesces these // globals together onto fewer pages, improving the locality of the dynamic // linker. if (ReloModel == Reloc::Static) return SectionKind::getDataNoRel(); switch (C->getRelocationInfo()) { default: assert(0 && "unknown relocation info kind"); case Constant::NoRelocation: return SectionKind::getDataNoRel(); case Constant::LocalRelocation: return SectionKind::getDataRelLocal(); case Constant::GlobalRelocations: return SectionKind::getDataRel(); } }
TargetSelectionDAGInfo::TargetSelectionDAGInfo(const TargetMachine &TM) : TD(TM.getTargetData()) { }