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);
}
Ejemplo n.º 2
0
/// 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));
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
// 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;
}
Ejemplo n.º 5
0
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");
    }
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
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()) {
}