4.4.3.3. X86TargetLowering子对象
在X86Subtarget构造函数的314行,接着调用X86TargetLowering构造函数构建X86Subtarget中的该类型的子对象TLInfo。
这个TargetLowering派生类,由基于SelectionDAG的指令选择器用于描述LLVM代码如何被降级为SelectionDAG操作。至于其他,这个类展示了:
- 用于各种ValueType的一个初始寄存器类别,
- 目标机器原生支持哪些操作,
- Setcc操作的返回类型,
- 可用作偏移数的类型,及
- 各种高级特性,比如通过常量将除法转换为一组乘法是否合算
4.4.3.3.1. TargetLowering
首先看一下基类TargetLowering的构造函数。
40 TargetLowering::TargetLowering(const TargetMachine &tm)
41 : TargetLoweringBase(tm) {}
TargetLoweringBase构造函数的定义如下。它为各个目标机器提供了基准设置,各目标机器可以在自己的TargetLowering派生类的构造函数里重新设置相关的参数。
532 TargetLoweringBase::TargetLoweringBase(const TargetMachine &tm) : TM(tm) {
533 initActions();
534
535 // Perform these initializations only once.
536 MaxStoresPerMemset = MaxStoresPerMemcpy = MaxStoresPerMemmove =
537 MaxLoadsPerMemcmp = 8;
538 MaxGluedStoresPerMemcpy = 0;
539 MaxStoresPerMemsetOptSize = MaxStoresPerMemcpyOptSize
540 = MaxStoresPerMemmoveOptSize = MaxLoadsPerMemcmpOptSize = 4;
541 UseUnderscoreSetJmp = false;
542 UseUnderscoreLongJmp = false;
543 HasMultipleConditionRegisters = false;
544 HasExtractBitsInsn = false;
545 JumpIsExpensive = JumpIsExpensiveOverride;
546 PredictableSelectIsExpensive = false;
547 EnableExtLdPromotion = false;
548 HasFloatingPointExceptions = true;
549 StackPointerRegisterToSaveRestore = 0;
550 BooleanContents = UndefinedBooleanContent;
551 BooleanFloatContents = UndefinedBooleanContent;
552 BooleanVectorContents = UndefinedBooleanContent;
553 SchedPreferenceInfo = Sched::ILP;
554 JumpBufSize = 0;
555 JumpBufAlignment = 0;
556 MinFunctionAlignment = 0;
557 PrefFunctionAlignment = 0;
558 PrefLoopAlignment = 0;
559 GatherAllAliasesMaxDepth = 18;
560 MinStackArgumentAlignment = 1;
561 // TODO: the default will be switched to 0 in the next commit, along
562 // with the Target-specific changes necessary.
563 MaxAtomicSizeInBitsSupported = 1024;
564
565 MinCmpXchgSizeInBits = 0;
566 SupportsUnalignedAtomics = false;
567
568 std::fill(std::begin(LibcallRoutineNames), std::end(LibcallRoutineNames), nullptr);
569
570 InitLibcalls(TM.getTargetTriple());
571 InitCmpLibcallCCs(CmpLibcallCCs);
572 }
在750行调用initActions()初始化各种action。从下面的代码可以看到,有这些action:OpActions、LoadExtActions、TruncStoreActions、IndexedModeActions与CondCodeActions。它们都是整数类型的数组,数组的内容则是一个LegalizeAction枚举类型。这个枚举类型表示指定的操作对一个目标机器是否合法。如果不是,应该采取什么行动使它们合法:
43 namespace LegalizeActions {
44 enum LegalizeAction : std::uint8_t {
45 /// The operation is expected to be selectable directly by the target, and
46 /// no transformation is necessary.
47 Legal,
48
49 /// The operation should be synthesized from multiple instructions acting on
50 /// a narrower scalar base-type. For example a 64-bit add might be
51 /// implemented in terms of 32-bit add-with-carry.
52 NarrowScalar,
53
54 /// The operation should be implemented in terms of a wider scalar
55 /// base-type. For example a <2 x s8> add could be implemented as a <2
56 /// x s32> add (ignoring the high bits).
57 WidenScalar,
58
59 /// The (vector) operation should be implemented by splitting it in