LLVM学习笔记(51)

3.10. X86折叠表的生成(v7.0)

指令折叠是在寄存器分配过程中执行的优化,目的是删除不必要的拷贝指令。例如,这样的一组指令:

%EBX = LOAD %mem_address

%EAX = COPY %EBX

可以被安全地替换为单条指令:

%EAX = LOAD %mem_address

通常,后者较前者更小,更快。

X86中,许多指令有内存形式与寄存器形式,即通过内存或寄存器传递操作数。为了执行指令折叠优化,需要某种方式将这两种形式的同一条指令关联起来。目前LLVM维护了几张体量庞大的表用于关联这些指令。

Intel以色列的雇员Ayman Musa开发了这部分的codegen,希望能通过TableGen自动生成这些表。不过这部分代码目前因为尚有bug,没有默认生成。这里有关于这个bug的描述。

总的来说,这是因为Musa的主要假设是同一条指令的这两个形式共享相同的编码信息,除了负责“如何向指令传递参数”的部分,其中一个版本定义其中一个参数是寄存器,另一个版本定义它为内存操作数,而其他参数以相同方式传递。

但实际上,某些指令在寄存器与内存形式间有不同与上面假设的情形,例如bt(比特测试)指令,其寄存器形式寄存器参数相关比特是第456比特(依赖于模式与寄存器大小),而内存形式相关比特是第163264比特。

这导致了编译错误。Musa建议特别处理这些指令。目前,这部分的codegen默认是关闭的,防止X86加入新指令时导致生成错误的表。可以在编译llvm时使用选项X86_GEN_FOLD_TABLES=ON来打开这个codegen

与这个codegen相关,在td层面,在X86Inst定义里原有isMemoryFoldable域,它缺省设置为1。后来又添加了一个类:class NotMemoryFoldable { bit isMemoryFoldable = 0; },所有不能折叠的指令使用它作为一个基类(它与X86inst原有的isMemoryFoldable是重复的,TableGen比较奇怪,域可以重复声明,反正最后出现的获胜。因此有时会出现有点难看的扩展)。

561     void X86FoldTablesEmitter::run(raw_ostream &OS) {

562       emitSourceFileHeader("X86 fold tables", OS);

563    

564       // Holds all memory instructions

565       std::vector<const CodeGenInstruction *> MemInsts;

566      // Holds all register instructions - divided according to opcode.

567       std::map<uint8_t, std::vector<const CodeGenInstruction *>> RegInsts;

568    

569       ArrayRef<const CodeGenInstruction *> NumberedInstructions =

570           Target.getInstructionsByEnumValue();

571    

572       for (const CodeGenInstruction *Inst : NumberedInstructions) {

573         if (!Inst->TheDef->getNameInit() || !Inst->TheDef->isSubClassOf("X86Inst"))

574           continue;

575    

576         const Record *Rec = Inst->TheDef;

577    

578         // - Do not proceed if the instruction is marked as notMemoryFoldable.

579         // - Instructions including RST register class operands are not relevant

580         //   for memory folding (for further details check the explanation in

581         //   lib/Target/X86/X86InstrFPStack.td file).

582         // - Some instructions (listed in the manual map above) use the register

583         //   class ptr_rc_tailcall, which can be of a size 32 or 64, to ensure

584         //   safe mapping of these instruction we manually map them and exclude

585         //   them from the automation.

586         if (Rec->getValueAsBit("isMemoryFoldable") == false ||

587           hasRSTRegClass(Inst) || hasPtrTailcallRegClass(Inst))

588           continue;

589    

590         // Add all the memory form instructions to

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值