diff --git a/lib/Target/Mips/MipsTargetMachine.cpp b/lib/Target/Mips/MipsTargetMachine.cpp index 79d1b4b13e9..afa60d2340e 100644 --- a/lib/Target/Mips/MipsTargetMachine.cpp +++ b/lib/Target/Mips/MipsTargetMachine.cpp @@ -56,7 +56,8 @@ MipsTargetMachine::MipsTargetMachine(const Target &T, StringRef TT, 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", @@ -83,20 +84,47 @@ MipselTargetMachine(const Target &T, StringRef TT, 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(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(getSubtargetImpl(MF->getFunction())); MF->setSubtarget(Subtarget); return; } diff --git a/lib/Target/Mips/MipsTargetMachine.h b/lib/Target/Mips/MipsTargetMachine.h index 58400cd1b48..5ddbbcccfbb 100644 --- a/lib/Target/Mips/MipsTargetMachine.h +++ b/lib/Target/Mips/MipsTargetMachine.h @@ -25,11 +25,14 @@ class formatted_raw_ostream; class MipsRegisterInfo; class MipsTargetMachine : public LLVMTargetMachine { + bool isLittle; MipsSubtarget *Subtarget; MipsSubtarget DefaultSubtarget; MipsSubtarget NoMips16Subtarget; MipsSubtarget Mips16Subtarget; + mutable StringMap> SubtargetMap; + public: MipsTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, @@ -45,6 +48,8 @@ public: return &DefaultSubtarget; } + const MipsSubtarget *getSubtargetImpl(const Function &F) const override; + /// \brief Reset the subtarget for the Mips target. void resetSubtarget(MachineFunction *MF); diff --git a/test/CodeGen/Mips/fp16instrinsmc.ll b/test/CodeGen/Mips/fp16instrinsmc.ll index 7ced36c016f..84d3814ee8b 100644 --- a/test/CodeGen/Mips/fp16instrinsmc.ll +++ b/test/CodeGen/Mips/fp16instrinsmc.ll @@ -385,7 +385,7 @@ entry: ; Function Attrs: nounwind declare double @exp2(double) #0 -attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="true" } +attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } attributes #1 = { nounwind readnone "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="true" } attributes #2 = { nounwind readnone } attributes #3 = { nounwind } diff --git a/test/CodeGen/Mips/hfptrcall.ll b/test/CodeGen/Mips/hfptrcall.ll index 9df8d900693..683952d0e4e 100644 --- a/test/CodeGen/Mips/hfptrcall.ll +++ b/test/CodeGen/Mips/hfptrcall.ll @@ -118,8 +118,8 @@ entry: declare i32 @printf(i8*, ...) #1 -attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="true" } -attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="true" } +attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } diff --git a/test/CodeGen/Mips/nomips16.ll b/test/CodeGen/Mips/nomips16.ll index 0affb16ac7c..5f7d74e4197 100644 --- a/test/CodeGen/Mips/nomips16.ll +++ b/test/CodeGen/Mips/nomips16.ll @@ -33,6 +33,6 @@ entry: ; CHECK: .end nofoo -attributes #0 = { nounwind "less-precise-fpmad"="false" "mips16" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="true" } -attributes #1 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "nomips16" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="true" } +attributes #0 = { nounwind "less-precise-fpmad"="false" "mips16" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "nomips16" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } diff --git a/test/CodeGen/Mips/seleq.ll b/test/CodeGen/Mips/seleq.ll index 190baad0b1d..9af422fa1bd 100644 --- a/test/CodeGen/Mips/seleq.ll +++ b/test/CodeGen/Mips/seleq.ll @@ -10,7 +10,7 @@ @z3 = common global i32 0, align 4 @z4 = common global i32 0, align 4 -define void @calc_seleq() nounwind "target-cpu"="mips32" "target-features"="+o32,+mips32" { +define void @calc_seleq() nounwind { entry: %0 = load i32* @a, align 4 %1 = load i32* @b, align 4