diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h index 972dbfa518d..492b023663b 100644 --- a/include/llvm/Attributes.h +++ b/include/llvm/Attributes.h @@ -54,13 +54,15 @@ const Attributes Alignment = 31<<16; ///< Alignment of parameter (5 bits) // stored as log2 of alignment with +1 bias // 0 means unaligned different from align 1 const Attributes NoCapture = 1<<21; ///< Function creates no aliases of pointer +const Attributes NoRedZone = 1<<22; /// disable redzone /// @brief Attributes that only apply to function parameters. const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture; /// @brief Attributes that only apply to function. const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly | - NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq; + NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq | + NoRedZone; /// @brief Parameter attributes that do not apply to vararg call arguments. const Attributes VarArgsIncompatible = StructRet; diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index 06d7d79441e..4869157d746 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -117,10 +117,6 @@ namespace llvm { /// wth earlier copy coalescing. extern bool StrongPHIElim; - /// DisableRedZone - This flag disables use of the "Red Zone" on - /// targets which would otherwise have one. - extern bool DisableRedZone; - } // End llvm namespace #endif diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index f2e68901760..340cfe152f5 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -547,6 +547,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(optsize); KEYWORD(ssp); KEYWORD(sspreq); + KEYWORD(noredzone); KEYWORD(type); KEYWORD(opaque); diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 8db4c715b79..4f8be889c70 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -730,7 +730,7 @@ bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) { case lltok::kw_optsize: Attrs |= Attribute::OptimizeForSize; break; case lltok::kw_ssp: Attrs |= Attribute::StackProtect; break; case lltok::kw_sspreq: Attrs |= Attribute::StackProtectReq; break; - + case lltok::kw_noredzone: Attrs |= Attribute::NoRedZone; break; case lltok::kw_align: { unsigned Alignment; diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h index d8bd38a4a61..2d1cfa5a053 100644 --- a/lib/AsmParser/LLToken.h +++ b/lib/AsmParser/LLToken.h @@ -80,6 +80,7 @@ namespace lltok { kw_optsize, kw_ssp, kw_sspreq, + kw_noredzone, kw_type, kw_opaque, diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp index 5d5beebda70..cb315062abf 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -908,6 +908,7 @@ void PPCRegisterInfo::determineFrameLayout(MachineFunction &MF) const { // If we are a leaf function, and use up to 224 bytes of stack space, // don't have a frame pointer, calls, or dynamic alloca then we do not need // to adjust the stack pointer (we fit in the Red Zone). + bool DisableRedZone = MF.getFunction()->hasFnAttr(Attribute::NoRedZone); if (!DisableRedZone && FrameSize <= 224 && // Fits in red zone. !MFI->hasVarSizedObjects() && // No dynamic alloca. diff --git a/lib/Target/TargetMachine.cpp b/lib/Target/TargetMachine.cpp index 1b042ddef9b..1259dbee6d0 100644 --- a/lib/Target/TargetMachine.cpp +++ b/lib/Target/TargetMachine.cpp @@ -41,7 +41,6 @@ namespace llvm { bool RealignStack; bool DisableJumpTables; bool StrongPHIElim; - bool DisableRedZone; bool AsmVerbosityDefault(false); } @@ -163,11 +162,6 @@ EnableStrongPHIElim(cl::Hidden, "strong-phi-elim", cl::desc("Use strong PHI elimination."), cl::location(StrongPHIElim), cl::init(false)); -static cl::opt -DisableRedZoneOption("disable-red-zone", - cl::desc("Do not emit code that uses the red zone."), - cl::location(DisableRedZone), - cl::init(false)); //--------------------------------------------------------------------------- // TargetMachine Class diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp index 674be298647..5d56db563ba 100644 --- a/lib/Target/X86/X86RegisterInfo.cpp +++ b/lib/Target/X86/X86RegisterInfo.cpp @@ -751,6 +751,7 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const { // function, and use up to 128 bytes of stack space, don't have a frame // pointer, calls, or dynamic alloca then we do not need to adjust the // stack pointer (we fit in the Red Zone). + bool DisableRedZone = Fn->hasFnAttr(Attribute::NoRedZone); if (Is64Bit && !DisableRedZone && !needsStackRealignment(MF) && !MFI->hasVarSizedObjects() && // No dynamic alloca. diff --git a/lib/VMCore/Attributes.cpp b/lib/VMCore/Attributes.cpp index 5a8fad9cd32..3ebcadb2330 100644 --- a/lib/VMCore/Attributes.cpp +++ b/lib/VMCore/Attributes.cpp @@ -59,6 +59,8 @@ std::string Attribute::getAsString(Attributes Attrs) { Result += "ssp "; if (Attrs & Attribute::StackProtectReq) Result += "sspreq "; + if (Attrs & Attribute::NoRedZone) + Result += "noredzone "; if (Attrs & Attribute::Alignment) { Result += "align "; Result += utostr(Attribute::getAlignmentFromAttrs(Attrs)); diff --git a/test/CodeGen/X86/red-zone2.ll b/test/CodeGen/X86/red-zone2.ll new file mode 100644 index 00000000000..dea7d7eb0ea --- /dev/null +++ b/test/CodeGen/X86/red-zone2.ll @@ -0,0 +1,9 @@ +; RUN: llvm-as < %s | llc -march=x86-64 > %t +; RUN: grep subq %t | count 1 +; RUN: grep addq %t | count 1 + +define x86_fp80 @f0(float %f) nounwind readnone noredzone { +entry: + %0 = fpext float %f to x86_fp80 ; [#uses=1] + ret x86_fp80 %0 +} diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp index 4808f0e529c..a2474729dd2 100644 --- a/tools/llc/llc.cpp +++ b/tools/llc/llc.cpp @@ -100,6 +100,11 @@ cl::opt NoVerify("disable-verify", cl::Hidden, cl::desc("Do not verify input module")); +static cl::opt +DisableRedZone("disable-red-zone", + cl::desc("Do not emit code that uses the red zone."), + cl::init(false)); + // GetFileNameRoot - Helper function to get the basename of a filename. static inline std::string GetFileNameRoot(const std::string &InputFilename) { @@ -336,8 +341,11 @@ int main(int argc, char **argv) { // Run our queue of passes all at once now, efficiently. // TODO: this could lazily stream functions out of the module. for (Module::iterator I = mod.begin(), E = mod.end(); I != E; ++I) - if (!I->isDeclaration()) + if (!I->isDeclaration()) { + if (DisableRedZone) + I->addFnAttr(Attribute::NoRedZone); Passes.run(*I); + } Passes.doFinalization(); }