Ejemplo n.º 1
0
/// Canonicalize whitespaces in the input file. Line endings are replaced
/// with UNIX-style '\n'.
///
/// \param PreserveHorizontal Don't squash consecutive horizontal whitespace
/// characters to a single space.
static MemoryBuffer *CanonicalizeInputFile(MemoryBuffer *MB,
                                           bool PreserveHorizontal) {
  SmallString<128> NewFile;
  NewFile.reserve(MB->getBufferSize());

  for (const char *Ptr = MB->getBufferStart(), *End = MB->getBufferEnd();
       Ptr != End; ++Ptr) {
    // Eliminate trailing dosish \r.
    if (Ptr <= End - 2 && Ptr[0] == '\r' && Ptr[1] == '\n') {
      continue;
    }

    // If current char is not a horizontal whitespace or if horizontal 
    // whitespace canonicalization is disabled, dump it to output as is.
    if (PreserveHorizontal || (*Ptr != ' ' && *Ptr != '\t')) {
      NewFile.push_back(*Ptr);
      continue;
    }

    // Otherwise, add one space and advance over neighboring space.
    NewFile.push_back(' ');
    while (Ptr+1 != End &&
           (Ptr[1] == ' ' || Ptr[1] == '\t'))
      ++Ptr;
  }

  // Free the old buffer and return a new one.
  MemoryBuffer *MB2 =
    MemoryBuffer::getMemBufferCopy(NewFile.str(), MB->getBufferIdentifier());

  delete MB;
  return MB2;
}
Ejemplo n.º 2
0
/// CanonicalizeInputFile - Remove duplicate horizontal space from the specified
/// memory buffer, free it, and return a new one.
static MemoryBuffer *CanonicalizeInputFile(MemoryBuffer *MB) {
  SmallString<128> NewFile;
  NewFile.reserve(MB->getBufferSize());

  for (const char *Ptr = MB->getBufferStart(), *End = MB->getBufferEnd();
       Ptr != End; ++Ptr) {
    // If C is not a horizontal whitespace, skip it.
    if (*Ptr != ' ' && *Ptr != '\t') {
      NewFile.push_back(*Ptr);
      continue;
    }

    // Otherwise, add one space and advance over neighboring space.
    NewFile.push_back(' ');
    while (Ptr+1 != End &&
           (Ptr[1] == ' ' || Ptr[1] == '\t'))
      ++Ptr;
  }

  // Free the old buffer and return a new one.
  MemoryBuffer *MB2 =
    MemoryBuffer::getMemBufferCopy(NewFile.str(), MB->getBufferIdentifier());

  delete MB;
  return MB2;
}
Ejemplo n.º 3
0
const X86Subtarget *
X86TargetMachine::getSubtargetImpl(const Function &F) const {
  Attribute CPUAttr = F.getFnAttribute("target-cpu");
  Attribute FSAttr = F.getFnAttribute("target-features");

  StringRef CPU = !CPUAttr.hasAttribute(Attribute::None)
                      ? CPUAttr.getValueAsString()
                      : (StringRef)TargetCPU;
  StringRef FS = !FSAttr.hasAttribute(Attribute::None)
                     ? FSAttr.getValueAsString()
                     : (StringRef)TargetFS;

  SmallString<512> Key;
  Key.reserve(CPU.size() + FS.size());
  Key += CPU;
  Key += FS;

  // FIXME: This is related to the code below to reset the target options,
  // we need to know whether or not the soft float flag is set on the
  // function before we can generate a subtarget. We also need to use
  // it as a key for the subtarget since that can be the only difference
  // between two functions.
  bool SoftFloat =
      F.getFnAttribute("use-soft-float").getValueAsString() == "true";
  // If the soft float attribute is set on the function turn on the soft float
  // subtarget feature.
  if (SoftFloat)
    Key += FS.empty() ? "+soft-float" : ",+soft-float";

  FS = Key.substr(CPU.size());

  auto &I = SubtargetMap[Key];
  if (!I) {
    // This needs to be done before we create a new subtarget since any
    // creation will depend on the TM and the code generation flags on the
    // function that reside in TargetOptions.
    resetTargetOptions(F);
    I = llvm::make_unique<X86Subtarget>(TargetTriple, CPU, FS, *this,
                                        Options.StackAlignmentOverride);
#ifndef LLVM_BUILD_GLOBAL_ISEL
    GISelAccessor *GISel = new GISelAccessor();
#else
    X86GISelActualAccessor *GISel = new X86GISelActualAccessor();

    GISel->CallLoweringInfo.reset(new X86CallLowering(*I->getTargetLowering()));
    GISel->Legalizer.reset(new X86LegalizerInfo(*I, *this));

    auto *RBI = new X86RegisterBankInfo(*I->getRegisterInfo());
    GISel->RegBankInfo.reset(RBI);
    GISel->InstSelector.reset(createX86InstructionSelector(
        *this, *I, *RBI));
#endif
    I->setGISelAccessor(*GISel);
  }
  return I.get();
}
Ejemplo n.º 4
0
void LTOCodeGenerator::applyScopeRestrictions() {
  if (ScopeRestrictionsDone)
    return;

  // Declare a callback for the internalize pass that will ask for every
  // candidate GlobalValue if it can be internalized or not.
  SmallString<64> MangledName;
  auto mustPreserveGV = [&](const GlobalValue &GV) -> bool {
    // Unnamed globals can't be mangled, but they can't be preserved either.
    if (!GV.hasName())
      return false;

    // Need to mangle the GV as the "MustPreserveSymbols" StringSet is filled
    // with the linker supplied name, which on Darwin includes a leading
    // underscore.
    MangledName.clear();
    MangledName.reserve(GV.getName().size() + 1);
    Mangler::getNameWithPrefix(MangledName, GV.getName(),
                               MergedModule->getDataLayout());
    return MustPreserveSymbols.count(MangledName);
  };

  // Preserve linkonce value on linker request
  preserveDiscardableGVs(*MergedModule, mustPreserveGV);

  if (!ShouldInternalize)
    return;

  if (ShouldRestoreGlobalsLinkage) {
    // Record the linkage type of non-local symbols so they can be restored
    // prior
    // to module splitting.
    auto RecordLinkage = [&](const GlobalValue &GV) {
      if (!GV.hasAvailableExternallyLinkage() && !GV.hasLocalLinkage() &&
          GV.hasName())
        ExternalSymbols.insert(std::make_pair(GV.getName(), GV.getLinkage()));
    };
    for (auto &GV : *MergedModule)
      RecordLinkage(GV);
    for (auto &GV : MergedModule->globals())
      RecordLinkage(GV);
    for (auto &GV : MergedModule->aliases())
      RecordLinkage(GV);
  }

  // Update the llvm.compiler_used globals to force preserving libcalls and
  // symbols referenced from asm
  updateCompilerUsed(*MergedModule, *TargetMach, AsmUndefinedRefs);

  internalizeModule(*MergedModule, mustPreserveGV);

  ScopeRestrictionsDone = true;
}
Ejemplo n.º 5
0
static ErrorOr<std::unique_ptr<MemoryBuffer>>
getMemoryBufferForStream(int FD, const Twine &BufferName) {
  const ssize_t ChunkSize = 4096*4;
  SmallString<ChunkSize> Buffer;
  ssize_t ReadBytes;
  // Read into Buffer until we hit EOF.
  do {
    Buffer.reserve(Buffer.size() + ChunkSize);
    ReadBytes = read(FD, Buffer.end(), ChunkSize);
    if (ReadBytes == -1) {
      if (errno == EINTR) continue;
      return std::error_code(errno, std::generic_category());
    }
    Buffer.set_size(Buffer.size() + ReadBytes);
  } while (ReadBytes != 0);

  return MemoryBuffer::getMemBufferCopy(Buffer, BufferName);
}
Ejemplo n.º 6
0
const X86Subtarget *
X86TargetMachine::getSubtargetImpl(const Function &F) const {
  Attribute CPUAttr = F.getFnAttribute("target-cpu");
  Attribute FSAttr = F.getFnAttribute("target-features");

  StringRef CPU = !CPUAttr.hasAttribute(Attribute::None)
                      ? CPUAttr.getValueAsString()
                      : (StringRef)TargetCPU;
  StringRef FS = !FSAttr.hasAttribute(Attribute::None)
                     ? FSAttr.getValueAsString()
                     : (StringRef)TargetFS;

  SmallString<512> Key;
  Key.reserve(CPU.size() + FS.size());
  Key += CPU;
  Key += FS;

  // FIXME: This is related to the code below to reset the target options,
  // we need to know whether or not the soft float flag is set on the
  // function before we can generate a subtarget. We also need to use
  // it as a key for the subtarget since that can be the only difference
  // between two functions.
  bool SoftFloat =
      F.getFnAttribute("use-soft-float").getValueAsString() == "true";
  // If the soft float attribute is set on the function turn on the soft float
  // subtarget feature.
  if (SoftFloat)
    Key += FS.empty() ? "+soft-float" : ",+soft-float";

  FS = Key.substr(CPU.size());

  auto &I = SubtargetMap[Key];
  if (!I) {
    // This needs to be done before we create a new subtarget since any
    // creation will depend on the TM and the code generation flags on the
    // function that reside in TargetOptions.
    resetTargetOptions(F);
    I = llvm::make_unique<X86Subtarget>(TargetTriple, CPU, FS, *this,
                                        Options.StackAlignmentOverride);
  }
  return I.get();
}
Ejemplo n.º 7
0
static error_code getMemoryBufferForStream(int FD,
                                           StringRef BufferName,
                                           std::unique_ptr<MemoryBuffer> &Result) {
  const ssize_t ChunkSize = 4096*4;
  SmallString<ChunkSize> Buffer;
  ssize_t ReadBytes;
  // Read into Buffer until we hit EOF.
  do {
    Buffer.reserve(Buffer.size() + ChunkSize);
    ReadBytes = read(FD, Buffer.end(), ChunkSize);
    if (ReadBytes == -1) {
      if (errno == EINTR) continue;
      return error_code(errno, posix_category());
    }
    Buffer.set_size(Buffer.size() + ReadBytes);
  } while (ReadBytes != 0);

  Result.reset(MemoryBuffer::getMemBufferCopy(Buffer, BufferName));
  return error_code::success();
}
Ejemplo n.º 8
0
error_code MemoryBuffer::getSTDIN(OwningPtr<MemoryBuffer> &result) {
  // Read in all of the data from stdin, we cannot mmap stdin.
  //
  // FIXME: That isn't necessarily true, we should try to mmap stdin and
  // fallback if it fails.
  sys::Program::ChangeStdinToBinary();

  const ssize_t ChunkSize = 4096*4;
  SmallString<ChunkSize> Buffer;
  ssize_t ReadBytes;
  // Read into Buffer until we hit EOF.
  do {
    Buffer.reserve(Buffer.size() + ChunkSize);
    ReadBytes = read(0, Buffer.end(), ChunkSize);
    if (ReadBytes == -1) {
      if (errno == EINTR) continue;
      return error_code(errno, posix_category());
    }
    Buffer.set_size(Buffer.size() + ReadBytes);
  } while (ReadBytes != 0);

  result.reset(getMemBufferCopy(Buffer, "<stdin>"));
  return error_code::success();
}
Ejemplo n.º 9
0
const X86Subtarget *
X86TargetMachine::getSubtargetImpl(const Function &F) const {
  Attribute CPUAttr = F.getFnAttribute("target-cpu");
  Attribute FSAttr = F.getFnAttribute("target-features");

  StringRef CPU = !CPUAttr.hasAttribute(Attribute::None)
                      ? CPUAttr.getValueAsString()
                      : (StringRef)TargetCPU;
  StringRef FS = !FSAttr.hasAttribute(Attribute::None)
                     ? FSAttr.getValueAsString()
                     : (StringRef)TargetFS;

  SmallString<512> Key;
  Key.reserve(CPU.size() + FS.size());
  Key += CPU;
  Key += FS;

  // FIXME: This is related to the code below to reset the target options,
  // we need to know whether or not the soft float flag is set on the
  // function before we can generate a subtarget. We also need to use
  // it as a key for the subtarget since that can be the only difference
  // between two functions.
  bool SoftFloat =
      F.getFnAttribute("use-soft-float").getValueAsString() == "true";
  // If the soft float attribute is set on the function turn on the soft float
  // subtarget feature.
  if (SoftFloat)
    Key += FS.empty() ? "+soft-float" : ",+soft-float";

  // Keep track of the key width after all features are added so we can extract
  // the feature string out later.
  unsigned CPUFSWidth = Key.size();

  // Extract prefer-vector-width attribute.
  unsigned PreferVectorWidthOverride = 0;
  if (F.hasFnAttribute("prefer-vector-width")) {
    StringRef Val = F.getFnAttribute("prefer-vector-width").getValueAsString();
    unsigned Width;
    if (!Val.getAsInteger(0, Width)) {
      Key += ",prefer-vector-width=";
      Key += Val;
      PreferVectorWidthOverride = Width;
    }
  }

  // Extract min-legal-vector-width attribute.
  unsigned RequiredVectorWidth = UINT32_MAX;
  if (F.hasFnAttribute("min-legal-vector-width")) {
    StringRef Val =
        F.getFnAttribute("min-legal-vector-width").getValueAsString();
    unsigned Width;
    if (!Val.getAsInteger(0, Width)) {
      Key += ",min-legal-vector-width=";
      Key += Val;
      RequiredVectorWidth = Width;
    }
  }

  // Extracted here so that we make sure there is backing for the StringRef. If
  // we assigned earlier, its possible the SmallString reallocated leaving a
  // dangling StringRef.
  FS = Key.slice(CPU.size(), CPUFSWidth);

  auto &I = SubtargetMap[Key];
  if (!I) {
    // This needs to be done before we create a new subtarget since any
    // creation will depend on the TM and the code generation flags on the
    // function that reside in TargetOptions.
    resetTargetOptions(F);
    I = llvm::make_unique<X86Subtarget>(TargetTriple, CPU, FS, *this,
                                        Options.StackAlignmentOverride,
                                        PreferVectorWidthOverride,
                                        RequiredVectorWidth);
  }
  return I.get();
}
Ejemplo n.º 10
0
void RecordStreamer::flushSymverDirectives() {
  // Mapping from mangled name to GV.
  StringMap<const GlobalValue *> MangledNameMap;
  // The name in the assembler will be mangled, but the name in the IR
  // might not, so we first compute a mapping from mangled name to GV.
  Mangler Mang;
  SmallString<64> MangledName;
  for (const GlobalValue &GV : M.global_values()) {
    if (!GV.hasName())
      continue;
    MangledName.clear();
    MangledName.reserve(GV.getName().size() + 1);
    Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false);
    MangledNameMap[MangledName] = &GV;
  }

  // Walk all the recorded .symver aliases, and set up the binding
  // for each alias.
  for (auto &Symver : SymverAliasMap) {
    const MCSymbol *Aliasee = Symver.first;
    MCSymbolAttr Attr = MCSA_Invalid;
    bool IsDefined = false;

    // First check if the aliasee binding was recorded in the asm.
    RecordStreamer::State state = getSymbolState(Aliasee);
    switch (state) {
    case RecordStreamer::Global:
    case RecordStreamer::DefinedGlobal:
      Attr = MCSA_Global;
      break;
    case RecordStreamer::UndefinedWeak:
    case RecordStreamer::DefinedWeak:
      Attr = MCSA_Weak;
      break;
    default:
      break;
    }

    switch (state) {
    case RecordStreamer::Defined:
    case RecordStreamer::DefinedGlobal:
    case RecordStreamer::DefinedWeak:
      IsDefined = true;
      break;
    case RecordStreamer::NeverSeen:
    case RecordStreamer::Global:
    case RecordStreamer::Used:
    case RecordStreamer::UndefinedWeak:
      break;
    }

    if (Attr == MCSA_Invalid || !IsDefined) {
      const GlobalValue *GV = M.getNamedValue(Aliasee->getName());
      if (!GV) {
        auto MI = MangledNameMap.find(Aliasee->getName());
        if (MI != MangledNameMap.end())
          GV = MI->second;
      }
      if (GV) {
        // If we don't have a symbol attribute from assembly, then check if
        // the aliasee was defined in the IR.
        if (Attr == MCSA_Invalid) {
          if (GV->hasExternalLinkage())
            Attr = MCSA_Global;
          else if (GV->hasLocalLinkage())
            Attr = MCSA_Local;
          else if (GV->isWeakForLinker())
            Attr = MCSA_Weak;
        }
        IsDefined = IsDefined || !GV->isDeclarationForLinker();
      }
    }

    // Set the detected binding on each alias with this aliasee.
    for (auto AliasName : Symver.second) {
      std::pair<StringRef, StringRef> Split = AliasName.split("@@@");
      SmallString<128> NewName;
      if (!Split.second.empty() && !Split.second.startswith("@")) {
        // Special processing for "@@@" according
        // https://sourceware.org/binutils/docs/as/Symver.html
        const char *Separator = IsDefined ? "@@" : "@";
        AliasName =
            (Split.first + Separator + Split.second).toStringRef(NewName);
      }
      MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
      // TODO: Handle "@@@". Depending on SymbolAttribute value it needs to be
      // converted into @ or @@.
      const MCExpr *Value = MCSymbolRefExpr::create(Aliasee, getContext());
      if (IsDefined)
        markDefined(*Alias);
      // Don't use EmitAssignment override as it always marks alias as defined.
      MCStreamer::EmitAssignment(Alias, Value);
      if (Attr != MCSA_Invalid)
        EmitSymbolAttribute(Alias, Attr);
    }
  }
}
Ejemplo n.º 11
0
// Ensure ELF .symver aliases get the same binding as the defined symbol
// they alias with.
static void handleSymverAliases(const Module &M, RecordStreamer &Streamer) {
  if (Streamer.symverAliases().empty())
    return;

  // The name in the assembler will be mangled, but the name in the IR
  // might not, so we first compute a mapping from mangled name to GV.
  Mangler Mang;
  SmallString<64> MangledName;
  StringMap<const GlobalValue *> MangledNameMap;
  auto GetMangledName = [&](const GlobalValue &GV) {
    if (!GV.hasName())
      return;

    MangledName.clear();
    MangledName.reserve(GV.getName().size() + 1);
    Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false);
    MangledNameMap[MangledName] = &GV;
  };
  for (const Function &F : M)
    GetMangledName(F);
  for (const GlobalVariable &GV : M.globals())
    GetMangledName(GV);
  for (const GlobalAlias &GA : M.aliases())
    GetMangledName(GA);

  // Walk all the recorded .symver aliases, and set up the binding
  // for each alias.
  for (auto &Symver : Streamer.symverAliases()) {
    const MCSymbol *Aliasee = Symver.first;
    MCSymbolAttr Attr = MCSA_Invalid;

    // First check if the aliasee binding was recorded in the asm.
    RecordStreamer::State state = Streamer.getSymbolState(Aliasee);
    switch (state) {
    case RecordStreamer::Global:
    case RecordStreamer::DefinedGlobal:
      Attr = MCSA_Global;
      break;
    case RecordStreamer::UndefinedWeak:
    case RecordStreamer::DefinedWeak:
      Attr = MCSA_Weak;
      break;
    default:
      break;
    }

    // If we don't have a symbol attribute from assembly, then check if
    // the aliasee was defined in the IR.
    if (Attr == MCSA_Invalid) {
      const auto *GV = M.getNamedValue(Aliasee->getName());
      if (!GV) {
        auto MI = MangledNameMap.find(Aliasee->getName());
        if (MI != MangledNameMap.end())
          GV = MI->second;
        else
          continue;
      }
      if (GV->hasExternalLinkage())
        Attr = MCSA_Global;
      else if (GV->hasLocalLinkage())
        Attr = MCSA_Local;
      else if (GV->isWeakForLinker())
        Attr = MCSA_Weak;
    }
    if (Attr == MCSA_Invalid)
      continue;

    // Set the detected binding on each alias with this aliasee.
    for (auto &Alias : Symver.second)
      Streamer.EmitSymbolAttribute(Alias, Attr);
  }
}