Esempio n. 1
0
bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
  auto It = Functions.find(MF.getName());
  if (It == Functions.end())
    return error(Twine("no machine function information for function '") +
                 MF.getName() + "' in the MIR file");
  // TODO: Recreate the machine function.
  const yaml::MachineFunction &YamlMF = *It->getValue();
  if (YamlMF.Alignment)
    MF.setAlignment(YamlMF.Alignment);
  MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);
  MF.setHasInlineAsm(YamlMF.HasInlineAsm);
  if (YamlMF.AllVRegsAllocated)
    MF.getProperties().set(MachineFunctionProperties::Property::AllVRegsAllocated);
  PerFunctionMIParsingState PFS;
  if (initializeRegisterInfo(MF, YamlMF, PFS))
    return true;
  if (!YamlMF.Constants.empty()) {
    auto *ConstantPool = MF.getConstantPool();
    assert(ConstantPool && "Constant pool must be created");
    if (initializeConstantPool(*ConstantPool, YamlMF, MF,
                               PFS.ConstantPoolSlots))
      return true;
  }

  SMDiagnostic Error;
  if (parseMachineBasicBlockDefinitions(MF, YamlMF.Body.Value.Value, PFS,
                                        IRSlots, Error)) {
    reportDiagnostic(
        diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
    return true;
  }

  if (MF.empty())
    return error(Twine("machine function '") + Twine(MF.getName()) +
                 "' requires at least one machine basic block in its body");
  // Initialize the frame information after creating all the MBBs so that the
  // MBB references in the frame information can be resolved.
  if (initializeFrameInfo(MF, YamlMF, PFS))
    return true;
  // Initialize the jump table after creating all the MBBs so that the MBB
  // references can be resolved.
  if (!YamlMF.JumpTableInfo.Entries.empty() &&
      initializeJumpTableInfo(MF, YamlMF.JumpTableInfo, PFS))
    return true;
  // Parse the machine instructions after creating all of the MBBs so that the
  // parser can resolve the MBB references.
  if (parseMachineInstructions(MF, YamlMF.Body.Value.Value, PFS, IRSlots,
                               Error)) {
    reportDiagnostic(
        diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
    return true;
  }
  inferRegisterInfo(MF, YamlMF);
  // FIXME: This is a temporary workaround until the reserved registers can be
  // serialized.
  MF.getRegInfo().freezeReservedRegs(MF);
  MF.verify();
  return false;
}
Esempio n. 2
0
bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
  auto It = Functions.find(MF.getName());
  if (It == Functions.end())
    return error(Twine("no machine function information for function '") +
                 MF.getName() + "' in the MIR file");
  // TODO: Recreate the machine function.
  const yaml::MachineFunction &YamlMF = *It->getValue();
  if (YamlMF.Alignment)
    MF.setAlignment(YamlMF.Alignment);
  MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);
  MF.setHasInlineAsm(YamlMF.HasInlineAsm);
  PerFunctionMIParsingState PFS;
  if (initializeRegisterInfo(MF, MF.getRegInfo(), YamlMF,
                             PFS.VirtualRegisterSlots))
    return true;
  if (initializeFrameInfo(*MF.getFunction(), *MF.getFrameInfo(), YamlMF,
                          PFS.StackObjectSlots, PFS.FixedStackObjectSlots))
    return true;

  const auto &F = *MF.getFunction();
  for (const auto &YamlMBB : YamlMF.BasicBlocks) {
    const BasicBlock *BB = nullptr;
    const yaml::StringValue &Name = YamlMBB.Name;
    if (!Name.Value.empty()) {
      BB = dyn_cast_or_null<BasicBlock>(
          F.getValueSymbolTable().lookup(Name.Value));
      if (!BB)
        return error(Name.SourceRange.Start,
                     Twine("basic block '") + Name.Value +
                         "' is not defined in the function '" + MF.getName() +
                         "'");
    }
    auto *MBB = MF.CreateMachineBasicBlock(BB);
    MF.insert(MF.end(), MBB);
    bool WasInserted =
        PFS.MBBSlots.insert(std::make_pair(YamlMBB.ID, MBB)).second;
    if (!WasInserted)
      return error(Twine("redefinition of machine basic block with id #") +
                   Twine(YamlMBB.ID));
  }

  if (YamlMF.BasicBlocks.empty())
    return error(Twine("machine function '") + Twine(MF.getName()) +
                 "' requires at least one machine basic block in its body");
  // Initialize the jump table after creating all the MBBs so that the MBB
  // references can be resolved.
  if (!YamlMF.JumpTableInfo.Entries.empty() &&
      initializeJumpTableInfo(MF, YamlMF.JumpTableInfo, PFS))
    return true;
  // Initialize the machine basic blocks after creating them all so that the
  // machine instructions parser can resolve the MBB references.
  unsigned I = 0;
  for (const auto &YamlMBB : YamlMF.BasicBlocks) {
    if (initializeMachineBasicBlock(MF, *MF.getBlockNumbered(I++), YamlMBB,
                                    PFS))
      return true;
  }
  return false;
}
Esempio n. 3
0
bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
  auto It = Functions.find(MF.getName());
  if (It == Functions.end())
    return error(Twine("no machine function information for function '") +
                 MF.getName() + "' in the MIR file");
  // TODO: Recreate the machine function.
  const yaml::MachineFunction &YamlMF = *It->getValue();
  if (YamlMF.Alignment)
    MF.setAlignment(YamlMF.Alignment);
  MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);
  MF.setHasInlineAsm(YamlMF.HasInlineAsm);
  if (initializeRegisterInfo(MF.getRegInfo(), YamlMF))
    return true;

  const auto &F = *MF.getFunction();
  DenseMap<unsigned, MachineBasicBlock *> MBBSlots;
  for (const auto &YamlMBB : YamlMF.BasicBlocks) {
    const BasicBlock *BB = nullptr;
    if (!YamlMBB.Name.empty()) {
      BB = dyn_cast_or_null<BasicBlock>(
          F.getValueSymbolTable().lookup(YamlMBB.Name));
      if (!BB)
        return error(Twine("basic block '") + YamlMBB.Name +
                     "' is not defined in the function '" + MF.getName() + "'");
    }
    auto *MBB = MF.CreateMachineBasicBlock(BB);
    MF.insert(MF.end(), MBB);
    bool WasInserted = MBBSlots.insert(std::make_pair(YamlMBB.ID, MBB)).second;
    if (!WasInserted)
      return error(Twine("redefinition of machine basic block with id #") +
                   Twine(YamlMBB.ID));
  }

  // Initialize the machine basic blocks after creating them all so that the
  // machine instructions parser can resolve the MBB references.
  unsigned I = 0;
  for (const auto &YamlMBB : YamlMF.BasicBlocks) {
    if (initializeMachineBasicBlock(MF, *MF.getBlockNumbered(I++), YamlMBB,
                                    MBBSlots))
      return true;
  }
  return false;
}
Esempio n. 4
0
bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
  auto It = Functions.find(MF.getName());
  if (It == Functions.end())
    return error(Twine("no machine function information for function '") +
                 MF.getName() + "' in the MIR file");
  // TODO: Recreate the machine function.
  const yaml::MachineFunction &YamlMF = *It->getValue();
  if (YamlMF.Alignment)
    MF.setAlignment(YamlMF.Alignment);
  MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);
  MF.setHasInlineAsm(YamlMF.HasInlineAsm);
  PerFunctionMIParsingState PFS;
  if (initializeRegisterInfo(MF, YamlMF, PFS))
    return true;
  if (!YamlMF.Constants.empty()) {
    auto *ConstantPool = MF.getConstantPool();
    assert(ConstantPool && "Constant pool must be created");
    if (initializeConstantPool(*ConstantPool, YamlMF, MF,
                               PFS.ConstantPoolSlots))
      return true;
  }

  const auto &F = *MF.getFunction();
  for (const auto &YamlMBB : YamlMF.BasicBlocks) {
    const BasicBlock *BB = nullptr;
    const yaml::StringValue &Name = YamlMBB.Name;
    const yaml::StringValue &IRBlock = YamlMBB.IRBlock;
    if (!Name.Value.empty()) {
      BB = dyn_cast_or_null<BasicBlock>(
          F.getValueSymbolTable().lookup(Name.Value));
      if (!BB)
        return error(Name.SourceRange.Start,
                     Twine("basic block '") + Name.Value +
                         "' is not defined in the function '" + MF.getName() +
                         "'");
    }
    if (!IRBlock.Value.empty()) {
      // TODO: Report an error when both name and ir block are specified.
      SMDiagnostic Error;
      if (parseIRBlockReference(BB, SM, MF, IRBlock.Value, PFS, IRSlots, Error))
        return error(Error, IRBlock.SourceRange);
    }
    auto *MBB = MF.CreateMachineBasicBlock(BB);
    MF.insert(MF.end(), MBB);
    bool WasInserted =
        PFS.MBBSlots.insert(std::make_pair(YamlMBB.ID, MBB)).second;
    if (!WasInserted)
      return error(Twine("redefinition of machine basic block with id #") +
                   Twine(YamlMBB.ID));
  }

  if (YamlMF.BasicBlocks.empty())
    return error(Twine("machine function '") + Twine(MF.getName()) +
                 "' requires at least one machine basic block in its body");
  // Initialize the frame information after creating all the MBBs so that the
  // MBB references in the frame information can be resolved.
  if (initializeFrameInfo(MF, YamlMF, PFS))
    return true;
  // Initialize the jump table after creating all the MBBs so that the MBB
  // references can be resolved.
  if (!YamlMF.JumpTableInfo.Entries.empty() &&
      initializeJumpTableInfo(MF, YamlMF.JumpTableInfo, PFS))
    return true;
  // Initialize the machine basic blocks after creating them all so that the
  // machine instructions parser can resolve the MBB references.
  unsigned I = 0;
  for (const auto &YamlMBB : YamlMF.BasicBlocks) {
    if (initializeMachineBasicBlock(MF, *MF.getBlockNumbered(I++), YamlMBB,
                                    PFS))
      return true;
  }
  // FIXME: This is a temporary workaround until the reserved registers can be
  // serialized.
  MF.getRegInfo().freezeReservedRegs(MF);
  MF.verify();
  return false;
}
Esempio n. 5
0
bool AMDGPUAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
  CurrentProgramInfo = SIProgramInfo();

  const AMDGPUMachineFunction *MFI = MF.getInfo<AMDGPUMachineFunction>();

  // The starting address of all shader programs must be 256 bytes aligned.
  // Regular functions just need the basic required instruction alignment.
  MF.setAlignment(MFI->isEntryFunction() ? 8 : 2);

  SetupMachineFunction(MF);

  const GCNSubtarget &STM = MF.getSubtarget<GCNSubtarget>();
  MCContext &Context = getObjFileLowering().getContext();
  // FIXME: This should be an explicit check for Mesa.
  if (!STM.isAmdHsaOS() && !STM.isAmdPalOS()) {
    MCSectionELF *ConfigSection =
        Context.getELFSection(".AMDGPU.config", ELF::SHT_PROGBITS, 0);
    OutStreamer->SwitchSection(ConfigSection);
  }

  if (MFI->isEntryFunction()) {
    getSIProgramInfo(CurrentProgramInfo, MF);
  } else {
    auto I = CallGraphResourceInfo.insert(
      std::make_pair(&MF.getFunction(), SIFunctionResourceInfo()));
    SIFunctionResourceInfo &Info = I.first->second;
    assert(I.second && "should only be called once per function");
    Info = analyzeResourceUsage(MF);
  }

  if (STM.isAmdPalOS())
    EmitPALMetadata(MF, CurrentProgramInfo);
  else if (!STM.isAmdHsaOS()) {
    EmitProgramInfoSI(MF, CurrentProgramInfo);
  }

  DisasmLines.clear();
  HexLines.clear();
  DisasmLineMaxLen = 0;

  EmitFunctionBody();

  if (isVerbose()) {
    MCSectionELF *CommentSection =
        Context.getELFSection(".AMDGPU.csdata", ELF::SHT_PROGBITS, 0);
    OutStreamer->SwitchSection(CommentSection);

    if (!MFI->isEntryFunction()) {
      OutStreamer->emitRawComment(" Function info:", false);
      SIFunctionResourceInfo &Info = CallGraphResourceInfo[&MF.getFunction()];
      emitCommonFunctionComments(
        Info.NumVGPR,
        Info.getTotalNumSGPRs(MF.getSubtarget<GCNSubtarget>()),
        Info.PrivateSegmentSize,
        getFunctionCodeSize(MF), MFI);
      return false;
    }

    OutStreamer->emitRawComment(" Kernel info:", false);
    emitCommonFunctionComments(CurrentProgramInfo.NumVGPR,
                               CurrentProgramInfo.NumSGPR,
                               CurrentProgramInfo.ScratchSize,
                               getFunctionCodeSize(MF), MFI);

    OutStreamer->emitRawComment(
      " FloatMode: " + Twine(CurrentProgramInfo.FloatMode), false);
    OutStreamer->emitRawComment(
      " IeeeMode: " + Twine(CurrentProgramInfo.IEEEMode), false);
    OutStreamer->emitRawComment(
      " LDSByteSize: " + Twine(CurrentProgramInfo.LDSSize) +
      " bytes/workgroup (compile time only)", false);

    OutStreamer->emitRawComment(
      " SGPRBlocks: " + Twine(CurrentProgramInfo.SGPRBlocks), false);
    OutStreamer->emitRawComment(
      " VGPRBlocks: " + Twine(CurrentProgramInfo.VGPRBlocks), false);

    OutStreamer->emitRawComment(
      " NumSGPRsForWavesPerEU: " +
      Twine(CurrentProgramInfo.NumSGPRsForWavesPerEU), false);
    OutStreamer->emitRawComment(
      " NumVGPRsForWavesPerEU: " +
      Twine(CurrentProgramInfo.NumVGPRsForWavesPerEU), false);

    OutStreamer->emitRawComment(
      " WaveLimiterHint : " + Twine(MFI->needsWaveLimiter()), false);

    if (MF.getSubtarget<GCNSubtarget>().debuggerEmitPrologue()) {
      OutStreamer->emitRawComment(
        " DebuggerWavefrontPrivateSegmentOffsetSGPR: s" +
        Twine(CurrentProgramInfo.DebuggerWavefrontPrivateSegmentOffsetSGPR), false);
      OutStreamer->emitRawComment(
        " DebuggerPrivateSegmentBufferSGPR: s" +
        Twine(CurrentProgramInfo.DebuggerPrivateSegmentBufferSGPR), false);
    }

    OutStreamer->emitRawComment(
      " COMPUTE_PGM_RSRC2:USER_SGPR: " +
      Twine(G_00B84C_USER_SGPR(CurrentProgramInfo.ComputePGMRSrc2)), false);
    OutStreamer->emitRawComment(
      " COMPUTE_PGM_RSRC2:TRAP_HANDLER: " +
      Twine(G_00B84C_TRAP_HANDLER(CurrentProgramInfo.ComputePGMRSrc2)), false);
    OutStreamer->emitRawComment(
      " COMPUTE_PGM_RSRC2:TGID_X_EN: " +
      Twine(G_00B84C_TGID_X_EN(CurrentProgramInfo.ComputePGMRSrc2)), false);
    OutStreamer->emitRawComment(
      " COMPUTE_PGM_RSRC2:TGID_Y_EN: " +
      Twine(G_00B84C_TGID_Y_EN(CurrentProgramInfo.ComputePGMRSrc2)), false);
    OutStreamer->emitRawComment(
      " COMPUTE_PGM_RSRC2:TGID_Z_EN: " +
      Twine(G_00B84C_TGID_Z_EN(CurrentProgramInfo.ComputePGMRSrc2)), false);
    OutStreamer->emitRawComment(
      " COMPUTE_PGM_RSRC2:TIDIG_COMP_CNT: " +
      Twine(G_00B84C_TIDIG_COMP_CNT(CurrentProgramInfo.ComputePGMRSrc2)),
      false);
  }

  if (STM.dumpCode()) {

    OutStreamer->SwitchSection(
        Context.getELFSection(".AMDGPU.disasm", ELF::SHT_NOTE, 0));

    for (size_t i = 0; i < DisasmLines.size(); ++i) {
      std::string Comment = "\n";
      if (!HexLines[i].empty()) {
        Comment = std::string(DisasmLineMaxLen - DisasmLines[i].size(), ' ');
        Comment += " ; " + HexLines[i] + "\n";
      }

      OutStreamer->EmitBytes(StringRef(DisasmLines[i]));
      OutStreamer->EmitBytes(StringRef(Comment));
    }
  }

  return false;
}
Esempio n. 6
0
bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
  auto It = Functions.find(MF.getName());
  if (It == Functions.end())
    return error(Twine("no machine function information for function '") +
                 MF.getName() + "' in the MIR file");
  // TODO: Recreate the machine function.
  const yaml::MachineFunction &YamlMF = *It->getValue();
  if (YamlMF.Alignment)
    MF.setAlignment(YamlMF.Alignment);
  MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);

  if (YamlMF.Legalized)
    MF.getProperties().set(MachineFunctionProperties::Property::Legalized);
  if (YamlMF.RegBankSelected)
    MF.getProperties().set(
        MachineFunctionProperties::Property::RegBankSelected);
  if (YamlMF.Selected)
    MF.getProperties().set(MachineFunctionProperties::Property::Selected);

  PerFunctionMIParsingState PFS(MF, SM, IRSlots);
  if (initializeRegisterInfo(PFS, YamlMF))
    return true;
  if (!YamlMF.Constants.empty()) {
    auto *ConstantPool = MF.getConstantPool();
    assert(ConstantPool && "Constant pool must be created");
    if (initializeConstantPool(PFS, *ConstantPool, YamlMF))
      return true;
  }

  StringRef BlockStr = YamlMF.Body.Value.Value;
  SMDiagnostic Error;
  SourceMgr BlockSM;
  BlockSM.AddNewSourceBuffer(
      MemoryBuffer::getMemBuffer(BlockStr, "",/*RequiresNullTerminator=*/false),
      SMLoc());
  PFS.SM = &BlockSM;
  if (parseMachineBasicBlockDefinitions(PFS, BlockStr, Error)) {
    reportDiagnostic(
        diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
    return true;
  }
  PFS.SM = &SM;

  if (MF.empty())
    return error(Twine("machine function '") + Twine(MF.getName()) +
                 "' requires at least one machine basic block in its body");
  // Initialize the frame information after creating all the MBBs so that the
  // MBB references in the frame information can be resolved.
  if (initializeFrameInfo(PFS, YamlMF))
    return true;
  // Initialize the jump table after creating all the MBBs so that the MBB
  // references can be resolved.
  if (!YamlMF.JumpTableInfo.Entries.empty() &&
      initializeJumpTableInfo(PFS, YamlMF.JumpTableInfo))
    return true;
  // Parse the machine instructions after creating all of the MBBs so that the
  // parser can resolve the MBB references.
  StringRef InsnStr = YamlMF.Body.Value.Value;
  SourceMgr InsnSM;
  InsnSM.AddNewSourceBuffer(
      MemoryBuffer::getMemBuffer(InsnStr, "", /*RequiresNullTerminator=*/false),
      SMLoc());
  PFS.SM = &InsnSM;
  if (parseMachineInstructions(PFS, InsnStr, Error)) {
    reportDiagnostic(
        diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
    return true;
  }
  PFS.SM = &SM;

  inferRegisterInfo(PFS, YamlMF);

  computeFunctionProperties(MF);

  // FIXME: This is a temporary workaround until the reserved registers can be
  // serialized.
  MF.getRegInfo().freezeReservedRegs(MF);
  MF.verify();
  return false;
}
Esempio n. 7
0
bool
MIRParserImpl::initializeMachineFunction(const yaml::MachineFunction &YamlMF,
                                         MachineFunction &MF) {
  // TODO: Recreate the machine function.
  initNames2RegClasses(MF);
  initNames2RegBanks(MF);
  if (YamlMF.Alignment)
    MF.setAlignment(YamlMF.Alignment);
  MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);

  if (YamlMF.Legalized)
    MF.getProperties().set(MachineFunctionProperties::Property::Legalized);
  if (YamlMF.RegBankSelected)
    MF.getProperties().set(
        MachineFunctionProperties::Property::RegBankSelected);
  if (YamlMF.Selected)
    MF.getProperties().set(MachineFunctionProperties::Property::Selected);

  PerFunctionMIParsingState PFS(MF, SM, IRSlots, Names2RegClasses,
                                Names2RegBanks);
  if (parseRegisterInfo(PFS, YamlMF))
    return true;
  if (!YamlMF.Constants.empty()) {
    auto *ConstantPool = MF.getConstantPool();
    assert(ConstantPool && "Constant pool must be created");
    if (initializeConstantPool(PFS, *ConstantPool, YamlMF))
      return true;
  }

  StringRef BlockStr = YamlMF.Body.Value.Value;
  SMDiagnostic Error;
  SourceMgr BlockSM;
  BlockSM.AddNewSourceBuffer(
      MemoryBuffer::getMemBuffer(BlockStr, "",/*RequiresNullTerminator=*/false),
      SMLoc());
  PFS.SM = &BlockSM;
  if (parseMachineBasicBlockDefinitions(PFS, BlockStr, Error)) {
    reportDiagnostic(
        diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
    return true;
  }
  PFS.SM = &SM;

  // Initialize the frame information after creating all the MBBs so that the
  // MBB references in the frame information can be resolved.
  if (initializeFrameInfo(PFS, YamlMF))
    return true;
  // Initialize the jump table after creating all the MBBs so that the MBB
  // references can be resolved.
  if (!YamlMF.JumpTableInfo.Entries.empty() &&
      initializeJumpTableInfo(PFS, YamlMF.JumpTableInfo))
    return true;
  // Parse the machine instructions after creating all of the MBBs so that the
  // parser can resolve the MBB references.
  StringRef InsnStr = YamlMF.Body.Value.Value;
  SourceMgr InsnSM;
  InsnSM.AddNewSourceBuffer(
      MemoryBuffer::getMemBuffer(InsnStr, "", /*RequiresNullTerminator=*/false),
      SMLoc());
  PFS.SM = &InsnSM;
  if (parseMachineInstructions(PFS, InsnStr, Error)) {
    reportDiagnostic(
        diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
    return true;
  }
  PFS.SM = &SM;

  if (setupRegisterInfo(PFS, YamlMF))
    return true;

  computeFunctionProperties(MF);

  MF.verify();
  return false;
}