Subtarget Initialization in <ARCH>TargetMachine constructor

Hi,

I found some different discrepancy on how Subtarget is created
between some arch specific TargetMachine constructor.

For example, for BPF/Lanai:

BPFTargetMachine::BPFTargetMachine(const Target &T, const Triple &TT,
StringRef CPU, StringRef FS,
const TargetOptions &Options,
OptionalReloc::Model RM,
OptionalCodeModel::Model CM,
CodeGenOpt::Level OL, bool JIT)
: LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options,
getEffectiveRelocModel(RM), getEffectiveCodeModel(CM),
OL),
TLOF(make_unique()),
Subtarget(TT, CPU, FS, *this) {
initAsmInfo();
}
LanaiTargetMachine::LanaiTargetMachine(const Target &T, const Triple &TT,
StringRef Cpu, StringRef FeatureString,
const TargetOptions &Options,
OptionalReloc::Model RM,
OptionalCodeModel::Model CodeModel,
CodeGenOpt::Level OptLevel, bool JIT)
: LLVMTargetMachine(T, computeDataLayout(), TT, Cpu, FeatureString, Options,
getEffectiveRelocModel(RM),
getEffectiveCodeModel(CodeModel), OptLevel),
Subtarget(TT, Cpu, FeatureString, *this, Options, getCodeModel(),
OptLevel),
TLOF(new LanaiTargetObjectFile()) {
initAsmInfo();
}

Note that Subtarget is created as part of constructor. On the other hard, initAsmInfo() tries to create a subtargetinfo as well. The “Subtarget” created here later on is returned through:
const LanaiSubtarget *
getSubtargetImpl(const llvm::Function & /Fn/) const override {
return &Subtarget;
}

ARM/X86 does differently.

ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, const Triple &TT,
StringRef CPU, StringRef FS,
const TargetOptions &Options,
OptionalReloc::Model RM,
OptionalCodeModel::Model CM,
CodeGenOpt::Level OL, bool isLittle)
: LLVMTargetMachine(T, computeDataLayout(TT, CPU, Options, isLittle), TT,
CPU, FS, Options, getEffectiveRelocModel(TT, RM),
getEffectiveCodeModel(CM), OL),
TargetABI(computeTargetABI(TT, CPU, Options)),
TLOF(createTLOF(getTargetTriple())), isLittle(isLittle) {

}

It does not create a separate Subtarget, and its getSubtargetImpl() tries to get the value

from SubtargetMap.

Is there any downside to keep BPFTargetMachine as is? Or it is worthwhile to implement it in a similar way to X86/ARM?

Thanks!

Yonghong

Hi,

Hi Yonghong.

I found some different discrepancy on how Subtarget is created
between some arch specific TargetMachine constructor.
For example, for BPF/Lanai:

<snip>

Note that Subtarget is created as part of constructor. On the other hard,
initAsmInfo() tries to create a subtargetinfo as well. The "Subtarget"
created here later on is returned through:
  const LanaiSubtarget *
  getSubtargetImpl(const llvm::Function & /*Fn*/) const override {
    return &Subtarget;
  }

Ok, so BPF and Lanai initialize a BPFSubtarget and LanaiSubtarget in
the initializer list for BPFTargetMachine and LanaiTargetMachine. I'm
not sure I quite follow your concern about initAsmInfo, as that
accesses an MCSubtargetInfo rather than a subclass of Subtarget.

ARM/X86 does differently.
ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, const Triple
&TT,
                                           StringRef CPU, StringRef FS,
                                           const TargetOptions &Options,
                                           Optional<Reloc::Model> RM,
                                           Optional<CodeModel::Model> CM,
                                           CodeGenOpt::Level OL, bool
isLittle)
    : LLVMTargetMachine(T, computeDataLayout(TT, CPU, Options, isLittle),
TT,
                        CPU, FS, Options, getEffectiveRelocModel(TT, RM),
                        getEffectiveCodeModel(CM), OL),
      TargetABI(computeTargetABI(TT, CPU, Options)),
      TLOF(createTLOF(getTargetTriple())), isLittle(isLittle) {
...
}
It does not create a separate Subtarget, and its getSubtargetImpl() tries to
get the value
from SubtargetMap.

Is there any downside to keep BPFTargetMachine as is? Or it is worthwhile to
implement it in a similar way to X86/ARM?

My understanding is that SubtargetMap is used to allow different
subtargets to be returned for different functions/modules based on
attributes (e.g. one function might be soft-float, another function
might have a particular feature string or CPU in its attributes. I've
CCed in Eric Christopher who worked on this and can hopefully clarify
or correct me. From what I remember of BPF, I don't think it has
different subtargets and so wouldn't really benefit from moving
towards using a SubtargetMap unless it gained new subtargets.

Hope that helps,

Alex

Thanks, Alex. See my comments below.

Hi,

Hi Yonghong.

I found some different discrepancy on how Subtarget is created
between some arch specific TargetMachine constructor.
For example, for BPF/Lanai:

<snip>

Note that Subtarget is created as part of constructor. On the other hard,
initAsmInfo() tries to create a subtargetinfo as well. The "Subtarget"
created here later on is returned through:
  const LanaiSubtarget *
  getSubtargetImpl(const llvm::Function & /*Fn*/) const override {
    return &Subtarget;
  }

Ok, so BPF and Lanai initialize a BPFSubtarget and LanaiSubtarget in
the initializer list for BPFTargetMachine and LanaiTargetMachine. I'm
not sure I quite follow your concern about initAsmInfo, as that
accesses an MCSubtargetInfo rather than a subclass of Subtarget.

The following is what I observed:
Both Subtarget constructor and initAsmInfo will eventually create
a MCSubtargetInfo, which calls InitMCProcessorInfo.

void MCSubtargetInfo::InitMCProcessorInfo(StringRef CPU, StringRef FS) {
  FeatureBits = getFeatures(CPU, FS, ProcDesc, ProcFeatures);
  if (!CPU.empty())
    CPUSchedModel = &getSchedModelForCPU(CPU);
  else
    CPUSchedModel = &MCSchedModel::GetDefaultSchedModel();
}

If you have -mcpu=help in your command line
llc -march=<> -mcpu=help ...

The help information will be printed out twice because getFeatures will printout
the help info if both ProcDesc and ProcFeatures are not empty.
This is not really elegent. What I am wondering is whether there are other
side effect of this approach or not. If not, maybe I can live with this
for a while....

I see what you mean, thanks for the clarification. That seems worth
filing a bug for on https://bugs.llvm.org/, even though it seems
pretty low impact.

Best,

Alex

Yeah, this is pretty annoying, but hadn’t been fixed yet.

-eric

Thanks, Eric. Filed a lower priority bug
https://bugs.llvm.org/show_bug.cgi?id=34331
to keep the record.