LLVM学习笔记(44-2)
Posted wuhui_gdnt
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LLVM学习笔记(44-2)相关的知识,希望对你有一定的参考价值。
V7.0的变化——resolveSchedClass()等
V7.0在这里引入了相当剧烈的变化,因为x86也开始使用SchedVar,SchedWriteVariant,以及SchedWriteVariant,resolveSchedClass()开始有意义了。 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派生定义来获取一个MachineInstr或TargetSchedModel对象,用于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 1603行emitSchedModelHelpersImpl()前面已经看过,那时它为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 |
对于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)的主要内容,如果未能解决你的问题,请参考以下文章