Reloc::Model RM, CodeModel::Model CM,
CodeGenOpt::Level OL, bool isLittle)
: LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
- Subtarget(nullptr), DefaultSubtarget(TT, CPU, FS, isLittle, this),
+ isLittle(isLittle), Subtarget(nullptr),
+ DefaultSubtarget(TT, CPU, FS, isLittle, this),
NoMips16Subtarget(TT, CPU, FS.empty() ? "-mips16" : FS.str() + ",-mips16",
isLittle, this),
Mips16Subtarget(TT, CPU, FS.empty() ? "+mips16" : FS.str() + ",+mips16",
CodeGenOpt::Level OL)
: MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
+const MipsSubtarget *
+MipsTargetMachine::getSubtargetImpl(const Function &F) const override {
+ AttributeSet FnAttrs = F.getAttributes();
+ Attribute CPUAttr =
+ FnAttrs.getAttribute(AttributeSet::FunctionIndex, "target-cpu");
+ Attribute FSAttr =
+ FnAttrs.getAttribute(AttributeSet::FunctionIndex, "target-features");
+
+ std::string CPU = !CPUAttr.hasAttribute(Attribute::None)
+ ? CPUAttr.getValueAsString().str()
+ : TargetCPU;
+ std::string FS = !FSAttr.hasAttribute(Attribute::None)
+ ? FSAttr.getValueAsString().str()
+ : TargetFS;
+ bool hasMips16Attr =
+ !FnAttrs.getAttribute(AttributeSet::FunctionIndex, "mips16")
+ .hasAttribute(Attribute::None);
+ bool hasNoMips16Attr =
+ !FnAttrs.getAttribute(AttributeSet::FunctionIndex, "nomips16")
+ .hasAttribute(Attribute::None);
+
+ if (hasMips16Attr)
+ FS += FS.empty() ? "+mips16" : ",+mips16";
+ else if (hasNoMips16Attr)
+ FS += FS.empty() ? "-mips16" : ",-mips16";
+
+ auto &I = SubtargetMap[CPU + FS];
+ if (!I) {
+ // This needs to be done before we create a new subtarget since any
+ // creation will depend on the TM and the code generation flags on the
+ // function that reside in TargetOptions.
+ resetTargetOptions(F);
+ I = make_unique<MipsSubtarget>(TargetTriple, CPU, FS, isLittle, this);
+ }
+ return I.get();
+}
+
void MipsTargetMachine::resetSubtarget(MachineFunction *MF) {
DEBUG(dbgs() << "resetSubtarget\n");
- AttributeSet FnAttrs = MF->getFunction()->getAttributes();
- bool Mips16Attr = FnAttrs.hasAttribute(AttributeSet::FunctionIndex, "mips16");
- bool NoMips16Attr =
- FnAttrs.hasAttribute(AttributeSet::FunctionIndex, "nomips16");
- assert(!(Mips16Attr && NoMips16Attr) &&
- "mips16 and nomips16 specified on the same function");
- if (Mips16Attr)
- Subtarget = &Mips16Subtarget;
- else if (NoMips16Attr)
- Subtarget = &NoMips16Subtarget;
- else
- Subtarget = &DefaultSubtarget;
+
+ Subtarget = const_cast<MipsSubtarget*>(getSubtargetImpl(MF->getFunction()));
MF->setSubtarget(Subtarget);
return;
}
class MipsRegisterInfo;
class MipsTargetMachine : public LLVMTargetMachine {
+ bool isLittle;
MipsSubtarget *Subtarget;
MipsSubtarget DefaultSubtarget;
MipsSubtarget NoMips16Subtarget;
MipsSubtarget Mips16Subtarget;
+ mutable StringMap<std::unique_ptr<MipsSubtarget>> SubtargetMap;
+
public:
MipsTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS,
const TargetOptions &Options, Reloc::Model RM,
return &DefaultSubtarget;
}
+ const MipsSubtarget *getSubtargetImpl(const Function &F) const override;
+
/// \brief Reset the subtarget for the Mips target.
void resetSubtarget(MachineFunction *MF);