LLVM学习笔记(44-2)

Posted wuhui_gdnt

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LLVM学习笔记(44-2)相关的知识,希望对你有一定的参考价值。

V7.0的变化——resolveSchedClass()等

V7.0在这里引入了相当剧烈的变化,因为x86也开始使用SchedVarSchedWriteVariant,以及SchedWriteVariantresolveSchedClass()开始有意义了。

1593  void SubtargetEmitter::EmitSchedModelHelpers(const std::string &ClassName,

1594                                               raw_ostream &OS)

1595    OS << "unsigned " << ClassName

1596       << "\\n::resolveSchedClass(unsigned SchedClass, const MachineInstr *MI,"

1597       << " const TargetSchedModel *SchedModel) const \\n";

1598 

1599    // Emit the predicate prolog code.

1600    emitPredicateProlog(Records, OS);

1601 

1602    // Emit target predicates.

1603    emitSchedModelHelpersImpl(OS);

1604   

1605    OS << " // " << ClassName << "::resolveSchedClass\\n\\n";

1606 

1607    OS << "unsigned " << ClassName

1608       << "\\n::resolveVariantSchedClass(unsigned SchedClass, const MCInst *MI,"

1609       << " unsigned CPUID) const \\n"

1610       << "  return " << Target << "_MC"

1611       << "::resolveVariantSchedClassImpl(SchedClass, MI, CPUID);\\n"

1612       << " // " << ClassName << "::resolveVariantSchedClass\\n";

1613 

TD可以使用一个PredicateProlog派生定义来获取一个MachineInstrTargetSchedModel对象,用于resolveSchedClass()下面的处理。这部分代码由下面的方法生成。X86目前没有使用PredicateProlog

1466  static void emitPredicateProlog(const RecordKeeper &Records, raw_ostream &OS)

1467    std::string Buffer;

1468    raw_string_ostream Stream(Buffer);

1469 

1450    // Collect all the PredicateProlog records and print them to the output

1451    // stream.

1452    std::vector<Record *> Prologs =

1453        Records.getAllDerivedDefinitions("PredicateProlog");

1454    llvm::sort(Prologs.begin(), Prologs.end(), LessRecord());

1455    for (Record *P : Prologs)

1456      Stream << P->getValueAsString("Code") << '\\n';

1457 

1458    Stream.flush();

1459    OS << Buffer;

1460 

1603emitSchedModelHelpersImpl()前面已经看过,那时它为MCInst生成resolveVariantSchedClass(),现在它为X86GenSubtargetInfo生成resolveSchedClass()。最后生成这样的代码(与前面生成的resolveVariantSchedClassImpl()大同小异):

unsigned X86GenSubtargetInfo

::resolveSchedClass(unsigned SchedClass, const MachineInstr *MI, const TargetSchedModel *SchedModel) const

  switch (SchedClass)

  case 577: // MMX_PADDQirr_MMX_PSUBQirr

    if (SchedModel->getProcessorID() == 4) // BtVer2Model

      if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg())

        return 1203; // JWriteZeroLatency

      if (true)

        return 1204; // WriteVecALU

   

    break;

  case 703: // PCMPGTQrr_VPCMPGTQrr

    if (SchedModel->getProcessorID() == 4) // BtVer2Model

      if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg())

        return 1203; // JWriteZeroLatency

      if (true)

        return 1205; // WriteVecALUX

   

    break;

  case 986: // SUB32rr_SUB64rr_XOR32rr_XOR64rr

    if (SchedModel->getProcessorID() == 4) // BtVer2Model

      if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg())

        return 1203; // JWriteZeroLatency

      if (true)

        return 1206; // WriteALU

   

    break;

  case 987: // XORPSrr_VXORPSrr_XORPDrr_VXORPDrr_ANDNPSrr_VANDNPSrr_ANDNPDrr_VANDNPDrr

    if (SchedModel->getProcessorID() == 4) // BtVer2Model

      if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg())

        return 1203; // JWriteZeroLatency

      if (true)

        return 1207; // WriteFLogic

   

    break;

  case 988: // MMX_PXORirr_MMX_PANDNirr

    if (SchedModel->getProcessorID() == 4) // BtVer2Model

      if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg())

        return 1203; // JWriteZeroLatency

      if (true)

        return 1208; // WriteVecLogic

   

    break;

  case 989: // PXORrr_VPXORrr_PANDNrr_VPANDNrr

    if (SchedModel->getProcessorID() == 4) // BtVer2Model

      if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg())

        return 1203; // JWriteZeroLatency

      if (true)

        return 1209; // WriteVecLogicX

   

    break;

  case 990: // MMX_PSUBBirr_MMX_PSUBDirr_MMX_PSUBWirr_MMX_PCMPGTBirr_MMX_PCMPGTDirr_MMX_PCMPGTWirr

    if (SchedModel->getProcessorID() == 4) // BtVer2Model

      if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg())

        return 1203; // JWriteZeroLatency

      if (true)

        return 1204; // WriteVecALU

   

    break;

  case 991: // PSUBBrr_VPSUBBrr_PSUBDrr_VPSUBDrr_VPSUBQrr_PSUBWrr_VPSUBWrr_PCMPGTBrr_VPCMPGTBrr_PCMPGTDrr_VPCMPGTDrr_PCMPGTWrr_VPCMPGTWrr

    if (SchedModel->getProcessorID() == 4) // BtVer2Model

      if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg())

        return 1203; // JWriteZeroLatency

      if (true)

        return 1205; // WriteVecALUX

   

    break;

  case 992: // PSUBQrr

    if (SchedModel->getProcessorID() == 4) // BtVer2Model

      if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg())

        return 1203; // JWriteZeroLatency

      if (true)

        return 1205; // WriteVecALUX

   

    break;

  case 993: // LEA32r_LEA64r_LEA64_32r

    if (SchedModel->getProcessorID() == 4) // BtVer2Model

      if ((

          X86GenInstrInfo::isThreeOperandsLEA(*MI)

          || (

            MI->getOperand(2).isImm()

            && MI->getOperand(2).getImm() != 1

          )

        ))

        return 1210; // JWrite3OpsLEA

      if (true)

        return 1211; // WriteLEA

   

    break;

  case 996: // MMX_PCMPGTBirr_MMX_PCMPGTDirr_MMX_PCMPGTWirr

    if (SchedModel->getProcessorID() == 4) // BtVer2Model

      if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg())

        return 1203; // JWriteZeroLatency

      if (true)

        return 1204; // WriteVecALU

   

    break;

  case 1000: // PSUBBrr_PSUBDrr_PSUBWrr_VPSUBBrr_VPSUBDrr_VPSUBQrr_VPSUBWrr

    if (SchedModel->getProcessorID() == 4) // BtVer2Model

      if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg())

        return 1203; // JWriteZeroLatency

      if (true)

        return 1205; // WriteVecALUX

   

    break;

  ;

  report_fatal_error("Expected a variant SchedClass");

// X86GenSubtargetInfo::resolveSchedClass

 

unsigned X86GenSubtargetInfo

::resolveVariantSchedClass(unsigned SchedClass, const MCInst *MI, unsigned CPUID) const

  return X86_MC::resolveVariantSchedClassImpl(SchedClass, MI, CPUID);

// X86GenSubtargetInfo::resolveVariantSchedClass

V7.0的变化——getHwMode()

对于Hexagon处理器,有所谓的HwMode,根据不同的特性有不同的寻址大小与模式。它需要定义getHwMode()。

1615  void SubtargetEmitter::EmitHwModeCheck(const std::string &ClassName,

1616                                         raw_ostream &OS)

1617    const CodeGenHwModes &CGH = TGT.getHwModes();

1618    assert(CGH.getNumModeIds() > 0);

1619    if (CGH.getNumModeIds() == 1)

1620      return;

1621 

1622    OS << "unsigned " << ClassName << "::getHwMode() const \\n";

1623    for (unsigned M = 1, NumModes = CGH.getNumModeIds(); M != NumModes; ++M)

1624      const HwMode &HM = CGH.getMode(M);

1625      OS << "  if (checkFeatures(\\"" << HM.Features

1626         << "\\")) return " << M << ";\\n";

1627   

1628    OS << "  return 0;\\n\\n";

1629 

因此对Hexagon生成将生成这样的代码:

unsigned HexagonGenSubtargetInfo::getHwMode() const

  if (checkFeatures("+hvx-length128b")) return 1;

  if (checkFeatures("+hvx-length64b")) return 2;

  return 0;

以上是关于LLVM学习笔记(44-2)的主要内容,如果未能解决你的问题,请参考以下文章

LLVM学习笔记(52)

LLVM学习笔记(43-2)

LLVM学习笔记(54)

LLVM学习笔记(54)

LLVM学习笔记(53)

LLVM学习笔记(53)