From baldrick at free.fr Mon May 24 02:33:10 2010 From: baldrick at free.fr (Duncan Sands) Date: Mon, 24 May 2010 09:33:10 +0200 Subject: [llvm-commits] PATCH: use LLVM_GET_REG_NAME consistently in llvm-gcc In-Reply-To: <060D0BBE-FF47-439F-8C60-F89AF3748C41@apple.com> References: <060D0BBE-FF47-439F-8C60-F89AF3748C41@apple.com> Message-ID: <4BFA2BB6.9090203@free.fr> Hi Bob, > Duncan pointed out that there is one remaining reference to "reg_names" in gcc/llvm-convert.cpp, and he offered to test a patch to use LLVM_GET_REG_NAME instead. Here you go, Duncan. Happy testing! thanks for the patch. It seems to work fine, so I applied it. Ciao, Duncan. From baldrick at free.fr Mon May 24 02:49:56 2010 From: baldrick at free.fr (Duncan Sands) Date: Mon, 24 May 2010 07:49:56 -0000 Subject: [llvm-commits] [llvm] r104485 - in /llvm/trunk/tools/bugpoint: ExecutionDriver.cpp ToolRunner.cpp ToolRunner.h Message-ID: <20100524074956.2B2FA312800A@llvm.org> Author: baldrick Date: Mon May 24 02:49:55 2010 New Revision: 104485 URL: http://llvm.org/viewvc/llvm-project?rev=104485&view=rev Log: Apply timeouts and memory limits in more places. In particular, when bugpoint does "Running the code generator to test for a crash" this gets you a crash if llc goes into an infinite loop or uses up vast amounts of memory. Modified: llvm/trunk/tools/bugpoint/ExecutionDriver.cpp llvm/trunk/tools/bugpoint/ToolRunner.cpp llvm/trunk/tools/bugpoint/ToolRunner.h Modified: llvm/trunk/tools/bugpoint/ExecutionDriver.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/ExecutionDriver.cpp?rev=104485&r1=104484&r2=104485&view=diff ============================================================================== --- llvm/trunk/tools/bugpoint/ExecutionDriver.cpp (original) +++ llvm/trunk/tools/bugpoint/ExecutionDriver.cpp Mon May 24 02:49:55 2010 @@ -312,7 +312,7 @@ FileRemover BitcodeFileRemover(BitcodeFile, !SaveTemps); // Actually compile the program! - Interpreter->compileProgram(BitcodeFile.str(), Error); + Interpreter->compileProgram(BitcodeFile.str(), Error, Timeout, MemoryLimit); } Modified: llvm/trunk/tools/bugpoint/ToolRunner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/ToolRunner.cpp?rev=104485&r1=104484&r2=104485&view=diff ============================================================================== --- llvm/trunk/tools/bugpoint/ToolRunner.cpp (original) +++ llvm/trunk/tools/bugpoint/ToolRunner.cpp Mon May 24 02:49:55 2010 @@ -133,7 +133,9 @@ return ReturnCode; } -static std::string ProcessFailure(sys::Path ProgPath, const char** Args) { +static std::string ProcessFailure(sys::Path ProgPath, const char** Args, + unsigned Timeout = 0, + unsigned MemoryLimit = 0) { std::ostringstream OS; OS << "\nError running tool:\n "; for (const char **Arg = Args; *Arg; ++Arg) @@ -148,7 +150,8 @@ exit(1); } RunProgramWithTimeout(ProgPath, Args, sys::Path(""), ErrorFilename, - ErrorFilename); // FIXME: check return code ? + ErrorFilename, Timeout, MemoryLimit); + // FIXME: check return code ? // Print out the error messages generated by GCC if possible... std::ifstream ErrorFile(ErrorFilename.c_str()); @@ -353,7 +356,8 @@ // LLC Implementation of AbstractIntepreter interface // GCC::FileType LLC::OutputCode(const std::string &Bitcode, - sys::Path &OutputAsmFile, std::string &Error) { + sys::Path &OutputAsmFile, std::string &Error, + unsigned Timeout, unsigned MemoryLimit) { const char *Suffix = (UseIntegratedAssembler ? ".llc.o" : ".llc.s"); sys::Path uniqueFile(Bitcode + Suffix); std::string ErrMsg; @@ -386,14 +390,17 @@ errs() << "\n"; ); if (RunProgramWithTimeout(sys::Path(LLCPath), &LLCArgs[0], - sys::Path(), sys::Path(), sys::Path())) - Error = ProcessFailure(sys::Path(LLCPath), &LLCArgs[0]); + sys::Path(), sys::Path(), sys::Path(), + Timeout, MemoryLimit)) + Error = ProcessFailure(sys::Path(LLCPath), &LLCArgs[0], + Timeout, MemoryLimit); return UseIntegratedAssembler ? GCC::ObjectFile : GCC::AsmFile; } -void LLC::compileProgram(const std::string &Bitcode, std::string *Error) { +void LLC::compileProgram(const std::string &Bitcode, std::string *Error, + unsigned Timeout, unsigned MemoryLimit) { sys::Path OutputAsmFile; - OutputCode(Bitcode, OutputAsmFile, *Error); + OutputCode(Bitcode, OutputAsmFile, *Error, Timeout, MemoryLimit); OutputAsmFile.eraseFromDisk(); } @@ -408,7 +415,8 @@ unsigned MemoryLimit) { sys::Path OutputAsmFile; - GCC::FileType FileKind = OutputCode(Bitcode, OutputAsmFile, *Error); + GCC::FileType FileKind = OutputCode(Bitcode, OutputAsmFile, *Error, Timeout, + MemoryLimit); FileRemover OutFileRemover(OutputAsmFile, !SaveTemps); std::vector GCCArgs(ArgsForGCC); @@ -528,7 +536,8 @@ } GCC::FileType CBE::OutputCode(const std::string &Bitcode, - sys::Path &OutputCFile, std::string &Error) { + sys::Path &OutputCFile, std::string &Error, + unsigned Timeout, unsigned MemoryLimit) { sys::Path uniqueFile(Bitcode+".cbe.c"); std::string ErrMsg; if (uniqueFile.makeUnique(true, &ErrMsg)) { @@ -556,14 +565,15 @@ errs() << "\n"; ); if (RunProgramWithTimeout(LLCPath, &LLCArgs[0], sys::Path(), sys::Path(), - sys::Path())) - Error = ProcessFailure(LLCPath, &LLCArgs[0]); + sys::Path(), Timeout, MemoryLimit)) + Error = ProcessFailure(LLCPath, &LLCArgs[0], Timeout, MemoryLimit); return GCC::CFile; } -void CBE::compileProgram(const std::string &Bitcode, std::string *Error) { +void CBE::compileProgram(const std::string &Bitcode, std::string *Error, + unsigned Timeout, unsigned MemoryLimit) { sys::Path OutputCFile; - OutputCode(Bitcode, OutputCFile, *Error); + OutputCode(Bitcode, OutputCFile, *Error, Timeout, MemoryLimit); OutputCFile.eraseFromDisk(); } @@ -577,7 +587,7 @@ unsigned Timeout, unsigned MemoryLimit) { sys::Path OutputCFile; - OutputCode(Bitcode, OutputCFile, *Error); + OutputCode(Bitcode, OutputCFile, *Error, Timeout, MemoryLimit); FileRemover CFileRemove(OutputCFile, !SaveTemps); Modified: llvm/trunk/tools/bugpoint/ToolRunner.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/ToolRunner.h?rev=104485&r1=104484&r2=104485&view=diff ============================================================================== --- llvm/trunk/tools/bugpoint/ToolRunner.h (original) +++ llvm/trunk/tools/bugpoint/ToolRunner.h Mon May 24 02:49:55 2010 @@ -112,14 +112,17 @@ /// compileProgram - Compile the specified program from bitcode to executable /// code. This does not produce any output, it is only used when debugging /// the code generator. It returns false if the code generator fails. - virtual void compileProgram(const std::string &Bitcode, std::string *Error) {} + virtual void compileProgram(const std::string &Bitcode, std::string *Error, + unsigned Timeout = 0, unsigned MemoryLimit = 0) {} /// OutputCode - Compile the specified program from bitcode to code /// understood by the GCC driver (either C or asm). If the code generator /// fails, it sets Error, otherwise, this function returns the type of code /// emitted. virtual GCC::FileType OutputCode(const std::string &Bitcode, - sys::Path &OutFile, std::string &Error) { + sys::Path &OutFile, std::string &Error, + unsigned Timeout = 0, + unsigned MemoryLimit = 0) { Error = "OutputCode not supported by this AbstractInterpreter!"; return GCC::AsmFile; } @@ -161,7 +164,8 @@ /// compileProgram - Compile the specified program from bitcode to executable /// code. This does not produce any output, it is only used when debugging /// the code generator. Returns false if the code generator fails. - virtual void compileProgram(const std::string &Bitcode, std::string *Error); + virtual void compileProgram(const std::string &Bitcode, std::string *Error, + unsigned Timeout = 0, unsigned MemoryLimit = 0); virtual int ExecuteProgram(const std::string &Bitcode, const std::vector &Args, @@ -180,7 +184,9 @@ /// fails, it sets Error, otherwise, this function returns the type of code /// emitted. virtual GCC::FileType OutputCode(const std::string &Bitcode, - sys::Path &OutFile, std::string &Error); + sys::Path &OutFile, std::string &Error, + unsigned Timeout = 0, + unsigned MemoryLimit = 0); }; @@ -206,7 +212,8 @@ /// compileProgram - Compile the specified program from bitcode to executable /// code. This does not produce any output, it is only used when debugging /// the code generator. Returns false if the code generator fails. - virtual void compileProgram(const std::string &Bitcode, std::string *Error); + virtual void compileProgram(const std::string &Bitcode, std::string *Error, + unsigned Timeout = 0, unsigned MemoryLimit = 0); virtual int ExecuteProgram(const std::string &Bitcode, const std::vector &Args, @@ -225,7 +232,9 @@ /// fails, it sets Error, otherwise, this function returns the type of code /// emitted. virtual GCC::FileType OutputCode(const std::string &Bitcode, - sys::Path &OutFile, std::string &Error); + sys::Path &OutFile, std::string &Error, + unsigned Timeout = 0, + unsigned MemoryLimit = 0); }; } // End llvm namespace From nicolas.geoffray at lip6.fr Mon May 24 07:24:11 2010 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Mon, 24 May 2010 12:24:11 -0000 Subject: [llvm-commits] [llvm] r104488 - /llvm/trunk/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp Message-ID: <20100524122411.781F8312800A@llvm.org> Author: geoffray Date: Mon May 24 07:24:11 2010 New Revision: 104488 URL: http://llvm.org/viewvc/llvm-project?rev=104488&view=rev Log: Encode the Caml frametable by following what the comment says: the number of descriptors is first emitted, and StackOffsets are emitted in 16 bits. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp?rev=104488&r1=104487&r2=104488&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp Mon May 24 07:24:11 2010 @@ -104,6 +104,21 @@ AP.OutStreamer.SwitchSection(AP.getObjFileLowering().getDataSection()); EmitCamlGlobal(getModule(), AP, "frametable"); + int NumDescriptors = 0; + for (iterator I = begin(), IE = end(); I != IE; ++I) { + GCFunctionInfo &FI = **I; + for (GCFunctionInfo::iterator J = FI.begin(), JE = FI.end(); J != JE; ++J) { + NumDescriptors++; + } + } + + if (NumDescriptors >= 1<<16) { + // Very rude! + report_fatal_error(" Too much descriptor for ocaml GC"); + } + AP.EmitInt16(NumDescriptors); + AP.EmitAlignment(IntPtrSize == 4 ? 2 : 3); + for (iterator I = begin(), IE = end(); I != IE; ++I) { GCFunctionInfo &FI = **I; @@ -135,11 +150,13 @@ for (GCFunctionInfo::live_iterator K = FI.live_begin(J), KE = FI.live_end(J); K != KE; ++K) { - assert(K->StackOffset < 1<<16 && - "GC root stack offset is outside of fixed stack frame and out " - "of range for ocaml GC!"); - - AP.EmitInt32(K->StackOffset); + if (K->StackOffset >= 1<<16) { + // Very rude! + report_fatal_error( + "GC root stack offset is outside of fixed stack frame and out " + "of range for ocaml GC!"); + } + AP.EmitInt16(K->StackOffset); } AP.EmitAlignment(IntPtrSize == 4 ? 2 : 3); From baldrick at free.fr Mon May 24 08:00:30 2010 From: baldrick at free.fr (Duncan Sands) Date: Mon, 24 May 2010 13:00:30 -0000 Subject: [llvm-commits] [dragonegg] r104490 - /dragonegg/trunk/x86/llvm-target.h Message-ID: <20100524130030.1E81E312800A@llvm.org> Author: baldrick Date: Mon May 24 08:00:29 2010 New Revision: 104490 URL: http://llvm.org/viewvc/llvm-project?rev=104490&view=rev Log: Port commit 103976 (void) from llvm-gcc: Turn on "--disable-non-leaf-fp-elim" if -momit-leaf-frame-pointer is specified. Modified: dragonegg/trunk/x86/llvm-target.h Modified: dragonegg/trunk/x86/llvm-target.h URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/x86/llvm-target.h?rev=104490&r1=104489&r2=104490&view=diff ============================================================================== --- dragonegg/trunk/x86/llvm-target.h (original) +++ dragonegg/trunk/x86/llvm-target.h Mon May 24 08:00:29 2010 @@ -364,25 +364,30 @@ ((!nm || ISDIGIT (*nm)) ? reg_names[REG_NUM] : nm); }) /* Propagate code model setting to backend */ -#define LLVM_SET_MACHINE_OPTIONS(argvec) \ - switch (ix86_cmodel) { \ - default: \ - sorry ("code model %<%s%> not supported yet", ix86_cmodel_string); \ - break; \ - case CM_SMALL: \ - case CM_SMALL_PIC: \ - argvec.push_back("--code-model=small"); \ - break; \ - case CM_KERNEL: \ - argvec.push_back("--code-model=kernel"); \ - break; \ - case CM_MEDIUM: \ - case CM_MEDIUM_PIC: \ - argvec.push_back("--code-model=medium"); \ - break; \ - case CM_32: \ - argvec.push_back("--code-model=default"); \ - break; \ - } +#define LLVM_SET_MACHINE_OPTIONS(argvec) \ + do { \ + switch (ix86_cmodel) { \ + default: \ + sorry ("code model %<%s%> not supported yet", \ + ix86_cmodel_string); \ + break; \ + case CM_SMALL: \ + case CM_SMALL_PIC: \ + argvec.push_back("--code-model=small"); \ + break; \ + case CM_KERNEL: \ + argvec.push_back("--code-model=kernel"); \ + break; \ + case CM_MEDIUM: \ + case CM_MEDIUM_PIC: \ + argvec.push_back("--code-model=medium"); \ + break; \ + case CM_32: \ + argvec.push_back("--code-model=default"); \ + break; \ + } \ + if (TARGET_OMIT_LEAF_FRAME_POINTER) \ + argvec.push_back("--disable-non-leaf-fp-elim"); \ + } while (0) #endif /* LLVM_TARGET_H */ From baldrick at free.fr Mon May 24 08:07:56 2010 From: baldrick at free.fr (Duncan Sands) Date: Mon, 24 May 2010 13:07:56 -0000 Subject: [llvm-commits] [dragonegg] r104491 - /dragonegg/trunk/llvm-convert.cpp Message-ID: <20100524130756.81CE1312800A@llvm.org> Author: baldrick Date: Mon May 24 08:07:56 2010 New Revision: 104491 URL: http://llvm.org/viewvc/llvm-project?rev=104491&view=rev Log: Port commit 104042 (johannes) from llvm-gcc: Mark reads from register variables as sideeffect. The point of this is to create an order dependency when there are multiple uses of the same register; the scheduler could screw them up (see testcase, which is next checkin). 7993104. Modified: dragonegg/trunk/llvm-convert.cpp Modified: dragonegg/trunk/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-convert.cpp?rev=104491&r1=104490&r2=104491&view=diff ============================================================================== --- dragonegg/trunk/llvm-convert.cpp (original) +++ dragonegg/trunk/llvm-convert.cpp Mon May 24 08:07:56 2010 @@ -2954,7 +2954,7 @@ const char *Name = extractRegisterName(decl); Name = LLVM_GET_REG_NAME(Name, decode_reg_name(Name)); - InlineAsm *IA = InlineAsm::get(FTy, "", "={"+std::string(Name)+"}", false); + InlineAsm *IA = InlineAsm::get(FTy, "", "={"+std::string(Name)+"}", true); CallInst *Call = Builder.CreateCall(IA); Call->setDoesNotThrow(); From stoklund at 2pi.dk Mon May 24 09:48:12 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 24 May 2010 14:48:12 -0000 Subject: [llvm-commits] [llvm] r104492 - in /llvm/trunk: include/llvm/Target/Target.td lib/Target/Blackfin/BlackfinInstrInfo.td lib/Target/Blackfin/BlackfinRegisterInfo.cpp lib/Target/Blackfin/BlackfinRegisterInfo.h lib/Target/Blackfin/BlackfinRegisterInfo.td lib/Target/X86/X86InstrInfo.cpp lib/Target/X86/X86RegisterInfo.td utils/TableGen/CodeGenDAGPatterns.cpp utils/TableGen/DAGISelMatcherGen.cpp utils/TableGen/FastISelEmitter.cpp utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <20100524144812.90AD7312800A@llvm.org> Author: stoklund Date: Mon May 24 09:48:12 2010 New Revision: 104492 URL: http://llvm.org/viewvc/llvm-project?rev=104492&view=rev Log: Add the SubRegIndex TableGen class. This is the beginning of purely symbolic subregister indices, but we need a bit of jiggling before the explicit numeric indices can be completely removed. Modified: llvm/trunk/include/llvm/Target/Target.td llvm/trunk/lib/Target/Blackfin/BlackfinInstrInfo.td llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.cpp llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.h llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td llvm/trunk/lib/Target/X86/X86InstrInfo.cpp llvm/trunk/lib/Target/X86/X86RegisterInfo.td llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp llvm/trunk/utils/TableGen/FastISelEmitter.cpp llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Modified: llvm/trunk/include/llvm/Target/Target.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=104492&r1=104491&r2=104492&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/Target.td (original) +++ llvm/trunk/include/llvm/Target/Target.td Mon May 24 09:48:12 2010 @@ -21,6 +21,14 @@ class RegisterClass; // Forward def +class SubRegIndex { + string Namespace = ""; + + // This explicit numbering is going away after RegisterClass::SubRegClassList + // is replaced. + int NumberHack; +} + // Register - You should define one instance of this class for each register // in the target machine. String n will become the "name" of the register. class Register { Modified: llvm/trunk/lib/Target/Blackfin/BlackfinInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Blackfin/BlackfinInstrInfo.td?rev=104492&r1=104491&r2=104492&view=diff ============================================================================== --- llvm/trunk/lib/Target/Blackfin/BlackfinInstrInfo.td (original) +++ llvm/trunk/lib/Target/Blackfin/BlackfinInstrInfo.td Mon May 24 09:48:12 2010 @@ -301,9 +301,9 @@ def : Pat<(i32 (extloadi8 P:$ptr)), (LOAD32p_8z P:$ptr)>; def : Pat<(i16 (extloadi8 P:$ptr)), - (EXTRACT_SUBREG (LOAD32p_8z P:$ptr), bfin_subreg_lo16)>; + (EXTRACT_SUBREG (LOAD32p_8z P:$ptr), lo16)>; def : Pat<(i16 (zextloadi8 P:$ptr)), - (EXTRACT_SUBREG (LOAD32p_8z P:$ptr), bfin_subreg_lo16)>; + (EXTRACT_SUBREG (LOAD32p_8z P:$ptr), lo16)>; def LOAD32p_imm16_8z: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off), "$dst = b[$ptr + $off] (z);", @@ -313,17 +313,17 @@ (LOAD32p_imm16_8z P:$ptr, imm:$off)>; def : Pat<(i16 (extloadi8 (add P:$ptr, imm16:$off))), (EXTRACT_SUBREG (LOAD32p_imm16_8z P:$ptr, imm:$off), - bfin_subreg_lo16)>; + lo16)>; def : Pat<(i16 (zextloadi8 (add P:$ptr, imm16:$off))), (EXTRACT_SUBREG (LOAD32p_imm16_8z P:$ptr, imm:$off), - bfin_subreg_lo16)>; + lo16)>; def LOAD32p_8s: F1<(outs D:$dst), (ins P:$ptr), "$dst = b[$ptr] (x);", [(set D:$dst, (sextloadi8 P:$ptr))]>; def : Pat<(i16 (sextloadi8 P:$ptr)), - (EXTRACT_SUBREG (LOAD32p_8s P:$ptr), bfin_subreg_lo16)>; + (EXTRACT_SUBREG (LOAD32p_8s P:$ptr), lo16)>; def LOAD32p_imm16_8s: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off), "$dst = b[$ptr + $off] (x);", @@ -331,7 +331,7 @@ def : Pat<(i16 (sextloadi8 (add P:$ptr, imm16:$off))), (EXTRACT_SUBREG (LOAD32p_imm16_8s P:$ptr, imm:$off), - bfin_subreg_lo16)>; + lo16)>; // Memory loads without patterns let mayLoad = 1 in { @@ -468,16 +468,16 @@ def : Pat<(truncstorei16 D:$val, PI:$ptr), (STORE16pi (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS D:$val, D)), - bfin_subreg_lo16), PI:$ptr)>; + lo16), PI:$ptr)>; def : Pat<(truncstorei16 (srl D:$val, (i16 16)), PI:$ptr), (STORE16pi (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS D:$val, D)), - bfin_subreg_hi16), PI:$ptr)>; + hi16), PI:$ptr)>; def : Pat<(truncstorei8 D16L:$val, P:$ptr), (STORE8p (INSERT_SUBREG (i32 (IMPLICIT_DEF)), (i16 (COPY_TO_REGCLASS D16L:$val, D16L)), - bfin_subreg_lo16), + lo16), P:$ptr)>; //===----------------------------------------------------------------------===// @@ -516,19 +516,19 @@ (EXTRACT_SUBREG (MOVEsext8 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), D16L:$src, - bfin_subreg_lo16)), - bfin_subreg_lo16)>; + lo16)), + lo16)>; def : Pat<(sext_inreg D:$src, i16), - (MOVEsext (EXTRACT_SUBREG D:$src, bfin_subreg_lo16))>; + (MOVEsext (EXTRACT_SUBREG D:$src, lo16))>; def : Pat<(and D:$src, 0xffff), - (MOVEzext (EXTRACT_SUBREG D:$src, bfin_subreg_lo16))>; + (MOVEzext (EXTRACT_SUBREG D:$src, lo16))>; def : Pat<(i32 (anyext D16L:$src)), (INSERT_SUBREG (i32 (IMPLICIT_DEF)), (i16 (COPY_TO_REGCLASS D16L:$src, D16L)), - bfin_subreg_lo16)>; + lo16)>; // TODO Dreg = Dreg_byte (X/Z) @@ -859,4 +859,4 @@ def : Pat<(BfinCall (i32 texternalsym:$dst)), (CALLa texternalsym:$dst)>; def : Pat<(i16 (trunc D:$src)), - (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS D:$src, D)), bfin_subreg_lo16)>; + (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS D:$src, D)), lo16)>; Modified: llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.cpp?rev=104492&r1=104491&r2=104492&view=diff ============================================================================== --- llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.cpp Mon May 24 09:48:12 2010 @@ -177,11 +177,11 @@ // We must split into halves BuildMI(MBB, I, DL, - TII.get(BF::LOAD16i), getSubReg(Reg, bfin_subreg_hi16)) + TII.get(BF::LOAD16i), getSubReg(Reg, BF::hi16)) .addImm((value >> 16) & 0xffff) .addReg(Reg, RegState::ImplicitDefine); BuildMI(MBB, I, DL, - TII.get(BF::LOAD16i), getSubReg(Reg, bfin_subreg_lo16)) + TII.get(BF::LOAD16i), getSubReg(Reg, BF::lo16)) .addImm(value & 0xffff) .addReg(Reg, RegState::ImplicitKill) .addReg(Reg, RegState::ImplicitDefine); Modified: llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.h?rev=104492&r1=104491&r2=104492&view=diff ============================================================================== --- llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.h (original) +++ llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.h Mon May 24 09:48:12 2010 @@ -24,13 +24,6 @@ class TargetInstrInfo; class Type; - // Subregister indices, keep in sync with BlackfinRegisterInfo.td - enum BfinSubregIdx { - bfin_subreg_lo16 = 1, - bfin_subreg_hi16 = 2, - bfin_subreg_lo32 = 3 - }; - struct BlackfinRegisterInfo : public BlackfinGenRegisterInfo { BlackfinSubtarget &Subtarget; const TargetInstrInfo &TII; Modified: llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td?rev=104492&r1=104491&r2=104492&view=diff ============================================================================== --- llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td (original) +++ llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td Mon May 24 09:48:12 2010 @@ -11,8 +11,17 @@ // Declarations that describe the Blackfin register file //===----------------------------------------------------------------------===// -// Registers are identified with 3-bit group and 3-bit ID numbers. +// Subregs are: +// 1: .L +// 2: .H +// 3: .W (32 low bits of 40-bit accu) +let Namespace = "BF" in { +def lo16 : SubRegIndex { let NumberHack = 1; } +def hi16 : SubRegIndex { let NumberHack = 2; } +def lo32 : SubRegIndex { let NumberHack = 3; } +} +// Registers are identified with 3-bit group and 3-bit ID numbers. class BlackfinReg : Register { field bits<3> Group; field bits<3> Num; @@ -182,15 +191,6 @@ def LB0 : Ri<6, 2, "lb0">, DwarfRegNum<[48]>; def LB1 : Ri<6, 5, "lb1">, DwarfRegNum<[49]>; -// Subregs are: -// 1: .L -// 2: .H -// 3: .W (32 low bits of 40-bit accu) -// Keep in sync with enum in BlackfinRegisterInfo.h -def bfin_subreg_lo16 : PatLeaf<(i32 1)>; -def bfin_subreg_hi16 : PatLeaf<(i32 2)>; -def bfin_subreg_32bit : PatLeaf<(i32 3)>; - def : SubRegSet<1, [R0, R1, R2, R3, R4, R5, R6, R7, P0, P1, P2, P3, P4, P5, SP, FP, Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=104492&r1=104491&r2=104492&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Mon May 24 09:48:12 2010 @@ -2483,9 +2483,9 @@ unsigned DstReg = NewMI->getOperand(0).getReg(); if (TargetRegisterInfo::isPhysicalRegister(DstReg)) NewMI->getOperand(0).setReg(RI.getSubReg(DstReg, - 4/*x86_subreg_32bit*/)); + X86::x86_subreg_32bit)); else - NewMI->getOperand(0).setSubReg(4/*x86_subreg_32bit*/); + NewMI->getOperand(0).setSubReg(X86::x86_subreg_32bit); } return NewMI; } Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.td?rev=104492&r1=104491&r2=104492&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.td Mon May 24 09:48:12 2010 @@ -18,6 +18,17 @@ // let Namespace = "X86" in { + // Subregister indices. + def x86_subreg_8bit : SubRegIndex { let NumberHack = 1; } + def x86_subreg_8bit_hi : SubRegIndex { let NumberHack = 2; } + def x86_subreg_16bit : SubRegIndex { let NumberHack = 3; } + def x86_subreg_32bit : SubRegIndex { let NumberHack = 4; } + + def x86_subreg_ss : SubRegIndex { let NumberHack = 1; } + def x86_subreg_sd : SubRegIndex { let NumberHack = 2; } + def x86_subreg_xmm : SubRegIndex { let NumberHack = 3; } + + // In the register alias definitions below, we define which registers alias // which others. We only specify which registers the small registers alias, // because the register file generator is smart enough to figure out that @@ -224,15 +235,6 @@ // sub registers for each register. // -def x86_subreg_8bit : PatLeaf<(i32 1)>; -def x86_subreg_8bit_hi : PatLeaf<(i32 2)>; -def x86_subreg_16bit : PatLeaf<(i32 3)>; -def x86_subreg_32bit : PatLeaf<(i32 4)>; - -def x86_subreg_ss : PatLeaf<(i32 1)>; -def x86_subreg_sd : PatLeaf<(i32 2)>; -def x86_subreg_xmm : PatLeaf<(i32 3)>; - def : SubRegSet<1, [AX, CX, DX, BX, SP, BP, SI, DI, R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W], [AL, CL, DL, BL, SPL, BPL, SIL, DIL, Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp?rev=104492&r1=104491&r2=104492&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp (original) +++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp Mon May 24 09:48:12 2010 @@ -1057,6 +1057,11 @@ const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo(); return EEVT::TypeSet(T.getRegisterVTs(R)); } + + if (R->isSubClassOf("SubRegIndex")) { + assert(ResNo == 0 && "SubRegisterIndices only produce one result!"); + return EEVT::TypeSet(); + } if (R->isSubClassOf("ValueType") || R->isSubClassOf("CondCode")) { assert(ResNo == 0 && "This node only has one result!"); Modified: llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp?rev=104492&r1=104491&r2=104492&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp (original) +++ llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp Mon May 24 09:48:12 2010 @@ -224,6 +224,7 @@ if (// Handle register references. Nothing to do here, they always match. LeafRec->isSubClassOf("RegisterClass") || LeafRec->isSubClassOf("PointerLikeRegClass") || + LeafRec->isSubClassOf("SubRegIndex") || // Place holder for SRCVALUE nodes. Nothing to do here. LeafRec->getName() == "srcvalue") return; @@ -597,6 +598,14 @@ ResultOps.push_back(NextRecordedOperandNo++); return; } + + // Handle a subregister index. This is used for INSERT_SUBREG etc. + if (DI->getDef()->isSubClassOf("SubRegIndex")) { + std::string Value = getQualifiedName(DI->getDef()); + AddMatcher(new EmitStringIntegerMatcher(Value, MVT::i32)); + ResultOps.push_back(NextRecordedOperandNo++); + return; + } } errs() << "unhandled leaf node: \n"; Modified: llvm/trunk/utils/TableGen/FastISelEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/FastISelEmitter.cpp?rev=104492&r1=104491&r2=104492&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/FastISelEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/FastISelEmitter.cpp Mon May 24 09:48:12 2010 @@ -31,7 +31,7 @@ struct InstructionMemo { std::string Name; const CodeGenRegisterClass *RC; - unsigned char SubRegNo; + std::string SubRegNo; std::vector* PhysRegs; }; @@ -278,7 +278,7 @@ // For now, ignore instructions where the first operand is not an // output register. const CodeGenRegisterClass *DstRC = 0; - unsigned SubRegNo = ~0; + std::string SubRegNo; if (Op->getName() != "EXTRACT_SUBREG") { Record *Op0Rec = II.OperandList[0].Rec; if (!Op0Rec->isSubClassOf("RegisterClass")) @@ -287,8 +287,11 @@ if (!DstRC) continue; } else { - SubRegNo = static_cast( - Dst->getChild(1)->getLeafValue())->getValue(); + DefInit *SR = dynamic_cast(Dst->getChild(1)->getLeafValue()); + if (SR) + SubRegNo = getQualifiedName(SR->getDef()); + else + SubRegNo = Dst->getChild(1)->getLeafValue()->getAsString(); } // Inspect the pattern. @@ -437,7 +440,7 @@ } OS << " return FastEmitInst_"; - if (Memo.SubRegNo == (unsigned char)~0) { + if (Memo.SubRegNo.empty()) { Operands.PrintManglingSuffix(OS, *Memo.PhysRegs); OS << "(" << InstNS << Memo.Name << ", "; OS << InstNS << Memo.RC->getName() << "RegisterClass"; @@ -448,7 +451,7 @@ } else { OS << "extractsubreg(" << getName(RetVT); OS << ", Op0, Op0IsKill, "; - OS << (unsigned)Memo.SubRegNo; + OS << Memo.SubRegNo; OS << ");\n"; } @@ -532,7 +535,7 @@ OS << " return FastEmitInst_"; - if (Memo.SubRegNo == (unsigned char)~0) { + if (Memo.SubRegNo.empty()) { Operands.PrintManglingSuffix(OS, *Memo.PhysRegs); OS << "(" << InstNS << Memo.Name << ", "; OS << InstNS << Memo.RC->getName() << "RegisterClass"; @@ -542,7 +545,7 @@ OS << ");\n"; } else { OS << "extractsubreg(RetVT, Op0, Op0IsKill, "; - OS << (unsigned)Memo.SubRegNo; + OS << Memo.SubRegNo; OS << ");\n"; } Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp?rev=104492&r1=104491&r2=104492&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Mon May 24 09:48:12 2010 @@ -35,14 +35,31 @@ if (!Namespace.empty()) OS << "namespace " << Namespace << " {\n"; - OS << " enum {\n NoRegister,\n"; + OS << "enum {\n NoRegister,\n"; for (unsigned i = 0, e = Registers.size(); i != e; ++i) - OS << " " << Registers[i].getName() << ", \t// " << i+1 << "\n"; - OS << " NUM_TARGET_REGS \t// " << Registers.size()+1 << "\n"; - OS << " };\n"; + OS << " " << Registers[i].getName() << ", \t// " << i+1 << "\n"; + OS << " NUM_TARGET_REGS \t// " << Registers.size()+1 << "\n"; + OS << "};\n"; if (!Namespace.empty()) OS << "}\n"; + + const std::vector SubRegIndices = + Records.getAllDerivedDefinitions("SubRegIndex"); + if (!SubRegIndices.empty()) { + OS << "\n// Subregister indices\n"; + Namespace = SubRegIndices[0]->getValueAsString("Namespace"); + if (!Namespace.empty()) + OS << "namespace " << Namespace << " {\n"; + OS << "enum {\n NoSubRegister,\n"; + for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) + OS << " " << SubRegIndices[i]->getName() << " = " + << SubRegIndices[i]->getValueAsInt("NumberHack") << ",\n"; + OS << " NUM_TARGET_SUBREGS = " << SubRegIndices.size()+1 << "\n"; + OS << "};\n"; + if (!Namespace.empty()) + OS << "}\n"; + } OS << "} // End llvm namespace \n"; } From stoklund at 2pi.dk Mon May 24 09:48:17 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 24 May 2010 14:48:17 -0000 Subject: [llvm-commits] [llvm] r104493 - in /llvm/trunk/lib/Target/X86: X86FastISel.cpp X86ISelDAGToDAG.cpp X86Instr64bit.td X86InstrInfo.cpp X86InstrInfo.td X86InstrSSE.td X86RegisterInfo.h X86RegisterInfo.td Message-ID: <20100524144817.F18A73128018@llvm.org> Author: stoklund Date: Mon May 24 09:48:17 2010 New Revision: 104493 URL: http://llvm.org/viewvc/llvm-project?rev=104493&view=rev Log: Rename X86 subregister indices to something shorter. Use the tablegen-produced enums. Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp llvm/trunk/lib/Target/X86/X86Instr64bit.td llvm/trunk/lib/Target/X86/X86InstrInfo.cpp llvm/trunk/lib/Target/X86/X86InstrInfo.td llvm/trunk/lib/Target/X86/X86InstrSSE.td llvm/trunk/lib/Target/X86/X86RegisterInfo.h llvm/trunk/lib/Target/X86/X86RegisterInfo.td Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=104493&r1=104492&r2=104493&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original) +++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Mon May 24 09:48:17 2010 @@ -1029,7 +1029,7 @@ // we're doing here. if (CReg != X86::CL) BuildMI(MBB, DL, TII.get(TargetOpcode::EXTRACT_SUBREG), X86::CL) - .addReg(CReg).addImm(X86::SUBREG_8BIT); + .addReg(CReg).addImm(X86::sub_8bit); unsigned ResultReg = createResultReg(RC); BuildMI(MBB, DL, TII.get(OpReg), ResultReg).addReg(Op0Reg); @@ -1137,7 +1137,7 @@ // Then issue an extract_subreg. unsigned ResultReg = FastEmitInst_extractsubreg(MVT::i8, CopyReg, /*Kill=*/true, - X86::SUBREG_8BIT); + X86::sub_8bit); if (!ResultReg) return false; Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=104493&r1=104492&r2=104493&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Mon May 24 09:48:17 2010 @@ -1693,7 +1693,7 @@ Result, CurDAG->getTargetConstant(8, MVT::i8)), 0); // Then truncate it down to i8. - Result = CurDAG->getTargetExtractSubreg(X86::SUBREG_8BIT, dl, + Result = CurDAG->getTargetExtractSubreg(X86::sub_8bit, dl, MVT::i8, Result); } else { Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, @@ -1834,7 +1834,7 @@ CurDAG->getTargetConstant(8, MVT::i8)), 0); // Then truncate it down to i8. - Result = CurDAG->getTargetExtractSubreg(X86::SUBREG_8BIT, dl, + Result = CurDAG->getTargetExtractSubreg(X86::sub_8bit, dl, MVT::i8, Result); } else { Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, @@ -1883,7 +1883,7 @@ } // Extract the l-register. - SDValue Subreg = CurDAG->getTargetExtractSubreg(X86::SUBREG_8BIT, dl, + SDValue Subreg = CurDAG->getTargetExtractSubreg(X86::sub_8bit, dl, MVT::i8, Reg); // Emit a testb. @@ -1912,7 +1912,7 @@ Reg.getValueType(), Reg, RC), 0); // Extract the h-register. - SDValue Subreg = CurDAG->getTargetExtractSubreg(X86::SUBREG_8BIT_HI, dl, + SDValue Subreg = CurDAG->getTargetExtractSubreg(X86::sub_8bit_hi, dl, MVT::i8, Reg); // Emit a testb. No special NOREX tricks are needed since there's @@ -1930,7 +1930,7 @@ SDValue Reg = N0.getNode()->getOperand(0); // Extract the 16-bit subregister. - SDValue Subreg = CurDAG->getTargetExtractSubreg(X86::SUBREG_16BIT, dl, + SDValue Subreg = CurDAG->getTargetExtractSubreg(X86::sub_16bit, dl, MVT::i16, Reg); // Emit a testw. @@ -1946,7 +1946,7 @@ SDValue Reg = N0.getNode()->getOperand(0); // Extract the 32-bit subregister. - SDValue Subreg = CurDAG->getTargetExtractSubreg(X86::SUBREG_32BIT, dl, + SDValue Subreg = CurDAG->getTargetExtractSubreg(X86::sub_32bit, dl, MVT::i32, Reg); // Emit a testl. Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Instr64bit.td?rev=104493&r1=104492&r2=104493&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Instr64bit.td (original) +++ llvm/trunk/lib/Target/X86/X86Instr64bit.td Mon May 24 09:48:17 2010 @@ -498,7 +498,7 @@ // In the case of a 32-bit def that is known to implicitly zero-extend, // we can use a SUBREG_TO_REG. def : Pat<(i64 (zext def32:$src)), - (SUBREG_TO_REG (i64 0), GR32:$src, x86_subreg_32bit)>; + (SUBREG_TO_REG (i64 0), GR32:$src, sub_32bit)>; let neverHasSideEffects = 1 in { let Defs = [RAX], Uses = [EAX] in @@ -2004,14 +2004,14 @@ // defined after an extload. def : Pat<(extloadi64i32 addr:$src), (SUBREG_TO_REG (i64 0), (MOV32rm addr:$src), - x86_subreg_32bit)>; + sub_32bit)>; // anyext. Define these to do an explicit zero-extend to // avoid partial-register updates. def : Pat<(i64 (anyext GR8 :$src)), (MOVZX64rr8 GR8 :$src)>; def : Pat<(i64 (anyext GR16:$src)), (MOVZX64rr16 GR16 :$src)>; def : Pat<(i64 (anyext GR32:$src)), - (SUBREG_TO_REG (i64 0), GR32:$src, x86_subreg_32bit)>; + (SUBREG_TO_REG (i64 0), GR32:$src, sub_32bit)>; //===----------------------------------------------------------------------===// // Some peepholes @@ -2038,54 +2038,54 @@ (SUBREG_TO_REG (i64 0), (AND32ri - (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit), + (EXTRACT_SUBREG GR64:$src, sub_32bit), (i32 (GetLo32XForm imm:$imm))), - x86_subreg_32bit)>; + sub_32bit)>; // r & (2^32-1) ==> movz def : Pat<(and GR64:$src, 0x00000000FFFFFFFF), - (MOVZX64rr32 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit))>; + (MOVZX64rr32 (EXTRACT_SUBREG GR64:$src, sub_32bit))>; // r & (2^16-1) ==> movz def : Pat<(and GR64:$src, 0xffff), - (MOVZX64rr16 (i16 (EXTRACT_SUBREG GR64:$src, x86_subreg_16bit)))>; + (MOVZX64rr16 (i16 (EXTRACT_SUBREG GR64:$src, sub_16bit)))>; // r & (2^8-1) ==> movz def : Pat<(and GR64:$src, 0xff), - (MOVZX64rr8 (i8 (EXTRACT_SUBREG GR64:$src, x86_subreg_8bit)))>; + (MOVZX64rr8 (i8 (EXTRACT_SUBREG GR64:$src, sub_8bit)))>; // r & (2^8-1) ==> movz def : Pat<(and GR32:$src1, 0xff), - (MOVZX32rr8 (EXTRACT_SUBREG GR32:$src1, x86_subreg_8bit))>, + (MOVZX32rr8 (EXTRACT_SUBREG GR32:$src1, sub_8bit))>, Requires<[In64BitMode]>; // r & (2^8-1) ==> movz def : Pat<(and GR16:$src1, 0xff), - (MOVZX16rr8 (i8 (EXTRACT_SUBREG GR16:$src1, x86_subreg_8bit)))>, + (MOVZX16rr8 (i8 (EXTRACT_SUBREG GR16:$src1, sub_8bit)))>, Requires<[In64BitMode]>; // sext_inreg patterns def : Pat<(sext_inreg GR64:$src, i32), - (MOVSX64rr32 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit))>; + (MOVSX64rr32 (EXTRACT_SUBREG GR64:$src, sub_32bit))>; def : Pat<(sext_inreg GR64:$src, i16), - (MOVSX64rr16 (EXTRACT_SUBREG GR64:$src, x86_subreg_16bit))>; + (MOVSX64rr16 (EXTRACT_SUBREG GR64:$src, sub_16bit))>; def : Pat<(sext_inreg GR64:$src, i8), - (MOVSX64rr8 (EXTRACT_SUBREG GR64:$src, x86_subreg_8bit))>; + (MOVSX64rr8 (EXTRACT_SUBREG GR64:$src, sub_8bit))>; def : Pat<(sext_inreg GR32:$src, i8), - (MOVSX32rr8 (EXTRACT_SUBREG GR32:$src, x86_subreg_8bit))>, + (MOVSX32rr8 (EXTRACT_SUBREG GR32:$src, sub_8bit))>, Requires<[In64BitMode]>; def : Pat<(sext_inreg GR16:$src, i8), - (MOVSX16rr8 (i8 (EXTRACT_SUBREG GR16:$src, x86_subreg_8bit)))>, + (MOVSX16rr8 (i8 (EXTRACT_SUBREG GR16:$src, sub_8bit)))>, Requires<[In64BitMode]>; // trunc patterns def : Pat<(i32 (trunc GR64:$src)), - (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit)>; + (EXTRACT_SUBREG GR64:$src, sub_32bit)>; def : Pat<(i16 (trunc GR64:$src)), - (EXTRACT_SUBREG GR64:$src, x86_subreg_16bit)>; + (EXTRACT_SUBREG GR64:$src, sub_16bit)>; def : Pat<(i8 (trunc GR64:$src)), - (EXTRACT_SUBREG GR64:$src, x86_subreg_8bit)>; + (EXTRACT_SUBREG GR64:$src, sub_8bit)>; def : Pat<(i8 (trunc GR32:$src)), - (EXTRACT_SUBREG GR32:$src, x86_subreg_8bit)>, + (EXTRACT_SUBREG GR32:$src, sub_8bit)>, Requires<[In64BitMode]>; def : Pat<(i8 (trunc GR16:$src)), - (EXTRACT_SUBREG GR16:$src, x86_subreg_8bit)>, + (EXTRACT_SUBREG GR16:$src, sub_8bit)>, Requires<[In64BitMode]>; // h-register tricks. @@ -2101,67 +2101,67 @@ (i64 0), (MOVZX32_NOREXrr8 (EXTRACT_SUBREG (i64 (COPY_TO_REGCLASS GR64:$src, GR64_ABCD)), - x86_subreg_8bit_hi)), - x86_subreg_32bit)>; + sub_8bit_hi)), + sub_32bit)>; def : Pat<(and (srl_su GR32:$src, (i8 8)), (i32 255)), (MOVZX32_NOREXrr8 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)), - x86_subreg_8bit_hi))>, + sub_8bit_hi))>, Requires<[In64BitMode]>; def : Pat<(srl (and_su GR32:$src, 0xff00), (i8 8)), (MOVZX32_NOREXrr8 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)), - x86_subreg_8bit_hi))>, + sub_8bit_hi))>, Requires<[In64BitMode]>; def : Pat<(srl GR16:$src, (i8 8)), (EXTRACT_SUBREG (MOVZX32_NOREXrr8 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), - x86_subreg_8bit_hi)), - x86_subreg_16bit)>, + sub_8bit_hi)), + sub_16bit)>, Requires<[In64BitMode]>; def : Pat<(i32 (zext (srl_su GR16:$src, (i8 8)))), (MOVZX32_NOREXrr8 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), - x86_subreg_8bit_hi))>, + sub_8bit_hi))>, Requires<[In64BitMode]>; def : Pat<(i32 (anyext (srl_su GR16:$src, (i8 8)))), (MOVZX32_NOREXrr8 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), - x86_subreg_8bit_hi))>, + sub_8bit_hi))>, Requires<[In64BitMode]>; def : Pat<(i64 (zext (srl_su GR16:$src, (i8 8)))), (SUBREG_TO_REG (i64 0), (MOVZX32_NOREXrr8 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), - x86_subreg_8bit_hi)), - x86_subreg_32bit)>; + sub_8bit_hi)), + sub_32bit)>; def : Pat<(i64 (anyext (srl_su GR16:$src, (i8 8)))), (SUBREG_TO_REG (i64 0), (MOVZX32_NOREXrr8 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), - x86_subreg_8bit_hi)), - x86_subreg_32bit)>; + sub_8bit_hi)), + sub_32bit)>; // h-register extract and store. def : Pat<(store (i8 (trunc_su (srl_su GR64:$src, (i8 8)))), addr:$dst), (MOV8mr_NOREX addr:$dst, (EXTRACT_SUBREG (i64 (COPY_TO_REGCLASS GR64:$src, GR64_ABCD)), - x86_subreg_8bit_hi))>; + sub_8bit_hi))>; def : Pat<(store (i8 (trunc_su (srl_su GR32:$src, (i8 8)))), addr:$dst), (MOV8mr_NOREX addr:$dst, (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)), - x86_subreg_8bit_hi))>, + sub_8bit_hi))>, Requires<[In64BitMode]>; def : Pat<(store (i8 (trunc_su (srl_su GR16:$src, (i8 8)))), addr:$dst), (MOV8mr_NOREX addr:$dst, (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), - x86_subreg_8bit_hi))>, + sub_8bit_hi))>, Requires<[In64BitMode]>; // (shl x, 1) ==> (add x, x) Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=104493&r1=104492&r2=104493&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Mon May 24 09:48:17 2010 @@ -1154,7 +1154,7 @@ BuildMI(*MFI, MBBI, MI->getDebugLoc(), get(X86::INSERT_SUBREG),leaInReg) .addReg(leaInReg) .addReg(Src, getKillRegState(isKill)) - .addImm(X86::SUBREG_16BIT); + .addImm(X86::sub_16bit); MachineInstrBuilder MIB = BuildMI(*MFI, MBBI, MI->getDebugLoc(), get(Opc), leaOutReg); @@ -1198,7 +1198,7 @@ BuildMI(*MFI, MIB, MI->getDebugLoc(), get(X86::INSERT_SUBREG),leaInReg2) .addReg(leaInReg2) .addReg(Src2, getKillRegState(isKill2)) - .addImm(X86::SUBREG_16BIT); + .addImm(X86::sub_16bit); addRegReg(MIB, leaInReg, true, leaInReg2, true); } if (LV && isKill2 && InsMI2) @@ -1212,7 +1212,7 @@ BuildMI(*MFI, MBBI, MI->getDebugLoc(), get(X86::EXTRACT_SUBREG)) .addReg(Dest, RegState::Define | getDeadRegState(isDead)) .addReg(leaOutReg, RegState::Kill) - .addImm(X86::SUBREG_16BIT); + .addImm(X86::sub_16bit); if (LV) { // Update live variables @@ -2483,9 +2483,9 @@ unsigned DstReg = NewMI->getOperand(0).getReg(); if (TargetRegisterInfo::isPhysicalRegister(DstReg)) NewMI->getOperand(0).setReg(RI.getSubReg(DstReg, - X86::x86_subreg_32bit)); + X86::sub_32bit)); else - NewMI->getOperand(0).setSubReg(X86::x86_subreg_32bit); + NewMI->getOperand(0).setSubReg(X86::sub_32bit); } return NewMI; } Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=104493&r1=104492&r2=104493&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Mon May 24 09:48:17 2010 @@ -4503,7 +4503,7 @@ // Except for i16 -> i32 since isel expect i16 ops to be promoted to i32. def : Pat<(i32 (anyext GR16:$src)), - (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR16:$src, x86_subreg_16bit)>; + (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR16:$src, sub_16bit)>; //===----------------------------------------------------------------------===// @@ -4523,81 +4523,81 @@ // r & (2^16-1) ==> movz def : Pat<(and GR32:$src1, 0xffff), - (MOVZX32rr16 (EXTRACT_SUBREG GR32:$src1, x86_subreg_16bit))>; + (MOVZX32rr16 (EXTRACT_SUBREG GR32:$src1, sub_16bit))>; // r & (2^8-1) ==> movz def : Pat<(and GR32:$src1, 0xff), (MOVZX32rr8 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src1, GR32_ABCD)), - x86_subreg_8bit))>, + sub_8bit))>, Requires<[In32BitMode]>; // r & (2^8-1) ==> movz def : Pat<(and GR16:$src1, 0xff), (MOVZX16rr8 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src1, GR16_ABCD)), - x86_subreg_8bit))>, + sub_8bit))>, Requires<[In32BitMode]>; // sext_inreg patterns def : Pat<(sext_inreg GR32:$src, i16), - (MOVSX32rr16 (EXTRACT_SUBREG GR32:$src, x86_subreg_16bit))>; + (MOVSX32rr16 (EXTRACT_SUBREG GR32:$src, sub_16bit))>; def : Pat<(sext_inreg GR32:$src, i8), (MOVSX32rr8 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)), - x86_subreg_8bit))>, + sub_8bit))>, Requires<[In32BitMode]>; def : Pat<(sext_inreg GR16:$src, i8), (MOVSX16rr8 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), - x86_subreg_8bit))>, + sub_8bit))>, Requires<[In32BitMode]>; // trunc patterns def : Pat<(i16 (trunc GR32:$src)), - (EXTRACT_SUBREG GR32:$src, x86_subreg_16bit)>; + (EXTRACT_SUBREG GR32:$src, sub_16bit)>; def : Pat<(i8 (trunc GR32:$src)), (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)), - x86_subreg_8bit)>, + sub_8bit)>, Requires<[In32BitMode]>; def : Pat<(i8 (trunc GR16:$src)), (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), - x86_subreg_8bit)>, + sub_8bit)>, Requires<[In32BitMode]>; // h-register tricks def : Pat<(i8 (trunc (srl_su GR16:$src, (i8 8)))), (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), - x86_subreg_8bit_hi)>, + sub_8bit_hi)>, Requires<[In32BitMode]>; def : Pat<(i8 (trunc (srl_su GR32:$src, (i8 8)))), (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)), - x86_subreg_8bit_hi)>, + sub_8bit_hi)>, Requires<[In32BitMode]>; def : Pat<(srl GR16:$src, (i8 8)), (EXTRACT_SUBREG (MOVZX32rr8 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), - x86_subreg_8bit_hi)), - x86_subreg_16bit)>, + sub_8bit_hi)), + sub_16bit)>, Requires<[In32BitMode]>; def : Pat<(i32 (zext (srl_su GR16:$src, (i8 8)))), (MOVZX32rr8 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), - x86_subreg_8bit_hi))>, + sub_8bit_hi))>, Requires<[In32BitMode]>; def : Pat<(i32 (anyext (srl_su GR16:$src, (i8 8)))), (MOVZX32rr8 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), - x86_subreg_8bit_hi))>, + sub_8bit_hi))>, Requires<[In32BitMode]>; def : Pat<(and (srl_su GR32:$src, (i8 8)), (i32 255)), (MOVZX32rr8 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)), - x86_subreg_8bit_hi))>, + sub_8bit_hi))>, Requires<[In32BitMode]>; def : Pat<(srl (and_su GR32:$src, 0xff00), (i8 8)), (MOVZX32rr8 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)), - x86_subreg_8bit_hi))>, + sub_8bit_hi))>, Requires<[In32BitMode]>; // (shl x, 1) ==> (add x, x) Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=104493&r1=104492&r2=104493&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Mon May 24 09:48:17 2010 @@ -387,11 +387,11 @@ let AddedComplexity = 15 in def : Pat<(v4f32 (movl VR128:$src1, VR128:$src2)), (MOVSSrr (v4f32 VR128:$src1), - (EXTRACT_SUBREG (v4f32 VR128:$src2), x86_subreg_ss))>; + (EXTRACT_SUBREG (v4f32 VR128:$src2), sub_ss))>; // Implicitly promote a 32-bit scalar to a vector. def : Pat<(v4f32 (scalar_to_vector FR32:$src)), - (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src, x86_subreg_ss)>; + (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src, sub_ss)>; // Loading from memory automatically zeroing upper bits. let canFoldAsLoad = 1, isReMaterializable = 1 in @@ -403,11 +403,11 @@ // with SUBREG_TO_REG. let AddedComplexity = 20 in { def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))), - (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), x86_subreg_ss)>; + (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), sub_ss)>; def : Pat<(v4f32 (scalar_to_vector (loadf32 addr:$src))), - (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), x86_subreg_ss)>; + (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), sub_ss)>; def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))), - (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), x86_subreg_ss)>; + (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), sub_ss)>; } // Store scalar value to memory. @@ -419,7 +419,7 @@ def : Pat<(store (f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))), addr:$dst), (MOVSSmr addr:$dst, - (EXTRACT_SUBREG (v4f32 VR128:$src), x86_subreg_ss))>; + (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>; // Conversion instructions def CVTTSS2SIrr : SSI<0x2C, MRMSrcReg, (outs GR32:$dst), (ins FR32:$src), @@ -1131,7 +1131,7 @@ def : Pat<(v16i8 immAllZerosV), (V_SET0PI)>; def : Pat<(f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))), - (f32 (EXTRACT_SUBREG (v4f32 VR128:$src), x86_subreg_ss))>; + (f32 (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>; //===---------------------------------------------------------------------===// // SSE2 Instructions @@ -1153,11 +1153,11 @@ let AddedComplexity = 15 in def : Pat<(v2f64 (movl VR128:$src1, VR128:$src2)), (MOVSDrr (v2f64 VR128:$src1), - (EXTRACT_SUBREG (v2f64 VR128:$src2), x86_subreg_sd))>; + (EXTRACT_SUBREG (v2f64 VR128:$src2), sub_sd))>; // Implicitly promote a 64-bit scalar to a vector. def : Pat<(v2f64 (scalar_to_vector FR64:$src)), - (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src, x86_subreg_sd)>; + (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src, sub_sd)>; // Loading from memory automatically zeroing upper bits. let canFoldAsLoad = 1, isReMaterializable = 1, AddedComplexity = 20 in @@ -1169,15 +1169,15 @@ // with SUBREG_TO_REG. let AddedComplexity = 20 in { def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))), - (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), x86_subreg_sd)>; + (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>; def : Pat<(v2f64 (scalar_to_vector (loadf64 addr:$src))), - (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), x86_subreg_sd)>; + (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>; def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))), - (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), x86_subreg_sd)>; + (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>; def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))), - (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), x86_subreg_sd)>; + (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>; def : Pat<(v2f64 (X86vzload addr:$src)), - (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), x86_subreg_sd)>; + (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>; } // Store scalar value to memory. @@ -1189,7 +1189,7 @@ def : Pat<(store (f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))), addr:$dst), (MOVSDmr addr:$dst, - (EXTRACT_SUBREG (v2f64 VR128:$src), x86_subreg_sd))>; + (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd))>; // Conversion instructions def CVTTSD2SIrr : SDI<0x2C, MRMSrcReg, (outs GR32:$dst), (ins FR64:$src), @@ -2467,7 +2467,7 @@ (iPTR 0))), addr:$dst)]>; def : Pat<(f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))), - (f64 (EXTRACT_SUBREG (v2f64 VR128:$src), x86_subreg_sd))>; + (f64 (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd))>; def MOVPDI2DIrr : PDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src), "movd\t{$src, $dst|$dst, $src}", @@ -3047,10 +3047,10 @@ (MOVSSrr (v4f32 (V_SET0PS)), FR32:$src)>; def : Pat<(v4f32 (X86vzmovl (v4f32 VR128:$src))), (MOVSSrr (v4f32 (V_SET0PS)), - (f32 (EXTRACT_SUBREG (v4f32 VR128:$src), x86_subreg_ss)))>; + (f32 (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)))>; def : Pat<(v4i32 (X86vzmovl (v4i32 VR128:$src))), (MOVSSrr (v4i32 (V_SET0PI)), - (EXTRACT_SUBREG (v4i32 VR128:$src), x86_subreg_ss))>; + (EXTRACT_SUBREG (v4i32 VR128:$src), sub_ss))>; } // Splat v2f64 / v2i64 @@ -3186,17 +3186,17 @@ // Setting the lowest element in the vector. def : Pat<(v4i32 (movl VR128:$src1, VR128:$src2)), (MOVSSrr (v4i32 VR128:$src1), - (EXTRACT_SUBREG (v4i32 VR128:$src2), x86_subreg_ss))>; + (EXTRACT_SUBREG (v4i32 VR128:$src2), sub_ss))>; def : Pat<(v2i64 (movl VR128:$src1, VR128:$src2)), (MOVSDrr (v2i64 VR128:$src1), - (EXTRACT_SUBREG (v2i64 VR128:$src2), x86_subreg_sd))>; + (EXTRACT_SUBREG (v2i64 VR128:$src2), sub_sd))>; // vector_shuffle v1, v2 <4, 5, 2, 3> using movsd def : Pat<(v4f32 (movlp VR128:$src1, VR128:$src2)), - (MOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, x86_subreg_sd))>, + (MOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, sub_sd))>, Requires<[HasSSE2]>; def : Pat<(v4i32 (movlp VR128:$src1, VR128:$src2)), - (MOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, x86_subreg_sd))>, + (MOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, sub_sd))>, Requires<[HasSSE2]>; } Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.h?rev=104493&r1=104492&r2=104493&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.h (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.h Mon May 24 09:48:17 2010 @@ -30,16 +30,6 @@ }; } -namespace X86 { - /// SubregIndex - The index of various sized subregister classes. Note that - /// these indices must be kept in sync with the class indices in the - /// X86RegisterInfo.td file. - enum SubregIndex { - SUBREG_8BIT = 1, SUBREG_8BIT_HI = 2, SUBREG_16BIT = 3, SUBREG_32BIT = 4, - SUBREG_SS = 1, SUBREG_SD = 2, SUBREG_XMM = 3 - }; -} - /// DWARFFlavour - Flavour of dwarf regnumbers /// namespace DWARFFlavour { Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.td?rev=104493&r1=104492&r2=104493&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.td Mon May 24 09:48:17 2010 @@ -19,14 +19,14 @@ let Namespace = "X86" in { // Subregister indices. - def x86_subreg_8bit : SubRegIndex { let NumberHack = 1; } - def x86_subreg_8bit_hi : SubRegIndex { let NumberHack = 2; } - def x86_subreg_16bit : SubRegIndex { let NumberHack = 3; } - def x86_subreg_32bit : SubRegIndex { let NumberHack = 4; } - - def x86_subreg_ss : SubRegIndex { let NumberHack = 1; } - def x86_subreg_sd : SubRegIndex { let NumberHack = 2; } - def x86_subreg_xmm : SubRegIndex { let NumberHack = 3; } + def sub_8bit : SubRegIndex { let NumberHack = 1; } + def sub_8bit_hi : SubRegIndex { let NumberHack = 2; } + def sub_16bit : SubRegIndex { let NumberHack = 3; } + def sub_32bit : SubRegIndex { let NumberHack = 4; } + + def sub_ss : SubRegIndex { let NumberHack = 1; } + def sub_sd : SubRegIndex { let NumberHack = 2; } + def sub_xmm : SubRegIndex { let NumberHack = 3; } // In the register alias definitions below, we define which registers alias From stoklund at 2pi.dk Mon May 24 11:54:33 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 24 May 2010 16:54:33 -0000 Subject: [llvm-commits] [llvm] r104508 - in /llvm/trunk/lib/Target/ARM: ARMBaseInstrInfo.cpp ARMBaseRegisterInfo.cpp ARMExpandPseudoInsts.cpp ARMISelDAGToDAG.cpp ARMInstrNEON.td ARMRegisterInfo.h ARMRegisterInfo.td AsmPrinter/ARMAsmPrinter.cpp AsmPrinter/ARMInstPrinter.cpp NEONPreAllocPass.cpp Message-ID: <20100524165433.33F18312800A@llvm.org> Author: stoklund Date: Mon May 24 11:54:32 2010 New Revision: 104508 URL: http://llvm.org/viewvc/llvm-project?rev=104508&view=rev Log: Switch ARMRegisterInfo.td to use SubRegIndex and eliminate the parallel enums from ARMRegisterInfo.h Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp llvm/trunk/lib/Target/ARM/ARMInstrNEON.td llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp llvm/trunk/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp llvm/trunk/lib/Target/ARM/NEONPreAllocPass.cpp Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp?rev=104508&r1=104507&r2=104508&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp Mon May 24 11:54:32 2010 @@ -834,10 +834,10 @@ // spilled def has a sub-register index. MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::VST2q32)) .addFrameIndex(FI).addImm(128); - MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_0, getKillRegState(isKill), TRI); - MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_1, 0, TRI); - MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_2, 0, TRI); - MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_3, 0, TRI); + MIB = AddDReg(MIB, SrcReg, ARM::dsub_0, getKillRegState(isKill), TRI); + MIB = AddDReg(MIB, SrcReg, ARM::dsub_1, 0, TRI); + MIB = AddDReg(MIB, SrcReg, ARM::dsub_2, 0, TRI); + MIB = AddDReg(MIB, SrcReg, ARM::dsub_3, 0, TRI); AddDefaultPred(MIB.addMemOperand(MMO)); } else { MachineInstrBuilder MIB = @@ -845,10 +845,10 @@ .addFrameIndex(FI) .addImm(ARM_AM::getAM5Opc(ARM_AM::ia, 4))) .addMemOperand(MMO); - MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_0, getKillRegState(isKill), TRI); - MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_1, 0, TRI); - MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_2, 0, TRI); - AddDReg(MIB, SrcReg, ARM::DSUBREG_3, 0, TRI); + MIB = AddDReg(MIB, SrcReg, ARM::dsub_0, getKillRegState(isKill), TRI); + MIB = AddDReg(MIB, SrcReg, ARM::dsub_1, 0, TRI); + MIB = AddDReg(MIB, SrcReg, ARM::dsub_2, 0, TRI); + AddDReg(MIB, SrcReg, ARM::dsub_3, 0, TRI); } } else { assert(RC == ARM::QQQQPRRegisterClass && "Unknown regclass!"); @@ -857,14 +857,14 @@ .addFrameIndex(FI) .addImm(ARM_AM::getAM5Opc(ARM_AM::ia, 4))) .addMemOperand(MMO); - MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_0, getKillRegState(isKill), TRI); - MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_1, 0, TRI); - MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_2, 0, TRI); - MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_3, 0, TRI); - MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_4, 0, TRI); - MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_5, 0, TRI); - MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_6, 0, TRI); - AddDReg(MIB, SrcReg, ARM::DSUBREG_7, 0, TRI); + MIB = AddDReg(MIB, SrcReg, ARM::dsub_0, getKillRegState(isKill), TRI); + MIB = AddDReg(MIB, SrcReg, ARM::dsub_1, 0, TRI); + MIB = AddDReg(MIB, SrcReg, ARM::dsub_2, 0, TRI); + MIB = AddDReg(MIB, SrcReg, ARM::dsub_3, 0, TRI); + MIB = AddDReg(MIB, SrcReg, ARM::dsub_4, 0, TRI); + MIB = AddDReg(MIB, SrcReg, ARM::dsub_5, 0, TRI); + MIB = AddDReg(MIB, SrcReg, ARM::dsub_6, 0, TRI); + AddDReg(MIB, SrcReg, ARM::dsub_7, 0, TRI); } } @@ -916,10 +916,10 @@ } else if (RC == ARM::QQPRRegisterClass || RC == ARM::QQPR_VFP2RegisterClass){ if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) { MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::VLD2q32)); - MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_0, RegState::Define, TRI); - MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_1, RegState::Define, TRI); - MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_2, RegState::Define, TRI); - MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_3, RegState::Define, TRI); + MIB = AddDReg(MIB, DestReg, ARM::dsub_0, RegState::Define, TRI); + MIB = AddDReg(MIB, DestReg, ARM::dsub_1, RegState::Define, TRI); + MIB = AddDReg(MIB, DestReg, ARM::dsub_2, RegState::Define, TRI); + MIB = AddDReg(MIB, DestReg, ARM::dsub_3, RegState::Define, TRI); AddDefaultPred(MIB.addFrameIndex(FI).addImm(128).addMemOperand(MMO)); } else { MachineInstrBuilder MIB = @@ -927,10 +927,10 @@ .addFrameIndex(FI) .addImm(ARM_AM::getAM5Opc(ARM_AM::ia, 4))) .addMemOperand(MMO); - MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_0, RegState::Define, TRI); - MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_1, RegState::Define, TRI); - MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_2, RegState::Define, TRI); - AddDReg(MIB, DestReg, ARM::DSUBREG_3, RegState::Define, TRI); + MIB = AddDReg(MIB, DestReg, ARM::dsub_0, RegState::Define, TRI); + MIB = AddDReg(MIB, DestReg, ARM::dsub_1, RegState::Define, TRI); + MIB = AddDReg(MIB, DestReg, ARM::dsub_2, RegState::Define, TRI); + AddDReg(MIB, DestReg, ARM::dsub_3, RegState::Define, TRI); } } else { assert(RC == ARM::QQQQPRRegisterClass && "Unknown regclass!"); @@ -939,14 +939,14 @@ .addFrameIndex(FI) .addImm(ARM_AM::getAM5Opc(ARM_AM::ia, 4))) .addMemOperand(MMO); - MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_0, RegState::Define, TRI); - MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_1, RegState::Define, TRI); - MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_2, RegState::Define, TRI); - MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_3, RegState::Define, TRI); - MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_4, RegState::Define, TRI); - MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_5, RegState::Define, TRI); - MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_6, RegState::Define, TRI); - AddDReg(MIB, DestReg, ARM::DSUBREG_7, RegState::Define, TRI); + MIB = AddDReg(MIB, DestReg, ARM::dsub_0, RegState::Define, TRI); + MIB = AddDReg(MIB, DestReg, ARM::dsub_1, RegState::Define, TRI); + MIB = AddDReg(MIB, DestReg, ARM::dsub_2, RegState::Define, TRI); + MIB = AddDReg(MIB, DestReg, ARM::dsub_3, RegState::Define, TRI); + MIB = AddDReg(MIB, DestReg, ARM::dsub_4, RegState::Define, TRI); + MIB = AddDReg(MIB, DestReg, ARM::dsub_5, RegState::Define, TRI); + MIB = AddDReg(MIB, DestReg, ARM::dsub_6, RegState::Define, TRI); + AddDReg(MIB, DestReg, ARM::dsub_7, RegState::Define, TRI); } } Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp?rev=104508&r1=104507&r2=104508&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Mon May 24 11:54:32 2010 @@ -365,101 +365,101 @@ if (NumRegs == 8) { // 8 D registers -> 1 QQQQ register. return (Size == 512 && - SubIndices[0] == ARM::DSUBREG_0 && - SubIndices[1] == ARM::DSUBREG_1 && - SubIndices[2] == ARM::DSUBREG_2 && - SubIndices[3] == ARM::DSUBREG_3 && - SubIndices[4] == ARM::DSUBREG_4 && - SubIndices[5] == ARM::DSUBREG_5 && - SubIndices[6] == ARM::DSUBREG_6 && - SubIndices[7] == ARM::DSUBREG_7); + SubIndices[0] == ARM::dsub_0 && + SubIndices[1] == ARM::dsub_1 && + SubIndices[2] == ARM::dsub_2 && + SubIndices[3] == ARM::dsub_3 && + SubIndices[4] == ARM::dsub_4 && + SubIndices[5] == ARM::dsub_5 && + SubIndices[6] == ARM::dsub_6 && + SubIndices[7] == ARM::dsub_7); } else if (NumRegs == 4) { - if (SubIndices[0] == ARM::QSUBREG_0) { + if (SubIndices[0] == ARM::qsub_0) { // 4 Q registers -> 1 QQQQ register. return (Size == 512 && - SubIndices[1] == ARM::QSUBREG_1 && - SubIndices[2] == ARM::QSUBREG_2 && - SubIndices[3] == ARM::QSUBREG_3); - } else if (SubIndices[0] == ARM::DSUBREG_0) { + SubIndices[1] == ARM::qsub_1 && + SubIndices[2] == ARM::qsub_2 && + SubIndices[3] == ARM::qsub_3); + } else if (SubIndices[0] == ARM::dsub_0) { // 4 D registers -> 1 QQ register. if (Size >= 256 && - SubIndices[1] == ARM::DSUBREG_1 && - SubIndices[2] == ARM::DSUBREG_2 && - SubIndices[3] == ARM::DSUBREG_3) { + SubIndices[1] == ARM::dsub_1 && + SubIndices[2] == ARM::dsub_2 && + SubIndices[3] == ARM::dsub_3) { if (Size == 512) - NewSubIdx = ARM::QQSUBREG_0; + NewSubIdx = ARM::qqsub_0; return true; } - } else if (SubIndices[0] == ARM::DSUBREG_4) { + } else if (SubIndices[0] == ARM::dsub_4) { // 4 D registers -> 1 QQ register (2nd). if (Size == 512 && - SubIndices[1] == ARM::DSUBREG_5 && - SubIndices[2] == ARM::DSUBREG_6 && - SubIndices[3] == ARM::DSUBREG_7) { - NewSubIdx = ARM::QQSUBREG_1; + SubIndices[1] == ARM::dsub_5 && + SubIndices[2] == ARM::dsub_6 && + SubIndices[3] == ARM::dsub_7) { + NewSubIdx = ARM::qqsub_1; return true; } - } else if (SubIndices[0] == ARM::SSUBREG_0) { + } else if (SubIndices[0] == ARM::ssub_0) { // 4 S registers -> 1 Q register. if (Size >= 128 && - SubIndices[1] == ARM::SSUBREG_1 && - SubIndices[2] == ARM::SSUBREG_2 && - SubIndices[3] == ARM::SSUBREG_3) { + SubIndices[1] == ARM::ssub_1 && + SubIndices[2] == ARM::ssub_2 && + SubIndices[3] == ARM::ssub_3) { if (Size >= 256) - NewSubIdx = ARM::QSUBREG_0; + NewSubIdx = ARM::qsub_0; return true; } } } else if (NumRegs == 2) { - if (SubIndices[0] == ARM::QSUBREG_0) { + if (SubIndices[0] == ARM::qsub_0) { // 2 Q registers -> 1 QQ register. - if (Size >= 256 && SubIndices[1] == ARM::QSUBREG_1) { + if (Size >= 256 && SubIndices[1] == ARM::qsub_1) { if (Size == 512) - NewSubIdx = ARM::QQSUBREG_0; + NewSubIdx = ARM::qqsub_0; return true; } - } else if (SubIndices[0] == ARM::QSUBREG_2) { + } else if (SubIndices[0] == ARM::qsub_2) { // 2 Q registers -> 1 QQ register (2nd). - if (Size == 512 && SubIndices[1] == ARM::QSUBREG_3) { - NewSubIdx = ARM::QQSUBREG_1; + if (Size == 512 && SubIndices[1] == ARM::qsub_3) { + NewSubIdx = ARM::qqsub_1; return true; } - } else if (SubIndices[0] == ARM::DSUBREG_0) { + } else if (SubIndices[0] == ARM::dsub_0) { // 2 D registers -> 1 Q register. - if (Size >= 128 && SubIndices[1] == ARM::DSUBREG_1) { + if (Size >= 128 && SubIndices[1] == ARM::dsub_1) { if (Size >= 256) - NewSubIdx = ARM::QSUBREG_0; + NewSubIdx = ARM::qsub_0; return true; } - } else if (SubIndices[0] == ARM::DSUBREG_2) { + } else if (SubIndices[0] == ARM::dsub_2) { // 2 D registers -> 1 Q register (2nd). - if (Size >= 256 && SubIndices[1] == ARM::DSUBREG_3) { - NewSubIdx = ARM::QSUBREG_1; + if (Size >= 256 && SubIndices[1] == ARM::dsub_3) { + NewSubIdx = ARM::qsub_1; return true; } - } else if (SubIndices[0] == ARM::DSUBREG_4) { + } else if (SubIndices[0] == ARM::dsub_4) { // 2 D registers -> 1 Q register (3rd). - if (Size == 512 && SubIndices[1] == ARM::DSUBREG_5) { - NewSubIdx = ARM::QSUBREG_2; + if (Size == 512 && SubIndices[1] == ARM::dsub_5) { + NewSubIdx = ARM::qsub_2; return true; } - } else if (SubIndices[0] == ARM::DSUBREG_6) { + } else if (SubIndices[0] == ARM::dsub_6) { // 2 D registers -> 1 Q register (3rd). - if (Size == 512 && SubIndices[1] == ARM::DSUBREG_7) { - NewSubIdx = ARM::QSUBREG_3; + if (Size == 512 && SubIndices[1] == ARM::dsub_7) { + NewSubIdx = ARM::qsub_3; return true; } - } else if (SubIndices[0] == ARM::SSUBREG_0) { + } else if (SubIndices[0] == ARM::ssub_0) { // 2 S registers -> 1 D register. - if (SubIndices[1] == ARM::SSUBREG_1) { + if (SubIndices[1] == ARM::ssub_1) { if (Size >= 128) - NewSubIdx = ARM::DSUBREG_0; + NewSubIdx = ARM::dsub_0; return true; } - } else if (SubIndices[0] == ARM::SSUBREG_2) { + } else if (SubIndices[0] == ARM::ssub_2) { // 2 S registers -> 1 D register (2nd). - if (Size >= 128 && SubIndices[1] == ARM::SSUBREG_3) { - NewSubIdx = ARM::DSUBREG_1; + if (Size >= 128 && SubIndices[1] == ARM::ssub_3) { + NewSubIdx = ARM::dsub_1; return true; } } Modified: llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp?rev=104508&r1=104507&r2=104508&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp Mon May 24 11:54:32 2010 @@ -135,12 +135,12 @@ case ARM::VMOVQQ: { unsigned DstReg = MI.getOperand(0).getReg(); bool DstIsDead = MI.getOperand(0).isDead(); - unsigned EvenDst = TRI->getSubReg(DstReg, ARM::QSUBREG_0); - unsigned OddDst = TRI->getSubReg(DstReg, ARM::QSUBREG_1); + unsigned EvenDst = TRI->getSubReg(DstReg, ARM::qsub_0); + unsigned OddDst = TRI->getSubReg(DstReg, ARM::qsub_1); unsigned SrcReg = MI.getOperand(1).getReg(); bool SrcIsKill = MI.getOperand(1).isKill(); - unsigned EvenSrc = TRI->getSubReg(SrcReg, ARM::QSUBREG_0); - unsigned OddSrc = TRI->getSubReg(SrcReg, ARM::QSUBREG_1); + unsigned EvenSrc = TRI->getSubReg(SrcReg, ARM::qsub_0); + unsigned OddSrc = TRI->getSubReg(SrcReg, ARM::qsub_1); MachineInstrBuilder Even = AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::VMOVQ)) Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=104508&r1=104507&r2=104508&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Mon May 24 11:54:32 2010 @@ -964,8 +964,8 @@ /// SDNode *ARMDAGToDAGISel::PairDRegs(EVT VT, SDValue V0, SDValue V1) { DebugLoc dl = V0.getNode()->getDebugLoc(); - SDValue SubReg0 = CurDAG->getTargetConstant(ARM::DSUBREG_0, MVT::i32); - SDValue SubReg1 = CurDAG->getTargetConstant(ARM::DSUBREG_1, MVT::i32); + SDValue SubReg0 = CurDAG->getTargetConstant(ARM::dsub_0, MVT::i32); + SDValue SubReg1 = CurDAG->getTargetConstant(ARM::dsub_1, MVT::i32); if (llvm::ModelWithRegSequence()) { const SDValue Ops[] = { V0, SubReg0, V1, SubReg1 }; return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 4); @@ -982,8 +982,8 @@ /// SDNode *ARMDAGToDAGISel::PairQRegs(EVT VT, SDValue V0, SDValue V1) { DebugLoc dl = V0.getNode()->getDebugLoc(); - SDValue SubReg0 = CurDAG->getTargetConstant(ARM::QSUBREG_0, MVT::i32); - SDValue SubReg1 = CurDAG->getTargetConstant(ARM::QSUBREG_1, MVT::i32); + SDValue SubReg0 = CurDAG->getTargetConstant(ARM::qsub_0, MVT::i32); + SDValue SubReg1 = CurDAG->getTargetConstant(ARM::qsub_1, MVT::i32); const SDValue Ops[] = { V0, SubReg0, V1, SubReg1 }; return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 4); } @@ -993,10 +993,10 @@ SDNode *ARMDAGToDAGISel::QuadDRegs(EVT VT, SDValue V0, SDValue V1, SDValue V2, SDValue V3) { DebugLoc dl = V0.getNode()->getDebugLoc(); - SDValue SubReg0 = CurDAG->getTargetConstant(ARM::DSUBREG_0, MVT::i32); - SDValue SubReg1 = CurDAG->getTargetConstant(ARM::DSUBREG_1, MVT::i32); - SDValue SubReg2 = CurDAG->getTargetConstant(ARM::DSUBREG_2, MVT::i32); - SDValue SubReg3 = CurDAG->getTargetConstant(ARM::DSUBREG_3, MVT::i32); + SDValue SubReg0 = CurDAG->getTargetConstant(ARM::dsub_0, MVT::i32); + SDValue SubReg1 = CurDAG->getTargetConstant(ARM::dsub_1, MVT::i32); + SDValue SubReg2 = CurDAG->getTargetConstant(ARM::dsub_2, MVT::i32); + SDValue SubReg3 = CurDAG->getTargetConstant(ARM::dsub_3, MVT::i32); const SDValue Ops[] = { V0, SubReg0, V1, SubReg1, V2, SubReg2, V3, SubReg3 }; return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 8); } @@ -1006,10 +1006,10 @@ SDNode *ARMDAGToDAGISel::QuadQRegs(EVT VT, SDValue V0, SDValue V1, SDValue V2, SDValue V3) { DebugLoc dl = V0.getNode()->getDebugLoc(); - SDValue SubReg0 = CurDAG->getTargetConstant(ARM::QSUBREG_0, MVT::i32); - SDValue SubReg1 = CurDAG->getTargetConstant(ARM::QSUBREG_1, MVT::i32); - SDValue SubReg2 = CurDAG->getTargetConstant(ARM::QSUBREG_2, MVT::i32); - SDValue SubReg3 = CurDAG->getTargetConstant(ARM::QSUBREG_3, MVT::i32); + SDValue SubReg0 = CurDAG->getTargetConstant(ARM::qsub_0, MVT::i32); + SDValue SubReg1 = CurDAG->getTargetConstant(ARM::qsub_1, MVT::i32); + SDValue SubReg2 = CurDAG->getTargetConstant(ARM::qsub_2, MVT::i32); + SDValue SubReg3 = CurDAG->getTargetConstant(ARM::qsub_3, MVT::i32); const SDValue Ops[] = { V0, SubReg0, V1, SubReg1, V2, SubReg2, V3, SubReg3 }; return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 8); } @@ -1021,14 +1021,14 @@ SDValue V4, SDValue V5, SDValue V6, SDValue V7) { DebugLoc dl = V0.getNode()->getDebugLoc(); - SDValue SubReg0 = CurDAG->getTargetConstant(ARM::DSUBREG_0, MVT::i32); - SDValue SubReg1 = CurDAG->getTargetConstant(ARM::DSUBREG_1, MVT::i32); - SDValue SubReg2 = CurDAG->getTargetConstant(ARM::DSUBREG_2, MVT::i32); - SDValue SubReg3 = CurDAG->getTargetConstant(ARM::DSUBREG_3, MVT::i32); - SDValue SubReg4 = CurDAG->getTargetConstant(ARM::DSUBREG_4, MVT::i32); - SDValue SubReg5 = CurDAG->getTargetConstant(ARM::DSUBREG_5, MVT::i32); - SDValue SubReg6 = CurDAG->getTargetConstant(ARM::DSUBREG_6, MVT::i32); - SDValue SubReg7 = CurDAG->getTargetConstant(ARM::DSUBREG_7, MVT::i32); + SDValue SubReg0 = CurDAG->getTargetConstant(ARM::dsub_0, MVT::i32); + SDValue SubReg1 = CurDAG->getTargetConstant(ARM::dsub_1, MVT::i32); + SDValue SubReg2 = CurDAG->getTargetConstant(ARM::dsub_2, MVT::i32); + SDValue SubReg3 = CurDAG->getTargetConstant(ARM::dsub_3, MVT::i32); + SDValue SubReg4 = CurDAG->getTargetConstant(ARM::dsub_4, MVT::i32); + SDValue SubReg5 = CurDAG->getTargetConstant(ARM::dsub_5, MVT::i32); + SDValue SubReg6 = CurDAG->getTargetConstant(ARM::dsub_6, MVT::i32); + SDValue SubReg7 = CurDAG->getTargetConstant(ARM::dsub_7, MVT::i32); const SDValue Ops[] ={ V0, SubReg0, V1, SubReg1, V2, SubReg2, V3, SubReg3, V4, SubReg4, V5, SubReg5, V6, SubReg6, V7, SubReg7 }; return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 16); @@ -1108,7 +1108,7 @@ } for (unsigned Vec = 0; Vec < NumVecs; ++Vec) { - SDValue D = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_0+Vec, + SDValue D = CurDAG->getTargetExtractSubreg(ARM::dsub_0+Vec, dl, VT, RegSeq); ReplaceUses(SDValue(N, Vec), D); } @@ -1136,8 +1136,8 @@ SDValue QQ = SDValue(QuadDRegs(MVT::v4i64, SDValue(VLd, 0), SDValue(VLd, 1), SDValue(VLd, 2), SDValue(VLd, 3)), 0); - SDValue Q0 = CurDAG->getTargetExtractSubreg(ARM::QSUBREG_0, dl, VT, QQ); - SDValue Q1 = CurDAG->getTargetExtractSubreg(ARM::QSUBREG_1, dl, VT, QQ); + SDValue Q0 = CurDAG->getTargetExtractSubreg(ARM::qsub_0, dl, VT, QQ); + SDValue Q1 = CurDAG->getTargetExtractSubreg(ARM::qsub_1, dl, VT, QQ); ReplaceUses(SDValue(N, 0), Q0); ReplaceUses(SDValue(N, 1), Q1); } @@ -1188,7 +1188,7 @@ // Extract out the 3 / 4 Q registers. for (unsigned Vec = 0; Vec < NumVecs; ++Vec) { - SDValue Q = CurDAG->getTargetExtractSubreg(ARM::QSUBREG_0+Vec, + SDValue Q = CurDAG->getTargetExtractSubreg(ARM::qsub_0+Vec, dl, VT, RegSeq); ReplaceUses(SDValue(N, Vec), Q); } @@ -1264,15 +1264,15 @@ } // Now extract the D registers back out. - Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_0, dl, VT, + Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_0, dl, VT, RegSeq)); - Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1, dl, VT, + Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_1, dl, VT, RegSeq)); if (NumVecs > 2) - Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_2, dl, VT, + Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_2, dl, VT, RegSeq)); if (NumVecs > 3) - Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_3, dl, VT, + Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_3, dl, VT, RegSeq)); } else { for (unsigned Vec = 0; Vec < NumVecs; ++Vec) @@ -1299,13 +1299,13 @@ SDValue QQ = SDValue(PairQRegs(MVT::v4i64, Q0, Q1), 0); // Now extract the D registers back out. - Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_0, dl, RegVT, + Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_0, dl, RegVT, QQ)); - Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1, dl, RegVT, + Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_1, dl, RegVT, QQ)); - Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_2, dl, RegVT, + Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_2, dl, RegVT, QQ)); - Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_3, dl, RegVT, + Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_3, dl, RegVT, QQ)); Ops.push_back(Pred); Ops.push_back(Reg0); // predicate register @@ -1313,9 +1313,9 @@ return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), 5 + 4); } else { for (unsigned Vec = 0; Vec < NumVecs; ++Vec) { - Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_0, dl, RegVT, + Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_0, dl, RegVT, N->getOperand(Vec+3))); - Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1, dl, RegVT, + Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_1, dl, RegVT, N->getOperand(Vec+3))); } Ops.push_back(Pred); @@ -1332,9 +1332,9 @@ // Form the QQQQ REG_SEQUENCE. SDValue V[8]; for (unsigned Vec = 0, i = 0; Vec < NumVecs; ++Vec, i+=2) { - V[i] = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_0, dl, RegVT, + V[i] = CurDAG->getTargetExtractSubreg(ARM::dsub_0, dl, RegVT, N->getOperand(Vec+3)); - V[i+1] = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1, dl, RegVT, + V[i+1] = CurDAG->getTargetExtractSubreg(ARM::dsub_1, dl, RegVT, N->getOperand(Vec+3)); } if (NumVecs == 3) @@ -1347,7 +1347,7 @@ // Store the even D registers. Ops.push_back(Reg0); // post-access address offset for (unsigned Vec = 0; Vec < NumVecs; ++Vec) - Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_0+Vec*2, dl, + Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_0+Vec*2, dl, RegVT, RegSeq)); Ops.push_back(Pred); Ops.push_back(Reg0); // predicate register @@ -1360,7 +1360,7 @@ // Store the odd D registers. Ops[0] = SDValue(VStA, 0); // MemAddr for (unsigned Vec = 0; Vec < NumVecs; ++Vec) - Ops[Vec+3] = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1+Vec*2, dl, + Ops[Vec+3] = CurDAG->getTargetExtractSubreg(ARM::dsub_1+Vec*2, dl, RegVT, RegSeq); Ops[NumVecs+5] = Chain; Opc = QOpcodes1[OpcodeIndex]; @@ -1374,7 +1374,7 @@ // Store the even subregs. for (unsigned Vec = 0; Vec < NumVecs; ++Vec) - Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_0, dl, RegVT, + Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_0, dl, RegVT, N->getOperand(Vec+3))); Ops.push_back(Pred); Ops.push_back(Reg0); // predicate register @@ -1387,7 +1387,7 @@ // Store the odd subregs. Ops[0] = SDValue(VStA, 0); // MemAddr for (unsigned Vec = 0; Vec < NumVecs; ++Vec) - Ops[Vec+3] = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1, dl, RegVT, + Ops[Vec+3] = CurDAG->getTargetExtractSubreg(ARM::dsub_1, dl, RegVT, N->getOperand(Vec+3)); Ops[NumVecs+5] = Chain; Opc = QOpcodes1[OpcodeIndex]; @@ -1424,7 +1424,7 @@ if (!is64BitVector) { RegVT = GetNEONSubregVT(VT); NumElts = RegVT.getVectorNumElements(); - SubregIdx = (Lane < NumElts) ? ARM::DSUBREG_0 : ARM::DSUBREG_1; + SubregIdx = (Lane < NumElts) ? ARM::dsub_0 : ARM::dsub_1; Even = Lane < NumElts; } @@ -1467,15 +1467,15 @@ } // Now extract the D registers back out. - Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_0, dl, VT, + Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_0, dl, VT, RegSeq)); - Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1, dl, VT, + Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_1, dl, VT, RegSeq)); if (NumVecs > 2) - Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_2, dl, VT, + Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_2, dl, VT, RegSeq)); if (NumVecs > 3) - Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_3, dl, VT, + Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_3, dl, VT, RegSeq)); } else { for (unsigned Vec = 0; Vec < NumVecs; ++Vec) @@ -1505,7 +1505,7 @@ } // Extract the subregs of the input vector. - unsigned SubIdx = Even ? ARM::DSUBREG_0 : ARM::DSUBREG_1; + unsigned SubIdx = Even ? ARM::dsub_0 : ARM::dsub_1; for (unsigned Vec = 0; Vec < NumVecs; ++Vec) Ops.push_back(CurDAG->getTargetExtractSubreg(SubIdx+Vec*2, dl, RegVT, RegSeq)); @@ -1570,7 +1570,7 @@ V[4], V[5], V[6], V[7]), 0); } - unsigned SubIdx = is64BitVector ? ARM::DSUBREG_0 : ARM::QSUBREG_0; + unsigned SubIdx = is64BitVector ? ARM::dsub_0 : ARM::qsub_0; for (unsigned Vec = 0; Vec < NumVecs; ++Vec) ReplaceUses(SDValue(N, Vec), CurDAG->getTargetExtractSubreg(SubIdx+Vec, dl, VT, RegSeq)); @@ -1830,8 +1830,8 @@ DebugLoc dl = N->getDebugLoc(); SDValue V0 = N->getOperand(0); SDValue V1 = N->getOperand(1); - SDValue SubReg0 = CurDAG->getTargetConstant(ARM::DSUBREG_0, MVT::i32); - SDValue SubReg1 = CurDAG->getTargetConstant(ARM::DSUBREG_1, MVT::i32); + SDValue SubReg0 = CurDAG->getTargetConstant(ARM::dsub_0, MVT::i32); + SDValue SubReg1 = CurDAG->getTargetConstant(ARM::dsub_1, MVT::i32); const SDValue Ops[] = { V0, SubReg0, V1, SubReg1 }; return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 4); } Modified: llvm/trunk/lib/Target/ARM/ARMInstrNEON.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrNEON.td?rev=104508&r1=104507&r2=104508&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrNEON.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Mon May 24 11:54:32 2010 @@ -796,7 +796,7 @@ //===----------------------------------------------------------------------===// // Extract D sub-registers of Q registers. -// (arm_dsubreg_0 is 5; arm_dsubreg_1 is 6) +// (dsub_0 is 5; dsub_1 is 6) def DSubReg_i8_reg : SDNodeXFormgetTargetConstant(5 + N->getZExtValue() / 8, MVT::i32); }]>; @@ -814,7 +814,7 @@ }]>; // Extract S sub-registers of Q/D registers. -// (arm_ssubreg_0 is 1; arm_ssubreg_1 is 2; etc.) +// (ssub_0 is 1; ssub_1 is 2; etc.) def SSubReg_f32_reg : SDNodeXFormgetTargetConstant(1 + N->getZExtValue(), MVT::i32); }]>; @@ -3011,11 +3011,11 @@ (INSERT_SUBREG QPR:$src1, DPR:$src2, (DSubReg_f64_reg imm:$src3))>; def : Pat<(v2f32 (scalar_to_vector SPR:$src)), - (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$src, arm_ssubreg_0)>; + (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$src, ssub_0)>; def : Pat<(v2f64 (scalar_to_vector (f64 DPR:$src))), - (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), DPR:$src, arm_dsubreg_0)>; + (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), DPR:$src, dsub_0)>; def : Pat<(v4f32 (scalar_to_vector SPR:$src)), - (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), SPR:$src, arm_ssubreg_0)>; + (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), SPR:$src, ssub_0)>; def : Pat<(v8i8 (scalar_to_vector GPR:$src)), (VSETLNi8 (v8i8 (IMPLICIT_DEF)), GPR:$src, (i32 0))>; @@ -3027,15 +3027,15 @@ def : Pat<(v16i8 (scalar_to_vector GPR:$src)), (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)), (VSETLNi8 (v8i8 (IMPLICIT_DEF)), GPR:$src, (i32 0)), - arm_dsubreg_0)>; + dsub_0)>; def : Pat<(v8i16 (scalar_to_vector GPR:$src)), (INSERT_SUBREG (v8i16 (IMPLICIT_DEF)), (VSETLNi16 (v4i16 (IMPLICIT_DEF)), GPR:$src, (i32 0)), - arm_dsubreg_0)>; + dsub_0)>; def : Pat<(v4i32 (scalar_to_vector GPR:$src)), (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)), (VSETLNi32 (v2i32 (IMPLICIT_DEF)), GPR:$src, (i32 0)), - arm_dsubreg_0)>; + dsub_0)>; // VDUP : Vector Duplicate (from ARM core register to all elements) @@ -3369,27 +3369,27 @@ class N2VSPat : NEONFPPat<(ResTy (OpNode SPR:$a)), (EXTRACT_SUBREG (OpTy (Inst (INSERT_SUBREG (OpTy (IMPLICIT_DEF)), - SPR:$a, arm_ssubreg_0))), - arm_ssubreg_0)>; + SPR:$a, ssub_0))), + ssub_0)>; class N3VSPat : NEONFPPat<(f32 (OpNode SPR:$a, SPR:$b)), (EXTRACT_SUBREG (v2f32 (Inst (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), - SPR:$a, arm_ssubreg_0), + SPR:$a, ssub_0), (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), - SPR:$b, arm_ssubreg_0))), - arm_ssubreg_0)>; + SPR:$b, ssub_0))), + ssub_0)>; class N3VSMulOpPat : NEONFPPat<(f32 (OpNode SPR:$acc, (f32 (MulNode SPR:$a, SPR:$b)))), (EXTRACT_SUBREG (Inst (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), - SPR:$acc, arm_ssubreg_0), + SPR:$acc, ssub_0), (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), - SPR:$a, arm_ssubreg_0), + SPR:$a, ssub_0), (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), - SPR:$b, arm_ssubreg_0)), - arm_ssubreg_0)>; + SPR:$b, ssub_0)), + ssub_0)>; // These need separate instructions because they must use DPR_VFP2 register // class which have SPR sub-registers. Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h?rev=104508&r1=104507&r2=104508&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h (original) +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h Mon May 24 11:54:32 2010 @@ -23,19 +23,6 @@ class ARMBaseInstrInfo; class Type; -namespace ARM { - /// SubregIndex - The index of various subregister classes. Note that - /// these indices must be kept in sync with the class indices in the - /// ARMRegisterInfo.td file. - enum SubregIndex { - SSUBREG_0 = 1, SSUBREG_1 = 2, SSUBREG_2 = 3, SSUBREG_3 = 4, - DSUBREG_0 = 5, DSUBREG_1 = 6, DSUBREG_2 = 7, DSUBREG_3 = 8, - DSUBREG_4 = 9, DSUBREG_5 = 10, DSUBREG_6 = 11, DSUBREG_7 = 12, - QSUBREG_0 = 13, QSUBREG_1 = 14, QSUBREG_2 = 15, QSUBREG_3 = 16, - QQSUBREG_0= 17, QQSUBREG_1= 18 - }; -} - struct ARMRegisterInfo : public ARMBaseRegisterInfo { public: ARMRegisterInfo(const ARMBaseInstrInfo &tii, const ARMSubtarget &STI); Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td?rev=104508&r1=104507&r2=104508&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td Mon May 24 11:54:32 2010 @@ -445,29 +445,29 @@ // Subregister Set Definitions... now that we have all of the pieces, define the // sub registers for each register. // - -def arm_ssubreg_0 : PatLeaf<(i32 1)>; -def arm_ssubreg_1 : PatLeaf<(i32 2)>; -def arm_ssubreg_2 : PatLeaf<(i32 3)>; -def arm_ssubreg_3 : PatLeaf<(i32 4)>; - -def arm_dsubreg_0 : PatLeaf<(i32 5)>; -def arm_dsubreg_1 : PatLeaf<(i32 6)>; -def arm_dsubreg_2 : PatLeaf<(i32 7)>; -def arm_dsubreg_3 : PatLeaf<(i32 8)>; -def arm_dsubreg_4 : PatLeaf<(i32 9)>; -def arm_dsubreg_5 : PatLeaf<(i32 10)>; -def arm_dsubreg_6 : PatLeaf<(i32 11)>; -def arm_dsubreg_7 : PatLeaf<(i32 12)>; - -def arm_qsubreg_0 : PatLeaf<(i32 13)>; -def arm_qsubreg_1 : PatLeaf<(i32 14)>; -def arm_qsubreg_2 : PatLeaf<(i32 15)>; -def arm_qsubreg_3 : PatLeaf<(i32 16)>; - -def arm_qqsubreg_0 : PatLeaf<(i32 17)>; -def arm_qqsubreg_1 : PatLeaf<(i32 18)>; - +let Namespace = "ARM" in { +def ssub_0 : SubRegIndex { let NumberHack = 1; } +def ssub_1 : SubRegIndex { let NumberHack = 2; } +def ssub_2 : SubRegIndex { let NumberHack = 3; } +def ssub_3 : SubRegIndex { let NumberHack = 4; } + +def dsub_0 : SubRegIndex { let NumberHack = 5; } +def dsub_1 : SubRegIndex { let NumberHack = 6; } +def dsub_2 : SubRegIndex { let NumberHack = 7; } +def dsub_3 : SubRegIndex { let NumberHack = 8; } +def dsub_4 : SubRegIndex { let NumberHack = 9; } +def dsub_5 : SubRegIndex { let NumberHack = 10; } +def dsub_6 : SubRegIndex { let NumberHack = 11; } +def dsub_7 : SubRegIndex { let NumberHack = 12; } + +def qsub_0 : SubRegIndex { let NumberHack = 13; } +def qsub_1 : SubRegIndex { let NumberHack = 14; } +def qsub_2 : SubRegIndex { let NumberHack = 15; } +def qsub_3 : SubRegIndex { let NumberHack = 16; } + +def qqsub_0 : SubRegIndex { let NumberHack = 17; } +def qqsub_1 : SubRegIndex { let NumberHack = 18; } +} // S sub-registers of D registers. def : SubRegSet<1, [D0, D1, D2, D3, D4, D5, D6, D7, Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp?rev=104508&r1=104507&r2=104508&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Mon May 24 11:54:32 2010 @@ -319,8 +319,8 @@ unsigned Reg = MO.getReg(); assert(TargetRegisterInfo::isPhysicalRegister(Reg)); if (Modifier && strcmp(Modifier, "dregpair") == 0) { - unsigned DRegLo = TM.getRegisterInfo()->getSubReg(Reg, 5);// arm_dsubreg_0 - unsigned DRegHi = TM.getRegisterInfo()->getSubReg(Reg, 6);// arm_dsubreg_1 + unsigned DRegLo = TM.getRegisterInfo()->getSubReg(Reg, ARM::dsub_0); + unsigned DRegHi = TM.getRegisterInfo()->getSubReg(Reg, ARM::dsub_1); O << '{' << getRegisterName(DRegLo) << ',' << getRegisterName(DRegHi) << '}'; Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp?rev=104508&r1=104507&r2=104508&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp Mon May 24 11:54:32 2010 @@ -195,8 +195,8 @@ // FIXME: Breaks e.g. ARM/vmul.ll. assert(0); /* - unsigned DRegLo = TRI->getSubReg(Reg, 5); // arm_dsubreg_0 - unsigned DRegHi = TRI->getSubReg(Reg, 6); // arm_dsubreg_1 + unsigned DRegLo = TRI->getSubReg(Reg, ARM::dsub_0); + unsigned DRegHi = TRI->getSubReg(Reg, ARM::dsub_1); O << '{' << getRegisterName(DRegLo) << ',' << getRegisterName(DRegHi) << '}';*/ Modified: llvm/trunk/lib/Target/ARM/NEONPreAllocPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/NEONPreAllocPass.cpp?rev=104508&r1=104507&r2=104508&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/NEONPreAllocPass.cpp (original) +++ llvm/trunk/lib/Target/ARM/NEONPreAllocPass.cpp Mon May 24 11:54:32 2010 @@ -375,9 +375,9 @@ if (LastSubIdx != SubIdx-Stride) return false; } else { - // Must start from arm_dsubreg_0 or arm_qsubreg_0. - if (SubIdx != (ARM::DSUBREG_0+Offset) && - SubIdx != (ARM::QSUBREG_0+Offset)) + // Must start from dsub_0 or qsub_0. + if (SubIdx != (ARM::dsub_0+Offset) && + SubIdx != (ARM::qsub_0+Offset)) return false; } RegSeq = UseMI; @@ -423,9 +423,9 @@ if (LastSubIdx != SubIdx-Stride) return false; } else { - // Must start from arm_dsubreg_0 or arm_qsubreg_0. - if (SubIdx != (ARM::DSUBREG_0+Offset) && - SubIdx != (ARM::QSUBREG_0+Offset)) + // Must start from dsub_0 or qsub_0. + if (SubIdx != (ARM::dsub_0+Offset) && + SubIdx != (ARM::qsub_0+Offset)) return false; } SubIds.push_back(SubIdx); From stoklund at 2pi.dk Mon May 24 12:13:28 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 24 May 2010 17:13:28 -0000 Subject: [llvm-commits] [llvm] r104510 - in /llvm/trunk/lib/Target/ARM: ARMISelDAGToDAG.cpp ARMInstrNEON.td ARMRegisterInfo.td Message-ID: <20100524171328.59C6F312800A@llvm.org> Author: stoklund Date: Mon May 24 12:13:28 2010 New Revision: 104510 URL: http://llvm.org/viewvc/llvm-project?rev=104510&view=rev Log: Fix a few places that depended on the numeric value of subreg indices. Add assertions in places that depend on consecutive indices. Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp llvm/trunk/lib/Target/ARM/ARMInstrNEON.td llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=104510&r1=104509&r2=104510&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Mon May 24 12:13:28 2010 @@ -1107,6 +1107,7 @@ RegSeq = SDValue(QuadDRegs(MVT::v4i64, V0, V1, V2, V3), 0); } + assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering"); for (unsigned Vec = 0; Vec < NumVecs; ++Vec) { SDValue D = CurDAG->getTargetExtractSubreg(ARM::dsub_0+Vec, dl, VT, RegSeq); @@ -1187,6 +1188,7 @@ V4, V5, V6, V7), 0); // Extract out the 3 / 4 Q registers. + assert(ARM::qsub_3 == ARM::qsub_0+3 && "Unexpected subreg numbering"); for (unsigned Vec = 0; Vec < NumVecs; ++Vec) { SDValue Q = CurDAG->getTargetExtractSubreg(ARM::qsub_0+Vec, dl, VT, RegSeq); @@ -1345,6 +1347,7 @@ V[4], V[5], V[6], V[7]), 0); // Store the even D registers. + assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering"); Ops.push_back(Reg0); // post-access address offset for (unsigned Vec = 0; Vec < NumVecs; ++Vec) Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_0+Vec*2, dl, @@ -1570,6 +1573,8 @@ V[4], V[5], V[6], V[7]), 0); } + assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering"); + assert(ARM::qsub_3 == ARM::qsub_0+3 && "Unexpected subreg numbering"); unsigned SubIdx = is64BitVector ? ARM::dsub_0 : ARM::qsub_0; for (unsigned Vec = 0; Vec < NumVecs; ++Vec) ReplaceUses(SDValue(N, Vec), Modified: llvm/trunk/lib/Target/ARM/ARMInstrNEON.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrNEON.td?rev=104510&r1=104509&r2=104510&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrNEON.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Mon May 24 12:13:28 2010 @@ -796,27 +796,32 @@ //===----------------------------------------------------------------------===// // Extract D sub-registers of Q registers. -// (dsub_0 is 5; dsub_1 is 6) def DSubReg_i8_reg : SDNodeXFormgetTargetConstant(5 + N->getZExtValue() / 8, MVT::i32); + assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering"); + return CurDAG->getTargetConstant(ARM::dsub_0 + N->getZExtValue()/8, MVT::i32); }]>; def DSubReg_i16_reg : SDNodeXFormgetTargetConstant(5 + N->getZExtValue() / 4, MVT::i32); + assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering"); + return CurDAG->getTargetConstant(ARM::dsub_0 + N->getZExtValue()/4, MVT::i32); }]>; def DSubReg_i32_reg : SDNodeXFormgetTargetConstant(5 + N->getZExtValue() / 2, MVT::i32); + assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering"); + return CurDAG->getTargetConstant(ARM::dsub_0 + N->getZExtValue()/2, MVT::i32); }]>; def DSubReg_f64_reg : SDNodeXFormgetTargetConstant(5 + N->getZExtValue(), MVT::i32); + assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering"); + return CurDAG->getTargetConstant(ARM::dsub_0 + N->getZExtValue(), MVT::i32); }]>; def DSubReg_f64_other_reg : SDNodeXFormgetTargetConstant(5 + (1 - N->getZExtValue()), MVT::i32); + assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering"); + return CurDAG->getTargetConstant(ARM::dsub_0 + (1 - N->getZExtValue()), + MVT::i32); }]>; // Extract S sub-registers of Q/D registers. -// (ssub_0 is 1; ssub_1 is 2; etc.) def SSubReg_f32_reg : SDNodeXFormgetTargetConstant(1 + N->getZExtValue(), MVT::i32); + assert(ARM::ssub_3 == ARM::ssub_0+3 && "Unexpected subreg numbering"); + return CurDAG->getTargetConstant(ARM::ssub_0 + N->getZExtValue(), MVT::i32); }]>; // Translate lane numbers from Q registers to D subregs. Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td?rev=104510&r1=104509&r2=104510&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td Mon May 24 12:13:28 2010 @@ -446,6 +446,7 @@ // sub registers for each register. // let Namespace = "ARM" in { +// Note: Code depends on these having consecutive numbers. def ssub_0 : SubRegIndex { let NumberHack = 1; } def ssub_1 : SubRegIndex { let NumberHack = 2; } def ssub_2 : SubRegIndex { let NumberHack = 3; } From stoklund at 2pi.dk Mon May 24 12:42:56 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 24 May 2010 17:42:56 -0000 Subject: [llvm-commits] [llvm] r104513 - /llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td Message-ID: <20100524174256.28C1B312800A@llvm.org> Author: stoklund Date: Mon May 24 12:42:55 2010 New Revision: 104513 URL: http://llvm.org/viewvc/llvm-project?rev=104513&view=rev Log: SubRegIndex'ize MSP430 Modified: llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td Modified: llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td?rev=104513&r1=104512&r2=104513&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td (original) +++ llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td Mon May 24 12:42:55 2010 @@ -65,7 +65,10 @@ [PCB, SPB, SRB, CGB, FPB, R5B, R6B, R7B, R8B, R9B, R10B, R11B, R12B, R13B, R14B, R15B]>; -def subreg_8bit : PatLeaf<(i32 1)>; +def subreg_8bit : SubRegIndex { + let NumberHack = 1; + let Namespace = "MSP430"; +} def GR8 : RegisterClass<"MSP430", [i8], 8, // Volatile registers From stoklund at 2pi.dk Mon May 24 12:42:58 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 24 May 2010 17:42:58 -0000 Subject: [llvm-commits] [llvm] r104514 - in /llvm/trunk/lib/Target/Mips: MipsISelDAGToDAG.cpp MipsRegisterInfo.h MipsRegisterInfo.td Message-ID: <20100524174258.D3E533128018@llvm.org> Author: stoklund Date: Mon May 24 12:42:58 2010 New Revision: 104514 URL: http://llvm.org/viewvc/llvm-project?rev=104514&view=rev Log: SubRegIndex'ize Mips Modified: llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp llvm/trunk/lib/Target/Mips/MipsRegisterInfo.h llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td Modified: llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp?rev=104514&r1=104513&r2=104514&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp Mon May 24 12:42:58 2010 @@ -225,12 +225,12 @@ MVT::Other, Offset0, Base, Chain); SDValue Undef = SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, NVT), 0); - SDValue I0 = CurDAG->getTargetInsertSubreg(Mips::SUBREG_FPEVEN, dl, + SDValue I0 = CurDAG->getTargetInsertSubreg(Mips::sub_fpeven, dl, MVT::f64, Undef, SDValue(LD0, 0)); SDNode *LD1 = CurDAG->getMachineNode(Mips::LWC1, dl, MVT::f32, MVT::Other, Offset1, Base, SDValue(LD0, 1)); - SDValue I1 = CurDAG->getTargetInsertSubreg(Mips::SUBREG_FPODD, dl, + SDValue I1 = CurDAG->getTargetInsertSubreg(Mips::sub_fpodd, dl, MVT::f64, I0, SDValue(LD1, 0)); ReplaceUses(SDValue(N, 0), I1); @@ -266,9 +266,9 @@ DebugLoc dl = N->getDebugLoc(); // Get the even and odd part from the f64 register - SDValue FPOdd = CurDAG->getTargetExtractSubreg(Mips::SUBREG_FPODD, + SDValue FPOdd = CurDAG->getTargetExtractSubreg(Mips::sub_fpodd, dl, MVT::f32, N1); - SDValue FPEven = CurDAG->getTargetExtractSubreg(Mips::SUBREG_FPEVEN, + SDValue FPEven = CurDAG->getTargetExtractSubreg(Mips::sub_fpeven, dl, MVT::f32, N1); // The second store should start after for 4 bytes. @@ -438,9 +438,9 @@ SDValue Undef = SDValue( CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, MVT::f64), 0); SDNode *MTC = CurDAG->getMachineNode(Mips::MTC1, dl, MVT::f32, Zero); - SDValue I0 = CurDAG->getTargetInsertSubreg(Mips::SUBREG_FPEVEN, dl, + SDValue I0 = CurDAG->getTargetInsertSubreg(Mips::sub_fpeven, dl, MVT::f64, Undef, SDValue(MTC, 0)); - SDValue I1 = CurDAG->getTargetInsertSubreg(Mips::SUBREG_FPODD, dl, + SDValue I1 = CurDAG->getTargetInsertSubreg(Mips::sub_fpodd, dl, MVT::f64, I0, SDValue(MTC, 0)); ReplaceUses(SDValue(Node, 0), I1); return I1.getNode(); Modified: llvm/trunk/lib/Target/Mips/MipsRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsRegisterInfo.h?rev=104514&r1=104513&r2=104514&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsRegisterInfo.h (original) +++ llvm/trunk/lib/Target/Mips/MipsRegisterInfo.h Mon May 24 12:42:58 2010 @@ -23,15 +23,6 @@ class TargetInstrInfo; class Type; -namespace Mips { - /// SubregIndex - The index of various sized subregister classes. Note that - /// these indices must be kept in sync with the class indices in the - /// MipsRegisterInfo.td file. - enum SubregIndex { - SUBREG_FPEVEN = 1, SUBREG_FPODD = 2 - }; -} - struct MipsRegisterInfo : public MipsGenRegisterInfo { const MipsSubtarget &Subtarget; const TargetInstrInfo &TII; Modified: llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td?rev=104514&r1=104513&r2=104514&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td (original) +++ llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td Mon May 24 12:42:58 2010 @@ -144,8 +144,10 @@ // Subregister Set Definitions //===----------------------------------------------------------------------===// -def mips_subreg_fpeven : PatLeaf<(i32 1)>; -def mips_subreg_fpodd : PatLeaf<(i32 2)>; +let Namespace = "Mips" in { +def sub_fpeven : SubRegIndex { let NumberHack = 1; } +def sub_fpodd : SubRegIndex { let NumberHack = 2; } +} def : SubRegSet<1, [D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15], From stoklund at 2pi.dk Mon May 24 12:43:01 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 24 May 2010 17:43:01 -0000 Subject: [llvm-commits] [llvm] r104515 - in /llvm/trunk/lib/Target/SystemZ: AsmPrinter/SystemZAsmPrinter.cpp SystemZRegisterInfo.h SystemZRegisterInfo.td Message-ID: <20100524174301.A737D3128026@llvm.org> Author: stoklund Date: Mon May 24 12:43:01 2010 New Revision: 104515 URL: http://llvm.org/viewvc/llvm-project?rev=104515&view=rev Log: Use SubRegIndex in SystemZ. Anton, please review the change to SystemZAsmPrinter.cpp. It could be a bug. Modified: llvm/trunk/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.h llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td Modified: llvm/trunk/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp?rev=104515&r1=104514&r2=104515&view=diff ============================================================================== --- llvm/trunk/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp Mon May 24 12:43:01 2010 @@ -124,9 +124,9 @@ unsigned Reg = MO.getReg(); if (Modifier && strncmp(Modifier, "subreg", 6) == 0) { if (strncmp(Modifier + 7, "even", 4) == 0) - Reg = TM.getRegisterInfo()->getSubReg(Reg, SystemZ::SUBREG_EVEN); + Reg = TM.getRegisterInfo()->getSubReg(Reg, SystemZ::subreg_even32); else if (strncmp(Modifier + 7, "odd", 3) == 0) - Reg = TM.getRegisterInfo()->getSubReg(Reg, SystemZ::SUBREG_ODD); + Reg = TM.getRegisterInfo()->getSubReg(Reg, SystemZ::subreg_odd32); else assert(0 && "Invalid subreg modifier"); } Modified: llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.h?rev=104515&r1=104514&r2=104515&view=diff ============================================================================== --- llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.h (original) +++ llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.h Mon May 24 12:43:01 2010 @@ -1,4 +1,4 @@ -//===- SystemZRegisterInfo.h - SystemZ Register Information Impl ----*- C++ -*-===// +//===-- SystemZRegisterInfo.h - SystemZ Register Information ----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -19,15 +19,6 @@ namespace llvm { -namespace SystemZ { - /// SubregIndex - The index of various sized subregister classes. Note that - /// these indices must be kept in sync with the class indices in the - /// SystemZRegisterInfo.td file. - enum SubregIndex { - SUBREG_32BIT = 1, SUBREG_EVEN = 1, SUBREG_ODD = 2 - }; -} - class SystemZSubtarget; class SystemZInstrInfo; class Type; Modified: llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td?rev=104515&r1=104514&r2=104515&view=diff ============================================================================== --- llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td (original) +++ llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td Mon May 24 12:43:01 2010 @@ -145,11 +145,13 @@ // Status register def PSW : SystemZReg<"psw">; -def subreg_32bit : PatLeaf<(i32 1)>; -def subreg_even32 : PatLeaf<(i32 1)>; -def subreg_odd32 : PatLeaf<(i32 2)>; -def subreg_even : PatLeaf<(i32 3)>; -def subreg_odd : PatLeaf<(i32 4)>; +let Namespace = "SystemZ" in { +def subreg_32bit : SubRegIndex { let NumberHack = 1; } +def subreg_even32 : SubRegIndex { let NumberHack = 1; } +def subreg_odd32 : SubRegIndex { let NumberHack = 2; } +def subreg_even : SubRegIndex { let NumberHack = 3; } +def subreg_odd : SubRegIndex { let NumberHack = 4; } +} def : SubRegSet<1, [R0D, R1D, R2D, R3D, R4D, R5D, R6D, R7D, R8D, R9D, R10D, R11D, R12D, R13D, R14D, R15D], From stoklund at 2pi.dk Mon May 24 12:55:38 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 24 May 2010 17:55:38 -0000 Subject: [llvm-commits] [llvm] r104517 - /llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td Message-ID: <20100524175538.31A3D312800A@llvm.org> Author: stoklund Date: Mon May 24 12:55:38 2010 New Revision: 104517 URL: http://llvm.org/viewvc/llvm-project?rev=104517&view=rev Log: Add SubRegIndex defs to PowerPC. It looks like the CR subregister indices are never used. Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td?rev=104517&r1=104516&r2=104517&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td (original) +++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td Mon May 24 12:55:38 2010 @@ -234,6 +234,13 @@ def CR6 : CR<6, "cr6", [CR6LT, CR6GT, CR6EQ, CR6UN]>, DwarfRegNum<[74]>; def CR7 : CR<7, "cr7", [CR7LT, CR7GT, CR7EQ, CR7UN]>, DwarfRegNum<[75]>; +let Namespace = "PPC" in { +def sub_lt : SubRegIndex { let NumberHack = 1; } +def sub_gt : SubRegIndex { let NumberHack = 2; } +def sub_eq : SubRegIndex { let NumberHack = 3; } +def sub_un : SubRegIndex { let NumberHack = 4; } +} + def : SubRegSet<1, [CR0, CR1, CR2, CR3, CR4, CR5, CR6, CR7], [CR0LT, CR1LT, CR2LT, CR3LT, CR4LT, CR5LT, CR6LT, CR7LT]>; def : SubRegSet<2, [CR0, CR1, CR2, CR3, CR4, CR5, CR6, CR7], From evan.cheng at apple.com Mon May 24 13:00:18 2010 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 24 May 2010 18:00:18 -0000 Subject: [llvm-commits] [llvm] r104518 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp test/CodeGen/ARM/arm-returnaddr.ll Message-ID: <20100524180018.9CD6E312800A@llvm.org> Author: evancheng Date: Mon May 24 13:00:18 2010 New Revision: 104518 URL: http://llvm.org/viewvc/llvm-project?rev=104518&view=rev Log: LR is in GPR, not tGPR even in Thumb1 mode. Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/test/CodeGen/ARM/arm-returnaddr.ll Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=104518&r1=104517&r2=104518&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Mon May 24 13:00:18 2010 @@ -2158,10 +2158,7 @@ } // Return LR, which contains the return address. Mark it an implicit live-in. - ARMFunctionInfo *AFI = MF.getInfo(); - TargetRegisterClass *RC = AFI->isThumb1OnlyFunction() - ? ARM::tGPRRegisterClass : ARM::GPRRegisterClass; - unsigned Reg = MF.addLiveIn(ARM::LR, RC); + unsigned Reg = MF.addLiveIn(ARM::LR, ARM::GPRRegisterClass); return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, VT); } Modified: llvm/trunk/test/CodeGen/ARM/arm-returnaddr.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/arm-returnaddr.ll?rev=104518&r1=104517&r2=104518&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/arm-returnaddr.ll (original) +++ llvm/trunk/test/CodeGen/ARM/arm-returnaddr.ll Mon May 24 13:00:18 2010 @@ -1,5 +1,7 @@ ; RUN: llc < %s -mtriple=arm-apple-darwin | FileCheck %s +; RUN: llc < %s -mtriple=thumbv6-apple-darwin ; rdar://8015977 +; rdar://8020118 define arm_apcscc i8* @rt0(i32 %x) nounwind readnone { entry: From stuart at apple.com Mon May 24 13:25:58 2010 From: stuart at apple.com (Stuart Hastings) Date: Mon, 24 May 2010 18:25:58 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r104523 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <20100524182558.C16B3312800A@llvm.org> Author: stuart Date: Mon May 24 13:25:58 2010 New Revision: 104523 URL: http://llvm.org/viewvc/llvm-project?rev=104523&view=rev Log: Fix and off-by-one bug in bitfield handling. Radar 7980096. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=104523&r1=104522&r2=104523&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Mon May 24 13:25:58 2010 @@ -7304,7 +7304,7 @@ // adjust FieldPtr so that it is close enough to the bitfield that // *FieldPtr contains the first needed bit. Be careful to make sure that // the pointer remains appropriately aligned. - if (BitStart > LLVMValueBitSize) { + if (BitStart >= LLVMValueBitSize) { // In this case, we know that the alignment of the field is less than // the size of the field. To get the pointer close enough, add some // number of alignment units to the pointer. From dpatel at apple.com Mon May 24 13:26:49 2010 From: dpatel at apple.com (Devang Patel) Date: Mon, 24 May 2010 18:26:49 -0000 Subject: [llvm-commits] [llvm] r104524 - /llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Message-ID: <20100524182649.47EAB312800A@llvm.org> Author: dpatel Date: Mon May 24 13:26:49 2010 New Revision: 104524 URL: http://llvm.org/viewvc/llvm-project?rev=104524&view=rev Log: Do not emit line number entries for unknown debug values. This fixes recent regression in store.exp from gdb testsuite. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=104524&r1=104523&r2=104524&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Mon May 24 13:26:49 2010 @@ -2195,6 +2195,9 @@ if (!DV.Verify()) return; if (DV.getTag() != dwarf::DW_TAG_arg_variable) LocalVar = true; + // Ignore Undef values. + if (MI->getOperand(0).isReg() && !MI->getOperand(0).getReg()) + LocalVar = false; } MCSymbol *Label = NULL; From criswell at uiuc.edu Mon May 24 13:31:05 2010 From: criswell at uiuc.edu (John Criswell) Date: Mon, 24 May 2010 18:31:05 -0000 Subject: [llvm-commits] [poolalloc] r104525 - in /poolalloc/trunk: LICENSE.TXT tools/Makefile tools/WatchDog/ Message-ID: <20100524183105.6C576312800A@llvm.org> Author: criswell Date: Mon May 24 13:31:05 2010 New Revision: 104525 URL: http://llvm.org/viewvc/llvm-project?rev=104525&view=rev Log: Added the WatchDog program from the SAFECode source code. Added: poolalloc/trunk/tools/WatchDog/ (props changed) - copied from r104523, safecode/trunk/tools/WatchDog/ Modified: poolalloc/trunk/LICENSE.TXT poolalloc/trunk/tools/Makefile Modified: poolalloc/trunk/LICENSE.TXT URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/LICENSE.TXT?rev=104525&r1=104524&r2=104525&view=diff ============================================================================== --- poolalloc/trunk/LICENSE.TXT (original) +++ poolalloc/trunk/LICENSE.TXT Mon May 24 13:31:05 2010 @@ -42,3 +42,24 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. +============================================================================== +Copyrights and Licenses for Third Party Software Distributed with LLVM: +============================================================================== +The Automatic Pool Allocation software contains code written by third parties. +Such software will have its own individual LICENSE.TXT file in the directory in +which it appears. This file will describe the copyrights, license, and +restrictions which apply to that code. + +The disclaimer of warranty in the University of Illinois Open Source License +applies to all code in this distribution, and nothing in any of the +other licenses gives permission to use the names of the LLVM Team or the +University of Illinois to endorse or promote products derived from this +Software. + +The following pieces of software have additional or alternate copyrights, +licenses, and/or restrictions: + +Program Directory +------- --------- +Watchdog poolalloc/tools/WatchDog + Modified: poolalloc/trunk/tools/Makefile URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/tools/Makefile?rev=104525&r1=104524&r2=104525&view=diff ============================================================================== --- poolalloc/trunk/tools/Makefile (original) +++ poolalloc/trunk/tools/Makefile Mon May 24 13:31:05 2010 @@ -6,6 +6,6 @@ # # List all of the subdirectories that we will compile. # -PARALLEL_DIRS= #Pa +PARALLEL_DIRS=WatchDog include $(LEVEL)/Makefile.common Propchange: poolalloc/trunk/tools/WatchDog/ ------------------------------------------------------------------------------ svn:mergeinfo = /safecode/branches/release_26/tools/WatchDog:97821-104255 From criswell at uiuc.edu Mon May 24 13:35:20 2010 From: criswell at uiuc.edu (John Criswell) Date: Mon, 24 May 2010 18:35:20 -0000 Subject: [llvm-commits] [poolalloc] r104527 - /poolalloc/trunk/test/TEST.dsgraph.Makefile Message-ID: <20100524183520.07E4E312800A@llvm.org> Author: criswell Date: Mon May 24 13:35:19 2010 New Revision: 104527 URL: http://llvm.org/viewvc/llvm-project?rev=104527&view=rev Log: Use the watchdog program to ensure that programs don't consume too many resources on Mac OS X. Modified: poolalloc/trunk/test/TEST.dsgraph.Makefile Modified: poolalloc/trunk/test/TEST.dsgraph.Makefile URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/TEST.dsgraph.Makefile?rev=104527&r1=104526&r2=104527&view=diff ============================================================================== --- poolalloc/trunk/test/TEST.dsgraph.Makefile (original) +++ poolalloc/trunk/test/TEST.dsgraph.Makefile Mon May 24 13:35:19 2010 @@ -16,6 +16,9 @@ # Pathame to the DSA pass dynamic library DSA_SO := $(PADIR)/$(CONFIGURATION)/lib/libLLVMDataStructure$(SHLIBEXT) +# Command for running the opt program +RUNOPT := $(LLVM_OBJ_ROOT)/projects/poolalloc/$(CONFIGURATION)/bin/watchdog $(LOPT) -load $(DSA_SO) + # PASS - The dsgraph pass to run: ds, bu, td PASS := td @@ -27,10 +30,10 @@ $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).report.txt): \ Output/%.$(TEST).report.txt: Output/%.llvm.bc Output/%.LOC.txt $(LOPT) @# Gather data - -($(LOPT) -load $(DSA_SO) -analyze -dsa-$(PASS) $(ANALYZE_OPTS) $<)> $@.time.1 2>&1 - -($(LOPT) -load $(DSA_SO) -analyze $(MEM) -dsa-$(PASS) -disable-verify $<)> $@.mem.1 2>&1 - -($(LOPT) -load $(DSA_SO) -steens-aa -time-passes -disable-output $<) > $@.time.2 2>&1 - -($(LOPT) -load $(DSA_SO) -steens-aa $(MEM) -disable-output $<) > $@.mem.2 2>&1 + -($(RUNOPT) -analyze -dsa-$(PASS) $(ANALYZE_OPTS) $<)> $@.time.1 2>&1 + -($(RUNOPT) -analyze $(MEM) -dsa-$(PASS) -disable-verify $<)> $@.mem.1 2>&1 + -($(RUNOPT) -steens-aa -time-passes -disable-output $<) > $@.time.2 2>&1 + -($(RUNOPT) -steens-aa $(MEM) -disable-output $<) > $@.mem.2 2>&1 @# Emit data. @echo "---------------------------------------------------------------" > $@ @echo ">>> ========= '$(RELDIR)/$*' Program" >> $@ From criswell at uiuc.edu Mon May 24 13:38:15 2010 From: criswell at uiuc.edu (John Criswell) Date: Mon, 24 May 2010 18:38:15 -0000 Subject: [llvm-commits] [poolalloc] r104529 - /poolalloc/trunk/test/TEST.poolalloc.Makefile Message-ID: <20100524183815.C6692312800A@llvm.org> Author: criswell Date: Mon May 24 13:38:15 2010 New Revision: 104529 URL: http://llvm.org/viewvc/llvm-project?rev=104529&view=rev Log: Run tests using the watchdog program to avoid the machine from trashing when running Mac OS X. Modified: poolalloc/trunk/test/TEST.poolalloc.Makefile Modified: poolalloc/trunk/test/TEST.poolalloc.Makefile URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/TEST.poolalloc.Makefile?rev=104529&r1=104528&r2=104529&view=diff ============================================================================== --- poolalloc/trunk/test/TEST.poolalloc.Makefile (original) +++ poolalloc/trunk/test/TEST.poolalloc.Makefile Mon May 24 13:38:15 2010 @@ -22,6 +22,9 @@ #PADIR := /home/andrewl/Research/llvm/projects/poolalloc PADIR := $(LLVM_OBJ_ROOT)/projects/poolalloc +# Watchdog utility +WATCHDOG := $(LLVM_OBJ_ROOT)/projects/poolalloc/$(CONFIGURATION)/bin/watchdog + # Bits of runtime to improve analysis PA_PRE_RT := $(PADIR)/$(CONFIGURATION)/lib/libpa_pre_rt.bca @@ -37,7 +40,7 @@ #PA_RT_O := $(PROJECT_DIR)/lib/$(CONFIGURATION)/poolalloc_fl_rt.o # Command to run opt with the pool allocator pass loaded -OPT_PA := $(LOPT) -load $(DSA_SO) -load $(PA_SO) +OPT_PA := $(WATCHDOG) $(LOPT) -load $(DSA_SO) -load $(PA_SO) # OPT_PA_STATS - Run opt with the -stats and -time-passes options, capturing the # output to a file. From clattner at apple.com Mon May 24 13:43:15 2010 From: clattner at apple.com (Chris Lattner) Date: Mon, 24 May 2010 11:43:15 -0700 Subject: [llvm-commits] [llvm-gcc-4.2] r104523 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp In-Reply-To: <20100524182558.C16B3312800A@llvm.org> References: <20100524182558.C16B3312800A@llvm.org> Message-ID: <37DD7D4F-9E66-456E-B3BE-7E8DC69DD4A2@apple.com> On May 24, 2010, at 11:25 AM, Stuart Hastings wrote: > Author: stuart > Date: Mon May 24 13:25:58 2010 > New Revision: 104523 > > URL: http://llvm.org/viewvc/llvm-project?rev=104523&view=rev > Log: > Fix and off-by-one bug in bitfield handling. Radar 7980096. Testcase please. -Chris > > Modified: > llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp > > Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=104523&r1=104522&r2=104523&view=diff > ============================================================================== > --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) > +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Mon May 24 13:25:58 2010 > @@ -7304,7 +7304,7 @@ > // adjust FieldPtr so that it is close enough to the bitfield that > // *FieldPtr contains the first needed bit. Be careful to make sure that > // the pointer remains appropriately aligned. > - if (BitStart > LLVMValueBitSize) { > + if (BitStart >= LLVMValueBitSize) { > // In this case, we know that the alignment of the field is less than > // the size of the field. To get the pointer close enough, add some > // number of alignment units to the pointer. > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From criswell at uiuc.edu Mon May 24 13:43:51 2010 From: criswell at uiuc.edu (John Criswell) Date: Mon, 24 May 2010 18:43:51 -0000 Subject: [llvm-commits] [poolalloc] r104530 - in /poolalloc/trunk/tools: Makefile Pa/pa.cpp Message-ID: <20100524184351.CDBF0312800A@llvm.org> Author: criswell Date: Mon May 24 13:43:51 2010 New Revision: 104530 URL: http://llvm.org/viewvc/llvm-project?rev=104530&view=rev Log: Fixed compilation of the Pa tool under LLVM 2.7 and made it build by default. Modified: poolalloc/trunk/tools/Makefile poolalloc/trunk/tools/Pa/pa.cpp Modified: poolalloc/trunk/tools/Makefile URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/tools/Makefile?rev=104530&r1=104529&r2=104530&view=diff ============================================================================== --- poolalloc/trunk/tools/Makefile (original) +++ poolalloc/trunk/tools/Makefile Mon May 24 13:43:51 2010 @@ -6,6 +6,6 @@ # # List all of the subdirectories that we will compile. # -PARALLEL_DIRS=WatchDog +PARALLEL_DIRS=WatchDog Pa include $(LEVEL)/Makefile.common Modified: poolalloc/trunk/tools/Pa/pa.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/tools/Pa/pa.cpp?rev=104530&r1=104529&r2=104530&view=diff ============================================================================== --- poolalloc/trunk/tools/Pa/pa.cpp (original) +++ poolalloc/trunk/tools/Pa/pa.cpp Mon May 24 13:43:51 2010 @@ -13,6 +13,7 @@ // //===--------------------------------------------------------------------===// +#include "llvm/Config/config.h" #include "llvm/Module.h" #include "llvm/LLVMContext.h" #include "llvm/Bitcode/ReaderWriter.h" @@ -26,7 +27,7 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Analysis/Verifier.h" #include "llvm/System/Signals.h" -#include "llvm/Config/config.h" +#include "llvm/Support/raw_os_ostream.h" #include "dsa/DSSupport.h" #include "dsa/DataStructure.h" @@ -100,7 +101,8 @@ Passes.add(createVerifierPass()); // Figure out where we are going to send the output... - std::ostream *Out = 0; + raw_fd_ostream *Out = 0; + std::string error; if (OutputFilename != "") { if (OutputFilename != "-") { // Specified an output filename? @@ -111,18 +113,18 @@ << "Use -f command line argument to force output\n"; return 1; } - Out = new std::ofstream(OutputFilename.c_str()); + Out = new raw_fd_ostream (OutputFilename.c_str(), error); // Make sure that the Out file gets unlinked from the disk if we get a // SIGINT sys::RemoveFileOnSignal(sys::Path(OutputFilename)); } else { - Out = &std::cout; + Out = new raw_stdout_ostream(); } } else { if (InputFilename == "-") { OutputFilename = "-"; - Out = &std::cout; + Out = new raw_stdout_ostream(); } else { OutputFilename = GetFileNameRoot(InputFilename); @@ -137,8 +139,8 @@ return 1; } - Out = new std::ofstream(OutputFilename.c_str()); - if (!Out->good()) { + Out = new raw_fd_ostream(OutputFilename.c_str(), error); + if (error.length()) { std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n"; delete Out; return 1; @@ -150,15 +152,13 @@ } // Add the writing of the output file to the list of passes - Passes.add (CreateBitcodeWriterPass(*Out)); + Passes.add (createBitcodeWriterPass(*Out)); // Run our queue of passes all at once now, efficiently. Passes.run(*M.get()); - - - // Delete the ostream if it's not a stdout stream - if (Out != &std::cout) delete Out; + // Delete the ostream + delete Out; return 0; } catch (msg) { From bob.wilson at apple.com Mon May 24 13:44:06 2010 From: bob.wilson at apple.com (Bob Wilson) Date: Mon, 24 May 2010 18:44:06 -0000 Subject: [llvm-commits] [llvm] r104531 - in /llvm/trunk: lib/Target/ARM/ARMInstrThumb2.td test/CodeGen/Thumb2/2010-05-24-rsbs.ll Message-ID: <20100524184406.8D52E3128034@llvm.org> Author: bwilson Date: Mon May 24 13:44:06 2010 New Revision: 104531 URL: http://llvm.org/viewvc/llvm-project?rev=104531&view=rev Log: Thumb2 RSBS instructions were being printed without the 'S' suffix. Fix it by changing the T2I_rbin_s_is multiclass to handle the CPSR output and 'S' suffix in the same way as T2I_bin_s_irs. Added: llvm/trunk/test/CodeGen/Thumb2/2010-05-24-rsbs.ll Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=104531&r1=104530&r2=104531&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Mon May 24 13:44:06 2010 @@ -461,9 +461,8 @@ let Defs = [CPSR] in { multiclass T2I_rbin_s_is opcod, string opc, PatFrag opnode> { // shifted imm - def ri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs, cc_out:$s), - IIC_iALUi, - !strconcat(opc, "${s}.w\t$dst, $rhs, $lhs"), + def ri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs), IIC_iALUi, + !strconcat(opc, "s.w\t$dst, $rhs, $lhs"), [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]> { let Inst{31-27} = 0b11110; let Inst{25} = 0; @@ -472,9 +471,8 @@ let Inst{15} = 0; } // shifted register - def rs : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs, cc_out:$s), - IIC_iALUsi, - !strconcat(opc, "${s}\t$dst, $rhs, $lhs"), + def rs : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs), IIC_iALUsi, + !strconcat(opc, "s\t$dst, $rhs, $lhs"), [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]> { let Inst{31-27} = 0b11101; let Inst{26-25} = 0b01; Added: llvm/trunk/test/CodeGen/Thumb2/2010-05-24-rsbs.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/2010-05-24-rsbs.ll?rev=104531&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/Thumb2/2010-05-24-rsbs.ll (added) +++ llvm/trunk/test/CodeGen/Thumb2/2010-05-24-rsbs.ll Mon May 24 13:44:06 2010 @@ -0,0 +1,9 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin | FileCheck %s +; Radar 8017376: Missing 's' suffix for t2RSBS instructions. +; CHECK: rsbs + +define arm_apcscc i64 @test(i64 %x) nounwind readnone { +entry: + %0 = sub nsw i64 1, %x ; [#uses=1] + ret i64 %0 +} From stuart at apple.com Mon May 24 13:51:26 2010 From: stuart at apple.com (Stuart Hastings) Date: Mon, 24 May 2010 11:51:26 -0700 Subject: [llvm-commits] [llvm-gcc-4.2] r104523 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp In-Reply-To: <37DD7D4F-9E66-456E-B3BE-7E8DC69DD4A2@apple.com> References: <20100524182558.C16B3312800A@llvm.org> <37DD7D4F-9E66-456E-B3BE-7E8DC69DD4A2@apple.com> Message-ID: On May 24, 2010, at 11:43 AM, Chris Lattner wrote: > > On May 24, 2010, at 11:25 AM, Stuart Hastings wrote: > >> Author: stuart >> Date: Mon May 24 13:25:58 2010 >> New Revision: 104523 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=104523&view=rev >> Log: >> Fix and off-by-one bug in bitfield handling. Radar 7980096. > > Testcase please. I've been thinking about that. The signature difference made by the patch is that the bitfield load-byte should be one byte above the store (-word). I'm looking at the existing bitfield test cases; is there an existing FrontendC test case that looks for something similar? stuart > > -Chris > >> >> Modified: >> llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp >> >> Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=104523&r1=104522&r2=104523&view=diff >> ============================================================================== >> --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) >> +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Mon May 24 13:25:58 2010 >> @@ -7304,7 +7304,7 @@ >> // adjust FieldPtr so that it is close enough to the bitfield that >> // *FieldPtr contains the first needed bit. Be careful to make sure that >> // the pointer remains appropriately aligned. >> - if (BitStart > LLVMValueBitSize) { >> + if (BitStart >= LLVMValueBitSize) { >> // In this case, we know that the alignment of the field is less than >> // the size of the field. To get the pointer close enough, add some >> // number of alignment units to the pointer. >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From bob.wilson at apple.com Mon May 24 15:08:35 2010 From: bob.wilson at apple.com (Bob Wilson) Date: Mon, 24 May 2010 20:08:35 -0000 Subject: [llvm-commits] [llvm] r104544 - /llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Message-ID: <20100524200835.2026D312800A@llvm.org> Author: bwilson Date: Mon May 24 15:08:34 2010 New Revision: 104544 URL: http://llvm.org/viewvc/llvm-project?rev=104544&view=rev Log: Clean up some extra whitespace. Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=104544&r1=104543&r2=104544&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Mon May 24 15:08:34 2010 @@ -228,7 +228,7 @@ "", itin> { let OutOperandList = oops; let InOperandList = iops; - let AsmString = asm; + let AsmString = asm; let Pattern = pattern; } @@ -240,7 +240,7 @@ : InstARM { let OutOperandList = oops; let InOperandList = !con(iops, (ins pred:$p)); - let AsmString = !strconcat(opc, !strconcat("${p}", asm)); + let AsmString = !strconcat(opc, !strconcat("${p}", asm)); let Pattern = pattern; list Predicates = [IsARM]; } @@ -252,7 +252,7 @@ : InstARM { let OutOperandList = oops; let InOperandList = iops; - let AsmString = !strconcat(opc, asm); + let AsmString = !strconcat(opc, asm); let Pattern = pattern; let isPredicable = 0; list Predicates = [IsARM]; @@ -268,7 +268,7 @@ : InstARM { let OutOperandList = oops; let InOperandList = !con(iops, (ins pred:$p, cc_out:$s)); - let AsmString = !strconcat(opc, !strconcat("${p}${s}", asm)); + let AsmString = !strconcat(opc, !strconcat("${p}${s}", asm)); let Pattern = pattern; list Predicates = [IsARM]; } @@ -280,7 +280,7 @@ : InstARM { let OutOperandList = oops; let InOperandList = iops; - let AsmString = asm; + let AsmString = asm; let Pattern = pattern; list Predicates = [IsARM]; } @@ -959,7 +959,7 @@ : InstThumb { let OutOperandList = oops; let InOperandList = iops; - let AsmString = asm; + let AsmString = asm; let Pattern = pattern; list Predicates = [IsThumb]; } @@ -995,7 +995,7 @@ : InstThumb { let OutOperandList = oops; let InOperandList = iops; - let AsmString = asm; + let AsmString = asm; let Pattern = pattern; list Predicates = [IsThumb1Only]; } @@ -1140,7 +1140,7 @@ : InstARM { let OutOperandList = oops; let InOperandList = !con(iops, (ins pred:$p, cc_out:$s)); - let AsmString = !strconcat(opc, !strconcat("${s}${p}", asm)); + let AsmString = !strconcat(opc, !strconcat("${s}${p}", asm)); let Pattern = pattern; list Predicates = [IsThumb2]; } @@ -1152,7 +1152,7 @@ : InstARM { let OutOperandList = oops; let InOperandList = iops; - let AsmString = asm; + let AsmString = asm; let Pattern = pattern; list Predicates = [IsThumb2]; } @@ -1163,7 +1163,7 @@ : InstARM { let OutOperandList = oops; let InOperandList = iops; - let AsmString = asm; + let AsmString = asm; let Pattern = pattern; list Predicates = [IsThumb1Only]; } @@ -1280,7 +1280,7 @@ : InstARM { let OutOperandList = oops; let InOperandList = !con(iops, (ins pred:$p)); - let AsmString = !strconcat(opc, !strconcat("${p}", asm)); + let AsmString = !strconcat(opc, !strconcat("${p}", asm)); let Pattern = pattern; list Predicates = [HasVFP2]; } @@ -1292,7 +1292,7 @@ : InstARM { let OutOperandList = oops; let InOperandList = iops; - let AsmString = asm; + let AsmString = asm; let Pattern = pattern; list Predicates = [HasVFP2]; } From stuart at apple.com Mon May 24 15:18:18 2010 From: stuart at apple.com (Stuart Hastings) Date: Mon, 24 May 2010 20:18:18 -0000 Subject: [llvm-commits] [test-suite] r104546 - /test-suite/trunk/SingleSource/UnitTests/2010-05-24-BitfieldTest.c Message-ID: <20100524201818.0B8A1312800A@llvm.org> Author: stuart Date: Mon May 24 15:18:17 2010 New Revision: 104546 URL: http://llvm.org/viewvc/llvm-project?rev=104546&view=rev Log: Test case for r104523. Radar 7980096. Added: test-suite/trunk/SingleSource/UnitTests/2010-05-24-BitfieldTest.c Added: test-suite/trunk/SingleSource/UnitTests/2010-05-24-BitfieldTest.c URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/2010-05-24-BitfieldTest.c?rev=104546&view=auto ============================================================================== --- test-suite/trunk/SingleSource/UnitTests/2010-05-24-BitfieldTest.c (added) +++ test-suite/trunk/SingleSource/UnitTests/2010-05-24-BitfieldTest.c Mon May 24 15:18:17 2010 @@ -0,0 +1,22 @@ +/* From Radar 7980096. Test case by Shantonu Sen! */ +#include + +typedef union { + struct { + unsigned long long count :8; + unsigned long long mcg_ctl_p :1; + } bits; + unsigned long long u64; +} ia32_mcg_cap_t; + +int main(int argc, char *argv[]) { + unsigned long long ctl_p; + ia32_mcg_cap_t ia32_mcg_cap; + + ia32_mcg_cap.u64 = 0x806; + + ctl_p = ia32_mcg_cap.bits.mcg_ctl_p; + assert(ctl_p == 0); + + return 0; +} From dalej at apple.com Mon May 24 15:19:32 2010 From: dalej at apple.com (Dale Johannesen) Date: Mon, 24 May 2010 20:19:32 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r104547 - /llvm-gcc-4.2/trunk/gcc/tree.c Message-ID: <20100524201932.1329C312800A@llvm.org> Author: johannes Date: Mon May 24 15:19:31 2010 New Revision: 104547 URL: http://llvm.org/viewvc/llvm-project?rev=104547&view=rev Log: Do not crash in case of null filename. Looks like somebody hit this before and fixed half of it.... 8020566/8020267 Modified: llvm-gcc-4.2/trunk/gcc/tree.c Modified: llvm-gcc-4.2/trunk/gcc/tree.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/tree.c?rev=104547&r1=104546&r2=104547&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/tree.c (original) +++ llvm-gcc-4.2/trunk/gcc/tree.c Mon May 24 15:19:31 2010 @@ -3347,8 +3347,10 @@ entry cache can reduce the number of allocations by more than half. */ if (last_annotated_node - /* LLVM LOCAL - Check for NULL file. */ + /* LLVM LOCAL begin - Check for NULL file (both places). */ && file + && last_annotated_node->file + /* LLVM LOCAL end - Check for NULL file (both places). */ && last_annotated_node->line == line && (last_annotated_node->file == file || !strcmp (last_annotated_node->file, file))) From clattner at apple.com Mon May 24 15:23:07 2010 From: clattner at apple.com (Chris Lattner) Date: Mon, 24 May 2010 13:23:07 -0700 Subject: [llvm-commits] [llvm-gcc-4.2] r104523 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp In-Reply-To: References: <20100524182558.C16B3312800A@llvm.org> <37DD7D4F-9E66-456E-B3BE-7E8DC69DD4A2@apple.com> Message-ID: <12983790-5FA2-4F33-8883-52CEAD1294A6@apple.com> On May 24, 2010, at 11:51 AM, Stuart Hastings wrote: > > On May 24, 2010, at 11:43 AM, Chris Lattner wrote: > >> >> On May 24, 2010, at 11:25 AM, Stuart Hastings wrote: >> >>> Author: stuart >>> Date: Mon May 24 13:25:58 2010 >>> New Revision: 104523 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=104523&view=rev >>> Log: >>> Fix and off-by-one bug in bitfield handling. Radar 7980096. >> >> Testcase please. > > I've been thinking about that. The signature difference made by the patch is that the bitfield load-byte should be one byte above the store (-word). I'm looking at the existing bitfield test cases; is there an existing FrontendC test case that looks for something similar? If you have a reduced executable test, you can drop it into llvm-test/SingleSource/UnitTests. From enderby at apple.com Mon May 24 15:32:23 2010 From: enderby at apple.com (Kevin Enderby) Date: Mon, 24 May 2010 20:32:23 -0000 Subject: [llvm-commits] [llvm] r104549 - in /llvm/trunk: lib/Target/X86/AsmParser/X86AsmParser.cpp test/MC/AsmParser/X86/x86_32-new-encoder.s Message-ID: <20100524203223.6EC68312800A@llvm.org> Author: enderby Date: Mon May 24 15:32:23 2010 New Revision: 104549 URL: http://llvm.org/viewvc/llvm-project?rev=104549&view=rev Log: MC/X86: Add aliases for CMOVcc variants. Modified: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s Modified: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp?rev=104549&r1=104548&r2=104549&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp (original) +++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp Mon May 24 15:32:23 2010 @@ -617,6 +617,20 @@ .Case("setnz", "setne") .Case("jz", "je") .Case("jnz", "jne") + .Case("cmovcl", "cmovbl") + .Case("cmovcl", "cmovbl") + .Case("cmovnal", "cmovbel") + .Case("cmovnbl", "cmovael") + .Case("cmovnbel", "cmoval") + .Case("cmovncl", "cmovael") + .Case("cmovngl", "cmovlel") + .Case("cmovnl", "cmovgel") + .Case("cmovngl", "cmovlel") + .Case("cmovngel", "cmovll") + .Case("cmovnll", "cmovgel") + .Case("cmovnlel", "cmovgl") + .Case("cmovnzl", "cmovnel") + .Case("cmovzl", "cmovel") .Default(Name); Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc)); Modified: llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s?rev=104549&r1=104548&r2=104549&view=diff ============================================================================== --- llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s (original) +++ llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s Mon May 24 15:32:23 2010 @@ -89,3 +89,132 @@ retl // CHECK: ret // CHECK: encoding: [0xc3] + +// rdar://7973854 +// CHECK: cmoval %eax, %edx +// CHECK: encoding: [0x0f,0x47,0xd0] + cmoval %eax,%edx + +// CHECK: cmovael %eax, %edx +// CHECK: encoding: [0x0f,0x43,0xd0] + cmovael %eax,%edx + +// CHECK: cmovbel %eax, %edx +// CHECK: encoding: [0x0f,0x46,0xd0] + cmovbel %eax,%edx + +// CHECK: cmovbl %eax, %edx +// CHECK: encoding: [0x0f,0x42,0xd0] + cmovbl %eax,%edx + +// CHECK: cmovbel %eax, %edx +// CHECK: encoding: [0x0f,0x46,0xd0] + cmovbel %eax,%edx + +// CHECK: cmovbl %eax, %edx +// CHECK: encoding: [0x0f,0x42,0xd0] + cmovcl %eax,%edx + +// CHECK: cmovel %eax, %edx +// CHECK: encoding: [0x0f,0x44,0xd0] + cmovel %eax,%edx + +// CHECK: cmovgl %eax, %edx +// CHECK: encoding: [0x0f,0x4f,0xd0] + cmovgl %eax,%edx + +// CHECK: cmovgel %eax, %edx +// CHECK: encoding: [0x0f,0x4d,0xd0] + cmovgel %eax,%edx + +// CHECK: cmovll %eax, %edx +// CHECK: encoding: [0x0f,0x4c,0xd0] + cmovll %eax,%edx + +// CHECK: cmovlel %eax, %edx +// CHECK: encoding: [0x0f,0x4e,0xd0] + cmovlel %eax,%edx + +// CHECK: cmovbel %eax, %edx +// CHECK: encoding: [0x0f,0x46,0xd0] + cmovnal %eax,%edx + +// CHECK: cmovnel %eax, %edx +// CHECK: encoding: [0x0f,0x45,0xd0] + cmovnel %eax,%edx + +// CHECK: cmovael %eax, %edx +// CHECK: encoding: [0x0f,0x43,0xd0] + cmovnbl %eax,%edx + +// CHECK: cmoval %eax, %edx +// CHECK: encoding: [0x0f,0x47,0xd0] + cmovnbel %eax,%edx + +// CHECK: cmovael %eax, %edx +// CHECK: encoding: [0x0f,0x43,0xd0] + cmovncl %eax,%edx + +// CHECK: cmovnel %eax, %edx +// CHECK: encoding: [0x0f,0x45,0xd0] + cmovnel %eax,%edx + +// CHECK: cmovlel %eax, %edx +// CHECK: encoding: [0x0f,0x4e,0xd0] + cmovngl %eax,%edx + +// CHECK: cmovgel %eax, %edx +// CHECK: encoding: [0x0f,0x4d,0xd0] + cmovnl %eax,%edx + +// CHECK: cmovnel %eax, %edx +// CHECK: encoding: [0x0f,0x45,0xd0] + cmovnel %eax,%edx + +// CHECK: cmovlel %eax, %edx +// CHECK: encoding: [0x0f,0x4e,0xd0] + cmovngl %eax,%edx + +// CHECK: cmovll %eax, %edx +// CHECK: encoding: [0x0f,0x4c,0xd0] + cmovngel %eax,%edx + +// CHECK: cmovgel %eax, %edx +// CHECK: encoding: [0x0f,0x4d,0xd0] + cmovnll %eax,%edx + +// CHECK: cmovgl %eax, %edx +// CHECK: encoding: [0x0f,0x4f,0xd0] + cmovnlel %eax,%edx + +// CHECK: cmovnol %eax, %edx +// CHECK: encoding: [0x0f,0x41,0xd0] + cmovnol %eax,%edx + +// CHECK: cmovnpl %eax, %edx +// CHECK: encoding: [0x0f,0x4b,0xd0] + cmovnpl %eax,%edx + +// CHECK: cmovnsl %eax, %edx +// CHECK: encoding: [0x0f,0x49,0xd0] + cmovnsl %eax,%edx + +// CHECK: cmovnel %eax, %edx +// CHECK: encoding: [0x0f,0x45,0xd0] + cmovnzl %eax,%edx + +// CHECK: cmovol %eax, %edx +// CHECK: encoding: [0x0f,0x40,0xd0] + cmovol %eax,%edx + +// CHECK: cmovpl %eax, %edx +// CHECK: encoding: [0x0f,0x4a,0xd0] + cmovpl %eax,%edx + +// CHECK: cmovsl %eax, %edx +// CHECK: encoding: [0x0f,0x48,0xd0] + cmovsl %eax,%edx + +// CHECK: cmovel %eax, %edx +// CHECK: encoding: [0x0f,0x44,0xd0] + cmovzl %eax,%edx From gohman at apple.com Mon May 24 15:51:08 2010 From: gohman at apple.com (Dan Gohman) Date: Mon, 24 May 2010 20:51:08 -0000 Subject: [llvm-commits] [llvm] r104552 - in /llvm/trunk: lib/Target/X86/X86InstrMMX.td test/MC/AsmParser/X86/x86_64-encoding.s Message-ID: <20100524205108.C3D84312800A@llvm.org> Author: djg Date: Mon May 24 15:51:08 2010 New Revision: 104552 URL: http://llvm.org/viewvc/llvm-project?rev=104552&view=rev Log: Fix an mmx movd encoding. Modified: llvm/trunk/lib/Target/X86/X86InstrMMX.td llvm/trunk/test/MC/AsmParser/X86/x86_64-encoding.s Modified: llvm/trunk/lib/Target/X86/X86InstrMMX.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrMMX.td?rev=104552&r1=104551&r2=104552&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrMMX.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrMMX.td Mon May 24 15:51:08 2010 @@ -130,10 +130,10 @@ def MMX_MOVD64from64rr : MMXRI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR64:$src), "movd\t{$src, $dst|$dst, $src}", []>; -def MMX_MOVD64rrv164 : MMXI<0x6E, MRMSrcReg, (outs VR64:$dst), (ins GR64:$src), - "movd\t{$src, $dst|$dst, $src}", - [(set VR64:$dst, - (v1i64 (scalar_to_vector GR64:$src)))]>; +def MMX_MOVD64rrv164 : MMXRI<0x6E, MRMSrcReg, (outs VR64:$dst), (ins GR64:$src), + "movd\t{$src, $dst|$dst, $src}", + [(set VR64:$dst, + (v1i64 (scalar_to_vector GR64:$src)))]>; let neverHasSideEffects = 1 in def MMX_MOVQ64rr : MMXI<0x6F, MRMSrcReg, (outs VR64:$dst), (ins VR64:$src), Modified: llvm/trunk/test/MC/AsmParser/X86/x86_64-encoding.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/X86/x86_64-encoding.s?rev=104552&r1=104551&r2=104552&view=diff ============================================================================== --- llvm/trunk/test/MC/AsmParser/X86/x86_64-encoding.s (original) +++ llvm/trunk/test/MC/AsmParser/X86/x86_64-encoding.s Mon May 24 15:51:08 2010 @@ -71,3 +71,35 @@ // CHECK: crc32q 4(%rbx), %rax // CHECK: encoding: [0xf2,0x48,0x0f,0x38,0xf1,0x43,0x04] crc32q 4(%rbx), %rax + +// CHECK: movd %r8, %mm1 +// CHECK: encoding: [0x49,0x0f,0x6e,0xc8] +movd %r8, %mm1 + +// CHECK: movd %r8d, %mm1 +// CHECK: encoding: [0x41,0x0f,0x6e,0xc8] +movd %r8d, %mm1 + +// CHECK: movd %rdx, %mm1 +// CHECK: encoding: [0x48,0x0f,0x6e,0xca] +movd %rdx, %mm1 + +// CHECK: movd %edx, %mm1 +// CHECK: encoding: [0x0f,0x6e,0xca] +movd %edx, %mm1 + +// CHECK: movd %mm1, %r8 +// CHECK: encoding: [0x49,0x0f,0x7e,0xc8] +movd %mm1, %r8 + +// CHECK: movd %mm1, %r8d +// CHECK: encoding: [0x41,0x0f,0x7e,0xc8] +movd %mm1, %r8d + +// CHECK: movd %mm1, %rdx +// CHECK: encoding: [0x48,0x0f,0x7e,0xca] +movd %mm1, %rdx + +// CHECK: movd %mm1, %edx +// CHECK: encoding: [0x0f,0x7e,0xca] +movd %mm1, %edx From evan.cheng at apple.com Mon May 24 16:33:37 2010 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 24 May 2010 21:33:37 -0000 Subject: [llvm-commits] [llvm] r104560 - in /llvm/trunk: include/llvm/CodeGen/MachineRegisterInfo.h lib/CodeGen/MachineFunction.cpp lib/CodeGen/MachineRegisterInfo.cpp Message-ID: <20100524213337.CA6E4312800A@llvm.org> Author: evancheng Date: Mon May 24 16:33:37 2010 New Revision: 104560 URL: http://llvm.org/viewvc/llvm-project?rev=104560&view=rev Log: Avoid adding duplicate function live-in's. Modified: llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h llvm/trunk/lib/CodeGen/MachineFunction.cpp llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp Modified: llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h?rev=104560&r1=104559&r2=104560&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h Mon May 24 16:33:37 2010 @@ -293,6 +293,10 @@ /// corresponding live-in physical register. unsigned getLiveInPhysReg(unsigned VReg) const; + /// getLiveInVirtReg - If PReg is a live-in physical register, return the + /// corresponding live-in physical register. + unsigned getLiveInVirtReg(unsigned PReg) const; + /// EmitLiveInCopies - Emit copies to initialize livein virtual registers /// into the given entry block. void EmitLiveInCopies(MachineBasicBlock *EntryMBB, Modified: llvm/trunk/lib/CodeGen/MachineFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineFunction.cpp?rev=104560&r1=104559&r2=104560&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineFunction.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineFunction.cpp Mon May 24 16:33:37 2010 @@ -398,8 +398,14 @@ unsigned MachineFunction::addLiveIn(unsigned PReg, const TargetRegisterClass *RC) { assert(RC->contains(PReg) && "Not the correct regclass!"); - unsigned VReg = getRegInfo().createVirtualRegister(RC); - getRegInfo().addLiveIn(PReg, VReg); + MachineRegisterInfo &MRI = getRegInfo(); + unsigned VReg = MRI.getLiveInVirtReg(PReg); + if (VReg) { + assert(MRI.getRegClass(VReg) == RC && "Register class mismatch!"); + return VReg; + } + VReg = MRI.createVirtualRegister(RC); + MRI.addLiveIn(PReg, VReg); return VReg; } Modified: llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp?rev=104560&r1=104559&r2=104560&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp Mon May 24 16:33:37 2010 @@ -165,6 +165,15 @@ return 0; } +/// getLiveInVirtReg - If PReg is a live-in physical register, return the +/// corresponding live-in physical register. +unsigned MachineRegisterInfo::getLiveInVirtReg(unsigned PReg) const { + for (livein_iterator I = livein_begin(), E = livein_end(); I != E; ++I) + if (I->first == PReg) + return I->second; + return 0; +} + static cl::opt SchedLiveInCopies("schedule-livein-copies", cl::Hidden, cl::desc("Schedule copies of livein registers"), From stoklund at 2pi.dk Mon May 24 16:46:58 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 24 May 2010 21:46:58 -0000 Subject: [llvm-commits] [llvm] r104563 - in /llvm/trunk: include/llvm/Target/Target.td include/llvm/Target/TargetRegisterInfo.h lib/Target/ARM/ARMRegisterInfo.td lib/Target/Blackfin/BlackfinRegisterInfo.td lib/Target/MSP430/MSP430RegisterInfo.td lib/Target/Mips/MipsRegisterInfo.td lib/Target/PowerPC/PPCRegisterInfo.td lib/Target/SystemZ/SystemZRegisterInfo.td lib/Target/X86/X86RegisterInfo.td utils/TableGen/CodeGenRegisters.h utils/TableGen/CodeGenTarget.cpp utils/TableGen/CodeGenTarget.h utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <20100524214658.E85E4312800A@llvm.org> Author: stoklund Date: Mon May 24 16:46:58 2010 New Revision: 104563 URL: http://llvm.org/viewvc/llvm-project?rev=104563&view=rev Log: Replace the tablegen RegisterClass field SubRegClassList with an alist-like data structure that represents a mapping without any dependencies on SubRegIndex numbering. This brings us closer to being able to remove the explicit SubRegIndex numbering, and it is now possible to specify any mapping without inventing *_INVALID register classes. Modified: llvm/trunk/include/llvm/Target/Target.td llvm/trunk/include/llvm/Target/TargetRegisterInfo.h llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td llvm/trunk/lib/Target/X86/X86RegisterInfo.td llvm/trunk/utils/TableGen/CodeGenRegisters.h llvm/trunk/utils/TableGen/CodeGenTarget.cpp llvm/trunk/utils/TableGen/CodeGenTarget.h llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Modified: llvm/trunk/include/llvm/Target/Target.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=104563&r1=104562&r2=104563&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/Target.td (original) +++ llvm/trunk/include/llvm/Target/Target.td Mon May 24 16:46:58 2010 @@ -125,9 +125,9 @@ // list MemberList = regList; - // SubClassList - Specify which register classes correspond to subregisters - // of this class. The order should be by subregister set index. - list SubRegClassList = []; + // SubRegClasses - Specify the register class of subregisters as a list of + // dags: (RegClass SubRegIndex, SubRegindex, ...) + list SubRegClasses = []; // MethodProtos/MethodBodies - These members can be used to insert arbitrary // code into a generated register class. The normal usage of this is to Modified: llvm/trunk/include/llvm/Target/TargetRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetRegisterInfo.h?rev=104563&r1=104562&r2=104563&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetRegisterInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetRegisterInfo.h Mon May 24 16:46:58 2010 @@ -152,9 +152,6 @@ /// index SubIdx, or NULL if no such class exists. const TargetRegisterClass* getSubRegisterRegClass(unsigned SubIdx) const { assert(SubIdx>0 && "Invalid subregister index"); - for (unsigned s = 0; s != SubIdx-1; ++s) - if (!SubRegClasses[s]) - return NULL; return SubRegClasses[SubIdx-1]; } Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td?rev=104563&r1=104562&r2=104563&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td Mon May 24 16:46:58 2010 @@ -23,6 +23,32 @@ let Namespace = "ARM"; } +// Subregister indices. +let Namespace = "ARM" in { +// Note: Code depends on these having consecutive numbers. +def ssub_0 : SubRegIndex { let NumberHack = 1; } +def ssub_1 : SubRegIndex { let NumberHack = 2; } +def ssub_2 : SubRegIndex { let NumberHack = 3; } +def ssub_3 : SubRegIndex { let NumberHack = 4; } + +def dsub_0 : SubRegIndex { let NumberHack = 5; } +def dsub_1 : SubRegIndex { let NumberHack = 6; } +def dsub_2 : SubRegIndex { let NumberHack = 7; } +def dsub_3 : SubRegIndex { let NumberHack = 8; } +def dsub_4 : SubRegIndex { let NumberHack = 9; } +def dsub_5 : SubRegIndex { let NumberHack = 10; } +def dsub_6 : SubRegIndex { let NumberHack = 11; } +def dsub_7 : SubRegIndex { let NumberHack = 12; } + +def qsub_0 : SubRegIndex { let NumberHack = 13; } +def qsub_1 : SubRegIndex { let NumberHack = 14; } +def qsub_2 : SubRegIndex { let NumberHack = 15; } +def qsub_3 : SubRegIndex { let NumberHack = 16; } + +def qqsub_0 : SubRegIndex { let NumberHack = 17; } +def qqsub_1 : SubRegIndex { let NumberHack = 18; } +} + // Integer registers def R0 : ARMReg< 0, "r0">, DwarfRegNum<[0]>; def R1 : ARMReg< 1, "r1">, DwarfRegNum<[1]>; @@ -308,7 +334,6 @@ D8, D9, D10, D11, D12, D13, D14, D15, D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30, D31]> { - let SubRegClassList = [SPR_INVALID, SPR_INVALID]; let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; iterator allocation_order_end(const MachineFunction &MF) const; @@ -356,14 +381,14 @@ def DPR_VFP2 : RegisterClass<"ARM", [f64, v8i8, v4i16, v2i32, v1i64, v2f32], 64, [D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15]> { - let SubRegClassList = [SPR, SPR]; + let SubRegClasses = [(SPR ssub_0, ssub_1)]; } // Subset of DPR which can be used as a source of NEON scalars for 16-bit // operations def DPR_8 : RegisterClass<"ARM", [f64, v8i8, v4i16, v2i32, v1i64, v2f32], 64, [D0, D1, D2, D3, D4, D5, D6, D7]> { - let SubRegClassList = [SPR_8, SPR_8]; + let SubRegClasses = [(SPR_8 ssub_0, ssub_1)]; } // Dummy 64-bit regclass to represent impossible subreg indices. @@ -377,27 +402,23 @@ def QPR : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], 128, [Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15]> { - let SubRegClassList = [SPR_INVALID, SPR_INVALID, SPR_INVALID, SPR_INVALID, - DPR, DPR, DPR_INVALID, DPR_INVALID, - DPR_INVALID, DPR_INVALID, DPR_INVALID, DPR_INVALID]; + let SubRegClasses = [(DPR dsub_0, dsub_1)]; } // Subset of QPR that have 32-bit SPR subregs. def QPR_VFP2 : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], 128, [Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]> { - let SubRegClassList = [SPR, SPR, SPR, SPR, - DPR_VFP2, DPR_VFP2, DPR_INVALID, DPR_INVALID, - DPR_INVALID, DPR_INVALID, DPR_INVALID, DPR_INVALID]; + let SubRegClasses = [(SPR ssub_0, ssub_1, ssub_2, ssub_3), + (DPR_VFP2 dsub_0, dsub_1)]; } // Subset of QPR that have DPR_8 and SPR_8 subregs. def QPR_8 : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], 128, [Q0, Q1, Q2, Q3]> { - let SubRegClassList = [SPR_8, SPR_8, SPR_8, SPR_8, - DPR_8, DPR_8, DPR_INVALID, DPR_INVALID, - DPR_INVALID, DPR_INVALID, DPR_INVALID, DPR_INVALID]; + let SubRegClasses = [(SPR_8 ssub_0, ssub_1, ssub_2, ssub_3), + (DPR_8 dsub_0, dsub_1)]; } // Dummy 128-bit regclass to represent impossible subreg indices. @@ -412,20 +433,18 @@ def QQPR : RegisterClass<"ARM", [v4i64], 256, [QQ0, QQ1, QQ2, QQ3, QQ4, QQ5, QQ6, QQ7]> { - let SubRegClassList = [SPR_INVALID, SPR_INVALID, SPR_INVALID, SPR_INVALID, - DPR, DPR, DPR, DPR, - DPR_INVALID, DPR_INVALID, DPR_INVALID, DPR_INVALID, - QPR, QPR, QPR_INVALID, QPR_INVALID]; + let SubRegClasses = [(DPR dsub_0, dsub_1, dsub_2, dsub_3), + (QPR qsub_0, qsub_1)]; } // Subset of QQPR that have 32-bit SPR subregs. def QQPR_VFP2 : RegisterClass<"ARM", [v4i64], 256, [QQ0, QQ1, QQ2, QQ3]> { - let SubRegClassList = [SPR, SPR, SPR, SPR, - DPR_VFP2, DPR_VFP2, DPR_VFP2, DPR_VFP2, - DPR_INVALID, DPR_INVALID, DPR_INVALID, DPR_INVALID, - QPR_VFP2, QPR_VFP2, QPR_INVALID, QPR_INVALID]; + let SubRegClasses = [(SPR ssub_0, ssub_1, ssub_2, ssub_3), + (DPR_VFP2 dsub_0, dsub_1, dsub_2, dsub_3), + (QPR_VFP2 qsub_0, qsub_1)]; + } // Pseudo 512-bit vector register class to model 4 consecutive Q registers @@ -433,9 +452,9 @@ def QQQQPR : RegisterClass<"ARM", [v8i64], 256, [QQQQ0, QQQQ1, QQQQ2, QQQQ3]> { - let SubRegClassList = [SPR_INVALID, SPR_INVALID, SPR_INVALID, SPR_INVALID, - DPR, DPR, DPR, DPR, DPR, DPR, DPR, DPR, - QPR, QPR, QPR, QPR]; + let SubRegClasses = [(DPR dsub_0, dsub_1, dsub_2, dsub_3, + dsub_4, dsub_5, dsub_6, dsub_7), + (QPR qsub_0, qsub_1, qsub_2, qsub_3)]; } // Condition code registers. @@ -445,30 +464,6 @@ // Subregister Set Definitions... now that we have all of the pieces, define the // sub registers for each register. // -let Namespace = "ARM" in { -// Note: Code depends on these having consecutive numbers. -def ssub_0 : SubRegIndex { let NumberHack = 1; } -def ssub_1 : SubRegIndex { let NumberHack = 2; } -def ssub_2 : SubRegIndex { let NumberHack = 3; } -def ssub_3 : SubRegIndex { let NumberHack = 4; } - -def dsub_0 : SubRegIndex { let NumberHack = 5; } -def dsub_1 : SubRegIndex { let NumberHack = 6; } -def dsub_2 : SubRegIndex { let NumberHack = 7; } -def dsub_3 : SubRegIndex { let NumberHack = 8; } -def dsub_4 : SubRegIndex { let NumberHack = 9; } -def dsub_5 : SubRegIndex { let NumberHack = 10; } -def dsub_6 : SubRegIndex { let NumberHack = 11; } -def dsub_7 : SubRegIndex { let NumberHack = 12; } - -def qsub_0 : SubRegIndex { let NumberHack = 13; } -def qsub_1 : SubRegIndex { let NumberHack = 14; } -def qsub_2 : SubRegIndex { let NumberHack = 15; } -def qsub_3 : SubRegIndex { let NumberHack = 16; } - -def qqsub_0 : SubRegIndex { let NumberHack = 17; } -def qqsub_1 : SubRegIndex { let NumberHack = 18; } -} // S sub-registers of D registers. def : SubRegSet<1, [D0, D1, D2, D3, D4, D5, D6, D7, Modified: llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td?rev=104563&r1=104562&r2=104563&view=diff ============================================================================== --- llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td (original) +++ llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td Mon May 24 16:46:58 2010 @@ -260,11 +260,11 @@ L0H, L0L, L1H, L1L, L2H, L2L, L3H, L3L]>; def D : RegisterClass<"BF", [i32], 32, [R0, R1, R2, R3, R4, R5, R6, R7]> { - let SubRegClassList = [D16L, D16H]; + let SubRegClasses = [(D16L lo16), (D16H hi16)]; } def P : RegisterClass<"BF", [i32], 32, [P0, P1, P2, P3, P4, P5, FP, SP]> { - let SubRegClassList = [P16L, P16H]; + let SubRegClasses = [(P16L lo16), (P16H hi16)]; let MethodProtos = [{ iterator allocation_order_end(const MachineFunction &MF) const; }]; @@ -287,7 +287,7 @@ def DP : RegisterClass<"BF", [i32], 32, [R0, R1, R2, R3, R4, R5, R6, R7, P0, P1, P2, P3, P4, P5, FP, SP]> { - let SubRegClassList = [DP16L, DP16H]; + let SubRegClasses = [(DP16L lo16), (DP16H hi16)]; let MethodProtos = [{ iterator allocation_order_end(const MachineFunction &MF) const; }]; Modified: llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td?rev=104563&r1=104562&r2=104563&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td (original) +++ llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td Mon May 24 16:46:58 2010 @@ -104,7 +104,7 @@ // Volatile, but not allocable PCW, SPW, SRW, CGW]> { - let SubRegClassList = [GR8]; + let SubRegClasses = [(GR8 subreg_8bit)]; let MethodProtos = [{ iterator allocation_order_end(const MachineFunction &MF) const; }]; Modified: llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td?rev=104563&r1=104562&r2=104563&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td (original) +++ llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td Mon May 24 16:46:58 2010 @@ -257,7 +257,7 @@ // Reserved D15]> { - let SubRegClassList = [FGR32, FGR32]; + let SubRegClasses = [(FGR32 sub_fpeven, sub_fpodd)]; let MethodProtos = [{ iterator allocation_order_end(const MachineFunction &MF) const; }]; Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td?rev=104563&r1=104562&r2=104563&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td (original) +++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td Mon May 24 16:46:58 2010 @@ -379,7 +379,7 @@ def CRRC : RegisterClass<"PPC", [i32], 32, [CR0, CR1, CR5, CR6, CR7, CR2, CR3, CR4]> { - let SubRegClassList = [CRBITRC, CRBITRC, CRBITRC, CRBITRC]; + let SubRegClasses = [(CRBITRC sub_lt, sub_gt, sub_eq, sub_un)]; } def CTRRC : RegisterClass<"PPC", [i32], 32, [CTR]>; Modified: llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td?rev=104563&r1=104562&r2=104563&view=diff ============================================================================== --- llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td (original) +++ llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td Mon May 24 16:46:58 2010 @@ -278,7 +278,7 @@ // Volatile, but not allocable R14D, R15D]> { - let SubRegClassList = [GR32]; + let SubRegClasses = [(GR32 subreg_32bit)]; let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; iterator allocation_order_end(const MachineFunction &MF) const; @@ -325,7 +325,7 @@ // Volatile, but not allocable R14D, R15D]> { - let SubRegClassList = [ADDR32]; + let SubRegClasses = [(ADDR32 subreg_32bit)]; let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; iterator allocation_order_end(const MachineFunction &MF) const; @@ -368,7 +368,7 @@ def GR64P : RegisterClass<"SystemZ", [v2i32], 64, [R0P, R2P, R4P, R6P, R8P, R10P, R12P, R14P]> { - let SubRegClassList = [GR32, GR32]; + let SubRegClasses = [(GR32 subreg_even32, subreg_odd32)]; let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; iterator allocation_order_end(const MachineFunction &MF) const; @@ -404,7 +404,8 @@ def GR128 : RegisterClass<"SystemZ", [v2i64], 128, [R0Q, R2Q, R4Q, R6Q, R8Q, R10Q, R12Q, R14Q]> { - let SubRegClassList = [GR32, GR32, GR64, GR64]; + let SubRegClasses = [(GR32 subreg_even32, subreg_odd32), + (GR64 subreg_even, subreg_odd)]; let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; iterator allocation_order_end(const MachineFunction &MF) const; @@ -464,7 +465,7 @@ def FP64 : RegisterClass<"SystemZ", [f64], 64, [F0L, F1L, F2L, F3L, F4L, F5L, F6L, F7L, F8L, F9L, F10L, F11L, F12L, F13L, F14L, F15L]> { - let SubRegClassList = [FP32]; + let SubRegClasses = [(FP32 subreg_32bit)]; let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; iterator allocation_order_end(const MachineFunction &MF) const; Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.td?rev=104563&r1=104562&r2=104563&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.td Mon May 24 16:46:58 2010 @@ -363,7 +363,7 @@ def GR16 : RegisterClass<"X86", [i16], 16, [AX, CX, DX, SI, DI, BX, BP, SP, R8W, R9W, R10W, R11W, R14W, R15W, R12W, R13W]> { - let SubRegClassList = [GR8, GR8]; + let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi)]; let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; iterator allocation_order_end(const MachineFunction &MF) const; @@ -415,7 +415,7 @@ def GR32 : RegisterClass<"X86", [i32], 32, [EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP, R8D, R9D, R10D, R11D, R14D, R15D, R12D, R13D]> { - let SubRegClassList = [GR8, GR8, GR16]; + let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi), (GR16 sub_16bit)]; let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; iterator allocation_order_end(const MachineFunction &MF) const; @@ -470,7 +470,9 @@ def GR64 : RegisterClass<"X86", [i64], 64, [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11, RBX, R14, R15, R12, R13, RBP, RSP, RIP]> { - let SubRegClassList = [GR8, GR8, GR16, GR32]; + let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi), + (GR16 sub_16bit), + (GR32 sub_32bit)]; let MethodProtos = [{ iterator allocation_order_end(const MachineFunction &MF) const; }]; @@ -519,20 +521,27 @@ def GR8_ABCD_H : RegisterClass<"X86", [i8], 8, [AH, CH, DH, BH]> { } def GR16_ABCD : RegisterClass<"X86", [i16], 16, [AX, CX, DX, BX]> { - let SubRegClassList = [GR8_ABCD_L, GR8_ABCD_H]; + let SubRegClasses = [(GR8_ABCD_L sub_8bit), (GR8_ABCD_H sub_8bit_hi)]; } def GR32_ABCD : RegisterClass<"X86", [i32], 32, [EAX, ECX, EDX, EBX]> { - let SubRegClassList = [GR8_ABCD_L, GR8_ABCD_H, GR16_ABCD]; + let SubRegClasses = [(GR8_ABCD_L sub_8bit), + (GR8_ABCD_H sub_8bit_hi), + (GR16_ABCD sub_16bit)]; } def GR64_ABCD : RegisterClass<"X86", [i64], 64, [RAX, RCX, RDX, RBX]> { - let SubRegClassList = [GR8_ABCD_L, GR8_ABCD_H, GR16_ABCD, GR32_ABCD]; + let SubRegClasses = [(GR8_ABCD_L sub_8bit), + (GR8_ABCD_H sub_8bit_hi), + (GR16_ABCD sub_16bit), + (GR32_ABCD sub_32bit)]; } def GR32_TC : RegisterClass<"X86", [i32], 32, [EAX, ECX, EDX]> { - let SubRegClassList = [GR8, GR8, GR16]; + let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi), (GR16 sub_16bit)]; } def GR64_TC : RegisterClass<"X86", [i64], 64, [RAX, RCX, RDX, RSI, RDI, R8, R9, R11]> { - let SubRegClassList = [GR8, GR8, GR16, GR32_TC]; + let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi), + (GR16 sub_16bit), + (GR32_TC sub_32bit)]; } // GR8_NOREX - GR8 registers which do not require a REX prefix. @@ -572,7 +581,7 @@ // GR16_NOREX - GR16 registers which do not require a REX prefix. def GR16_NOREX : RegisterClass<"X86", [i16], 16, [AX, CX, DX, SI, DI, BX, BP, SP]> { - let SubRegClassList = [GR8_NOREX, GR8_NOREX]; + let SubRegClasses = [(GR8_NOREX sub_8bit, sub_8bit_hi)]; let MethodProtos = [{ iterator allocation_order_end(const MachineFunction &MF) const; }]; @@ -595,7 +604,8 @@ // GR32_NOREX - GR32 registers which do not require a REX prefix. def GR32_NOREX : RegisterClass<"X86", [i32], 32, [EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP]> { - let SubRegClassList = [GR8_NOREX, GR8_NOREX, GR16_NOREX]; + let SubRegClasses = [(GR8_NOREX sub_8bit, sub_8bit_hi), + (GR16_NOREX sub_16bit)]; let MethodProtos = [{ iterator allocation_order_end(const MachineFunction &MF) const; }]; @@ -618,7 +628,9 @@ // GR64_NOREX - GR64 registers which do not require a REX prefix. def GR64_NOREX : RegisterClass<"X86", [i64], 64, [RAX, RCX, RDX, RSI, RDI, RBX, RBP, RSP, RIP]> { - let SubRegClassList = [GR8_NOREX, GR8_NOREX, GR16_NOREX, GR32_NOREX]; + let SubRegClasses = [(GR8_NOREX sub_8bit, sub_8bit_hi), + (GR16_NOREX sub_16bit), + (GR32_NOREX sub_32bit)]; let MethodProtos = [{ iterator allocation_order_end(const MachineFunction &MF) const; }]; @@ -643,7 +655,7 @@ def GR32_NOSP : RegisterClass<"X86", [i32], 32, [EAX, ECX, EDX, ESI, EDI, EBX, EBP, R8D, R9D, R10D, R11D, R14D, R15D, R12D, R13D]> { - let SubRegClassList = [GR8, GR8, GR16]; + let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi), (GR16 sub_16bit)]; let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; iterator allocation_order_end(const MachineFunction &MF) const; @@ -696,7 +708,9 @@ def GR64_NOSP : RegisterClass<"X86", [i64], 64, [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11, RBX, R14, R15, R12, R13, RBP]> { - let SubRegClassList = [GR8, GR8, GR16, GR32_NOSP]; + let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi), + (GR16 sub_16bit), + (GR32_NOSP sub_32bit)]; let MethodProtos = [{ iterator allocation_order_end(const MachineFunction &MF) const; }]; @@ -721,7 +735,9 @@ // GR64_NOREX_NOSP - GR64_NOREX registers except RSP. def GR64_NOREX_NOSP : RegisterClass<"X86", [i64], 64, [RAX, RCX, RDX, RSI, RDI, RBX, RBP]> { - let SubRegClassList = [GR8_NOREX, GR8_NOREX, GR16_NOREX, GR32_NOREX]; + let SubRegClasses = [(GR8_NOREX sub_8bit, sub_8bit_hi), + (GR16_NOREX sub_16bit), + (GR32_NOREX sub_32bit)]; let MethodProtos = [{ iterator allocation_order_end(const MachineFunction &MF) const; }]; @@ -745,7 +761,9 @@ // A class to support the 'A' assembler constraint: EAX then EDX. def GR32_AD : RegisterClass<"X86", [i32], 32, [EAX, EDX]> { - let SubRegClassList = [GR8_ABCD_L, GR8_ABCD_H, GR16_ABCD]; + let SubRegClasses = [(GR8_ABCD_L sub_8bit), + (GR8_ABCD_H sub_8bit_hi), + (GR16_ABCD sub_16bit)]; } // Scalar SSE2 floating point registers. @@ -823,7 +841,8 @@ [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15]> { - let SubRegClassList = [FR32, FR64]; + let SubRegClasses = [(FR32 sub_ss), (FR64 sub_sd)]; + let MethodProtos = [{ iterator allocation_order_end(const MachineFunction &MF) const; }]; @@ -843,7 +862,7 @@ [YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7, YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15]> { - let SubRegClassList = [FR32, FR64, VR128]; + let SubRegClasses = [(FR32 sub_ss), (FR64 sub_sd), (VR128 sub_xmm)]; } // Status flags registers. Modified: llvm/trunk/utils/TableGen/CodeGenRegisters.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenRegisters.h?rev=104563&r1=104562&r2=104563&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenRegisters.h (original) +++ llvm/trunk/utils/TableGen/CodeGenRegisters.h Mon May 24 16:46:58 2010 @@ -16,6 +16,7 @@ #define CODEGEN_REGISTERS_H #include "llvm/CodeGen/ValueTypes.h" +#include "llvm/ADT/DenseMap.h" #include #include #include @@ -40,7 +41,8 @@ unsigned SpillSize; unsigned SpillAlignment; int CopyCost; - std::vector SubRegClasses; + // Map SubRegIndex -> RegisterClass + DenseMap SubRegClasses; std::string MethodProtos, MethodBodies; const std::string &getName() const; Modified: llvm/trunk/utils/TableGen/CodeGenTarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenTarget.cpp?rev=104563&r1=104562&r2=104563&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenTarget.cpp (original) +++ llvm/trunk/utils/TableGen/CodeGenTarget.cpp Mon May 24 16:46:58 2010 @@ -173,6 +173,10 @@ return TheDef->getName(); } +void CodeGenTarget::ReadSubRegIndices() const { + SubRegIndices = Records.getAllDerivedDefinitions("SubRegIndex"); +} + void CodeGenTarget::ReadRegisterClasses() const { std::vector RegClasses = Records.getAllDerivedDefinitions("RegisterClass"); @@ -229,17 +233,30 @@ "' does not derive from the Register class!"; Elements.push_back(Reg); } - - std::vector SubRegClassList = - R->getValueAsListOfDefs("SubRegClassList"); - for (unsigned i = 0, e = SubRegClassList.size(); i != e; ++i) { - Record *SubRegClass = SubRegClassList[i]; - if (!SubRegClass->isSubClassOf("RegisterClass")) - throw "Register Class member '" + SubRegClass->getName() + - "' does not derive from the RegisterClass class!"; - SubRegClasses.push_back(SubRegClass); - } - + + // SubRegClasses is a list containing (RC, subregindex, ...) dags. + ListInit *SRC = R->getValueAsListInit("SubRegClasses"); + for (ListInit::const_iterator i = SRC->begin(), e = SRC->end(); i != e; ++i) { + DagInit *DAG = dynamic_cast(*i); + if (!DAG) throw "SubRegClasses must contain DAGs"; + DefInit *DAGOp = dynamic_cast(DAG->getOperator()); + Record *RCRec; + if (!DAGOp || !(RCRec = DAGOp->getDef())->isSubClassOf("RegisterClass")) + throw "Operator '" + DAG->getOperator()->getAsString() + + "' in SubRegClasses is not a RegisterClass"; + // Iterate over args, all SubRegIndex instances. + for (DagInit::const_arg_iterator ai = DAG->arg_begin(), ae = DAG->arg_end(); + ai != ae; ++ai) { + DefInit *Idx = dynamic_cast(*ai); + Record *IdxRec; + if (!Idx || !(IdxRec = Idx->getDef())->isSubClassOf("SubRegIndex")) + throw "Argument '" + (*ai)->getAsString() + + "' in SubRegClasses is not a SubRegIndex"; + if (!SubRegClasses.insert(std::make_pair(IdxRec, RCRec)).second) + throw "SubRegIndex '" + IdxRec->getName() + "' mentioned twice"; + } + } + // Allow targets to override the size in bits of the RegisterClass. unsigned Size = R->getValueAsInt("Size"); Modified: llvm/trunk/utils/TableGen/CodeGenTarget.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenTarget.h?rev=104563&r1=104562&r2=104563&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenTarget.h (original) +++ llvm/trunk/utils/TableGen/CodeGenTarget.h Mon May 24 16:46:58 2010 @@ -19,14 +19,12 @@ #include "CodeGenRegisters.h" #include "CodeGenInstruction.h" +#include "Record.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/ADT/DenseMap.h" #include namespace llvm { -class Record; -class RecordKeeper; struct CodeGenRegister; class CodeGenTarget; @@ -65,9 +63,11 @@ mutable DenseMap Instructions; mutable std::vector Registers; + mutable std::vector SubRegIndices; mutable std::vector RegisterClasses; mutable std::vector LegalValueTypes; void ReadRegisters() const; + void ReadSubRegIndices() const; void ReadRegisterClasses() const; void ReadInstructions() const; void ReadLegalValueTypes() const; @@ -100,11 +100,21 @@ return Registers; } + const std::vector &getSubRegIndices() const { + if (SubRegIndices.empty()) ReadSubRegIndices(); + return SubRegIndices; + } + + // Map a SubRegIndex Record to its number. + unsigned getSubRegIndexNo(Record *idx) const { + return idx->getValueAsInt("NumberHack"); + } + const std::vector &getRegisterClasses() const { if (RegisterClasses.empty()) ReadRegisterClasses(); return RegisterClasses; } - + const CodeGenRegisterClass &getRegisterClass(Record *R) const { const std::vector &RC = getRegisterClasses(); for (unsigned i = 0, e = RC.size(); i != e; ++i) Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp?rev=104563&r1=104562&r2=104563&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Mon May 24 16:46:58 2010 @@ -44,8 +44,7 @@ if (!Namespace.empty()) OS << "}\n"; - const std::vector SubRegIndices = - Records.getAllDerivedDefinitions("SubRegIndex"); + const std::vector SubRegIndices = Target.getSubRegIndices(); if (!SubRegIndices.empty()) { OS << "\n// Subregister indices\n"; Namespace = SubRegIndices[0]->getValueAsString("Namespace"); @@ -260,80 +259,82 @@ std::map > SuperRegClassMap; OS << "\n"; - // Emit the sub-register classes for each RegisterClass - for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { - const CodeGenRegisterClass &RC = RegisterClasses[rc]; + unsigned NumSubRegIndices = Target.getSubRegIndices().size(); - // Give the register class a legal C name if it's anonymous. - std::string Name = RC.TheDef->getName(); + if (NumSubRegIndices) { + // Emit the sub-register classes for each RegisterClass + for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { + const CodeGenRegisterClass &RC = RegisterClasses[rc]; + std::vector SRC(NumSubRegIndices); + for (DenseMap::const_iterator + i = RC.SubRegClasses.begin(), + e = RC.SubRegClasses.end(); i != e; ++i) { + // Build SRC array. + unsigned idx = Target.getSubRegIndexNo(i->first); + SRC.at(idx-1) = i->second; + + // Find the register class number of i->second for SuperRegClassMap. + for (unsigned rc2 = 0, e2 = RegisterClasses.size(); rc2 != e2; ++rc2) { + const CodeGenRegisterClass &RC2 = RegisterClasses[rc2]; + if (RC2.TheDef == i->second) { + SuperRegClassMap[rc2].insert(rc); + break; + } + } + } - OS << " // " << Name - << " Sub-register Classes...\n" - << " static const TargetRegisterClass* const " - << Name << "SubRegClasses[] = {\n "; + // Give the register class a legal C name if it's anonymous. + std::string Name = RC.TheDef->getName(); - bool Empty = true; + OS << " // " << Name + << " Sub-register Classes...\n" + << " static const TargetRegisterClass* const " + << Name << "SubRegClasses[] = {\n "; + + for (unsigned idx = 0; idx != NumSubRegIndices; ++idx) { + if (idx) + OS << ", "; + if (SRC[idx]) + OS << "&" << getQualifiedName(SRC[idx]) << "RegClass"; + else + OS << "0"; + } + OS << "\n };\n\n"; + } - for (unsigned subrc = 0, subrcMax = RC.SubRegClasses.size(); - subrc != subrcMax; ++subrc) { - unsigned rc2 = 0, e2 = RegisterClasses.size(); - for (; rc2 != e2; ++rc2) { - const CodeGenRegisterClass &RC2 = RegisterClasses[rc2]; - if (RC.SubRegClasses[subrc]->getName() == RC2.getName()) { + // Emit the super-register classes for each RegisterClass + for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { + const CodeGenRegisterClass &RC = RegisterClasses[rc]; + + // Give the register class a legal C name if it's anonymous. + std::string Name = RC.TheDef->getName(); + + OS << " // " << Name + << " Super-register Classes...\n" + << " static const TargetRegisterClass* const " + << Name << "SuperRegClasses[] = {\n "; + + bool Empty = true; + std::map >::iterator I = + SuperRegClassMap.find(rc); + if (I != SuperRegClassMap.end()) { + for (std::set::iterator II = I->second.begin(), + EE = I->second.end(); II != EE; ++II) { + const CodeGenRegisterClass &RC2 = RegisterClasses[*II]; if (!Empty) OS << ", "; OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass"; Empty = false; - - std::map >::iterator SCMI = - SuperRegClassMap.find(rc2); - if (SCMI == SuperRegClassMap.end()) { - SuperRegClassMap.insert(std::make_pair(rc2, - std::set())); - SCMI = SuperRegClassMap.find(rc2); - } - SCMI->second.insert(rc); - break; } } - if (rc2 == e2) - throw "Register Class member '" + - RC.SubRegClasses[subrc]->getName() + - "' is not a valid RegisterClass!"; - } - - OS << (!Empty ? ", " : "") << "NULL"; - OS << "\n };\n\n"; - } - // Emit the super-register classes for each RegisterClass - for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { - const CodeGenRegisterClass &RC = RegisterClasses[rc]; - - // Give the register class a legal C name if it's anonymous. - std::string Name = RC.TheDef->getName(); - - OS << " // " << Name - << " Super-register Classes...\n" - << " static const TargetRegisterClass* const " - << Name << "SuperRegClasses[] = {\n "; - - bool Empty = true; - std::map >::iterator I = - SuperRegClassMap.find(rc); - if (I != SuperRegClassMap.end()) { - for (std::set::iterator II = I->second.begin(), - EE = I->second.end(); II != EE; ++II) { - const CodeGenRegisterClass &RC2 = RegisterClasses[*II]; - if (!Empty) - OS << ", "; - OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass"; - Empty = false; - } + OS << (!Empty ? ", " : "") << "NULL"; + OS << "\n };\n\n"; } - - OS << (!Empty ? ", " : "") << "NULL"; - OS << "\n };\n\n"; + } else { + // No subregindices in this target + OS << " static const TargetRegisterClass* const " + << "NullRegClasses[] = { NULL };\n\n"; } // Emit the sub-classes array for each RegisterClass @@ -430,8 +431,10 @@ << RC.getName() + "VTs" << ", " << RC.getName() + "Subclasses" << ", " << RC.getName() + "Superclasses" << ", " - << RC.getName() + "SubRegClasses" << ", " - << RC.getName() + "SuperRegClasses" << ", " + << (NumSubRegIndices ? RC.getName() + "Sub" : std::string("Null")) + << "RegClasses, " + << (NumSubRegIndices ? RC.getName() + "Super" : std::string("Null")) + << "RegClasses, " << RC.SpillSize/8 << ", " << RC.SpillAlignment/8 << ", " << RC.CopyCost << ", " From stoklund at 2pi.dk Mon May 24 16:47:01 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 24 May 2010 21:47:01 -0000 Subject: [llvm-commits] [llvm] r104564 - /llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td Message-ID: <20100524214701.AB2773128018@llvm.org> Author: stoklund Date: Mon May 24 16:47:01 2010 New Revision: 104564 URL: http://llvm.org/viewvc/llvm-project?rev=104564&view=rev Log: Lose the dummies Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td?rev=104564&r1=104563&r2=104564&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td Mon May 24 16:47:01 2010 @@ -84,7 +84,6 @@ def S26 : ARMFReg<26, "s26">; def S27 : ARMFReg<27, "s27">; def S28 : ARMFReg<28, "s28">; def S29 : ARMFReg<29, "s29">; def S30 : ARMFReg<30, "s30">; def S31 : ARMFReg<31, "s31">; -def SDummy : ARMFReg<63, "sINVALID">; // Aliases of the F* registers used to hold 64-bit fp values (doubles) def D0 : ARMReg< 0, "d0", [S0, S1]>; @@ -113,7 +112,6 @@ def D26 : ARMFReg<26, "d26">; def D27 : ARMFReg<27, "d27">; def D28 : ARMFReg<28, "d28">; def D29 : ARMFReg<29, "d29">; def D30 : ARMFReg<30, "d30">; def D31 : ARMFReg<31, "d31">; -def DDummy : ARMFReg<31, "dINVALID">; // Advanced SIMD (NEON) defines 16 quad-word aliases def Q0 : ARMReg< 0, "q0", [D0, D1]>; @@ -132,7 +130,6 @@ def Q13 : ARMReg<13, "q13", [D26, D27]>; def Q14 : ARMReg<14, "q14", [D28, D29]>; def Q15 : ARMReg<15, "q15", [D30, D31]>; -def QDummy : ARMFReg<16, "qINVALID">; // Pseudo 256-bit registers to represent pairs of Q registers. These should // never be present in the emitted code. @@ -320,11 +317,6 @@ [S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12, S13, S14, S15]>; -// Dummy f32 regclass to represent impossible subreg indices. -def SPR_INVALID : RegisterClass<"ARM", [f32], 32, [SDummy]> { - let CopyCost = -1; -} - // Scalar double precision floating point / generic 64-bit vector register // class. // ARM requires only word alignment for double. It's more performant if it @@ -391,13 +383,6 @@ let SubRegClasses = [(SPR_8 ssub_0, ssub_1)]; } -// Dummy 64-bit regclass to represent impossible subreg indices. -def DPR_INVALID : RegisterClass<"ARM", - [f64, v8i8, v4i16, v2i32, v1i64, v2f32], 64, - [DDummy]> { - let CopyCost = -1; -} - // Generic 128-bit vector register class. def QPR : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], 128, [Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, @@ -421,13 +406,6 @@ (DPR_8 dsub_0, dsub_1)]; } -// Dummy 128-bit regclass to represent impossible subreg indices. -def QPR_INVALID : RegisterClass<"ARM", - [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], 128, - [QDummy]> { - let CopyCost = -1; -} - // Pseudo 256-bit vector register class to model pairs of Q registers // (4 consecutive D registers). def QQPR : RegisterClass<"ARM", [v4i64], From sabre at nondot.org Mon May 24 16:55:47 2010 From: sabre at nondot.org (Chris Lattner) Date: Mon, 24 May 2010 21:55:47 -0000 Subject: [llvm-commits] [llvm] r104567 - /llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Message-ID: <20100524215547.8A356312800A@llvm.org> Author: lattner Date: Mon May 24 16:55:47 2010 New Revision: 104567 URL: http://llvm.org/viewvc/llvm-project?rev=104567&view=rev Log: diaggroup categories should take precedence over diag-specific groups. Modified: llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Modified: llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp?rev=104567&r1=104566&r2=104567&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/ClangDiagnosticsEmitter.cpp Mon May 24 16:55:47 2010 @@ -70,15 +70,16 @@ /// lives in. static std::string getDiagnosticCategory(const Record *R, DiagGroupParentMap &DiagGroupParents) { - // If the diagnostic itself has a category, get it. - std::string CatName = R->getValueAsString("CategoryName"); - if (!CatName.empty()) return CatName; - - DefInit *Group = dynamic_cast(R->getValueInit("Group")); - if (Group == 0) return ""; + // If the diagnostic is in a group, and that group has a category, use it. + if (DefInit *Group = dynamic_cast(R->getValueInit("Group"))) { + // Check the diagnostic's diag group for a category. + std::string CatName = getCategoryFromDiagGroup(Group->getDef(), + DiagGroupParents); + if (!CatName.empty()) return CatName; + } - // Check the diagnostic's diag group for a category. - return getCategoryFromDiagGroup(Group->getDef(), DiagGroupParents); + // If the diagnostic itself has a category, get it. + return R->getValueAsString("CategoryName"); } namespace { From bob.wilson at apple.com Mon May 24 17:41:19 2010 From: bob.wilson at apple.com (Bob Wilson) Date: Mon, 24 May 2010 22:41:19 -0000 Subject: [llvm-commits] [llvm] r104570 - /llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Message-ID: <20100524224119.944C8312800A@llvm.org> Author: bwilson Date: Mon May 24 17:41:19 2010 New Revision: 104570 URL: http://llvm.org/viewvc/llvm-project?rev=104570&view=rev Log: Allow Thumb2 MVN instructions to set condition codes. The immediate operand version of t2MVN already allowed that, but not the register versions. Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=104570&r1=104569&r2=104570&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Mon May 24 17:41:19 2010 @@ -185,8 +185,8 @@ let Inst{15} = 0; } // register - def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr, - opc, ".w\t$dst, $src", + def r : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr, + opc, ".w\t$dst, $src", [(set GPR:$dst, (opnode GPR:$src))]> { let Inst{31-27} = 0b11101; let Inst{26-25} = 0b01; @@ -198,9 +198,9 @@ let Inst{5-4} = 0b00; // type } // shifted register - def s : T2I<(outs GPR:$dst), (ins t2_so_reg:$src), IIC_iMOVsi, - opc, ".w\t$dst, $src", - [(set GPR:$dst, (opnode t2_so_reg:$src))]> { + def s : T2sI<(outs GPR:$dst), (ins t2_so_reg:$src), IIC_iMOVsi, + opc, ".w\t$dst, $src", + [(set GPR:$dst, (opnode t2_so_reg:$src))]> { let Inst{31-27} = 0b11101; let Inst{26-25} = 0b01; let Inst{24-21} = opcod; From stoklund at 2pi.dk Mon May 24 18:03:18 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 24 May 2010 23:03:18 -0000 Subject: [llvm-commits] [llvm] r104571 - in /llvm/trunk: include/llvm/Target/Target.td lib/Target/ARM/ARMRegisterInfo.td lib/Target/Blackfin/BlackfinRegisterInfo.td lib/Target/MSP430/MSP430RegisterInfo.td lib/Target/Mips/MipsRegisterInfo.td lib/Target/PowerPC/PPCRegisterInfo.td lib/Target/SystemZ/SystemZRegisterInfo.td lib/Target/X86/X86RegisterInfo.td utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <20100524230319.0FAD8312800A@llvm.org> Author: stoklund Date: Mon May 24 18:03:18 2010 New Revision: 104571 URL: http://llvm.org/viewvc/llvm-project?rev=104571&view=rev Log: Switch SubRegSet to using symbolic SubRegIndices Modified: llvm/trunk/include/llvm/Target/Target.td llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td llvm/trunk/lib/Target/X86/X86RegisterInfo.td llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Modified: llvm/trunk/include/llvm/Target/Target.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=104571&r1=104570&r2=104571&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/Target.td (original) +++ llvm/trunk/include/llvm/Target/Target.td Mon May 24 18:03:18 2010 @@ -21,6 +21,7 @@ class RegisterClass; // Forward def +// SubRegIndex - Use instances on SubRegIndex to identify subregisters. class SubRegIndex { string Namespace = ""; @@ -80,8 +81,8 @@ // indices, for use as named subregs of a particular physical register. Each // register in 'subregs' becomes an addressable subregister at index 'n' of the // corresponding register in 'regs'. -class SubRegSet regs, list subregs> { - int index = n; +class SubRegSet regs, list subregs> { + SubRegIndex Index = n; list From = regs; list To = subregs; Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td?rev=104571&r1=104570&r2=104571&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td Mon May 24 18:03:18 2010 @@ -444,96 +444,96 @@ // // S sub-registers of D registers. -def : SubRegSet<1, [D0, D1, D2, D3, D4, D5, D6, D7, - D8, D9, D10, D11, D12, D13, D14, D15], - [S0, S2, S4, S6, S8, S10, S12, S14, - S16, S18, S20, S22, S24, S26, S28, S30]>; -def : SubRegSet<2, [D0, D1, D2, D3, D4, D5, D6, D7, - D8, D9, D10, D11, D12, D13, D14, D15], - [S1, S3, S5, S7, S9, S11, S13, S15, - S17, S19, S21, S23, S25, S27, S29, S31]>; +def : SubRegSet; +def : SubRegSet; // S sub-registers of Q registers. -def : SubRegSet<1, [Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7], - [S0, S4, S8, S12, S16, S20, S24, S28]>; -def : SubRegSet<2, [Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7], - [S1, S5, S9, S13, S17, S21, S25, S29]>; -def : SubRegSet<3, [Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7], - [S2, S6, S10, S14, S18, S22, S26, S30]>; -def : SubRegSet<4, [Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7], - [S3, S7, S11, S15, S19, S23, S27, S31]>; +def : SubRegSet; +def : SubRegSet; +def : SubRegSet; +def : SubRegSet; // D sub-registers of Q registers. -def : SubRegSet<5, [Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, - Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15], - [D0, D2, D4, D6, D8, D10, D12, D14, - D16, D18, D20, D22, D24, D26, D28, D30]>; -def : SubRegSet<6, [Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, - Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15], - [D1, D3, D5, D7, D9, D11, D13, D15, - D17, D19, D21, D23, D25, D27, D29, D31]>; +def : SubRegSet; +def : SubRegSet; // S sub-registers of QQ registers. Note there are no sub-indices // for referencing S4 - S7, S12 - S15, and S20 - S23. It doesn't // look like we need them. -def : SubRegSet<1, [QQ0, QQ1, QQ2, QQ3], - [S0, S8, S16, S24]>; -def : SubRegSet<2, [QQ0, QQ1, QQ2, QQ3], - [S1, S9, S17, S25]>; -def : SubRegSet<3, [QQ0, QQ1, QQ2, QQ3], - [S2, S10, S18, S26]>; -def : SubRegSet<4, [QQ0, QQ1, QQ2, QQ3], - [S3, S11, S19, S27]>; +def : SubRegSet; +def : SubRegSet; +def : SubRegSet; +def : SubRegSet; // D sub-registers of QQ registers. -def : SubRegSet<5, [QQ0, QQ1, QQ2, QQ3, QQ4, QQ5, QQ6, QQ7], - [D0, D4, D8, D12, D16, D20, D24, D28]>; -def : SubRegSet<6, [QQ0, QQ1, QQ2, QQ3, QQ4, QQ5, QQ6, QQ7], - [D1, D5, D9, D13, D17, D21, D25, D29]>; -def : SubRegSet<7, [QQ0, QQ1, QQ2, QQ3, QQ4, QQ5, QQ6, QQ7], - [D2, D6, D10, D14, D18, D22, D26, D30]>; -def : SubRegSet<8, [QQ0, QQ1, QQ2, QQ3, QQ4, QQ5, QQ6, QQ7], - [D3, D7, D11, D15, D19, D23, D27, D31]>; +def : SubRegSet; +def : SubRegSet; +def : SubRegSet; +def : SubRegSet; // Q sub-registers of QQ registers. -def : SubRegSet<13, [QQ0, QQ1, QQ2, QQ3, QQ4, QQ5, QQ6, QQ7], - [Q0, Q2, Q4, Q6, Q8, Q10, Q12, Q14]>; -def : SubRegSet<14,[QQ0, QQ1, QQ2, QQ3, QQ4, QQ5, QQ6, QQ7], - [Q1, Q3, Q5, Q7, Q9, Q11, Q13, Q15]>; +def : SubRegSet; +def : SubRegSet; // D sub-registers of QQQQ registers. -def : SubRegSet<5, [QQQQ0, QQQQ1, QQQQ2, QQQQ3], - [D0, D8, D16, D24]>; -def : SubRegSet<6, [QQQQ0, QQQQ1, QQQQ2, QQQQ3], - [D1, D9, D17, D25]>; -def : SubRegSet<7, [QQQQ0, QQQQ1, QQQQ2, QQQQ3], - [D2, D10, D18, D26]>; -def : SubRegSet<8, [QQQQ0, QQQQ1, QQQQ2, QQQQ3], - [D3, D11, D19, D27]>; - -def : SubRegSet<9, [QQQQ0, QQQQ1, QQQQ2, QQQQ3], - [D4, D12, D20, D28]>; -def : SubRegSet<10, [QQQQ0, QQQQ1, QQQQ2, QQQQ3], - [D5, D13, D21, D29]>; -def : SubRegSet<11, [QQQQ0, QQQQ1, QQQQ2, QQQQ3], - [D6, D14, D22, D30]>; -def : SubRegSet<12, [QQQQ0, QQQQ1, QQQQ2, QQQQ3], - [D7, D15, D23, D31]>; - -// Q sub-registers of QQQQQQQQ registers. -def : SubRegSet<13, [QQQQ0, QQQQ1, QQQQ2, QQQQ3], - [Q0, Q4, Q8, Q12]>; -def : SubRegSet<14, [QQQQ0, QQQQ1, QQQQ2, QQQQ3], - [Q1, Q5, Q9, Q13]>; -def : SubRegSet<15, [QQQQ0, QQQQ1, QQQQ2, QQQQ3], - [Q2, Q6, Q10, Q14]>; -def : SubRegSet<16, [QQQQ0, QQQQ1, QQQQ2, QQQQ3], - [Q3, Q7, Q11, Q15]>; - -// QQ sub-registers of QQQQQQQQ registers. -def : SubRegSet<17, [QQQQ0, QQQQ1, QQQQ2, QQQQ3], - [QQ0, QQ2, QQ4, QQ6]>; -def : SubRegSet<18, [QQQQ0, QQQQ1, QQQQ2, QQQQ3], - [QQ1, QQ3, QQ5, QQ7]>; +def : SubRegSet; +def : SubRegSet; +def : SubRegSet; +def : SubRegSet; + +def : SubRegSet; +def : SubRegSet; +def : SubRegSet; +def : SubRegSet; + +// Q sub-registers of QQQQ registers. +def : SubRegSet; +def : SubRegSet; +def : SubRegSet; +def : SubRegSet; + +// QQ sub-registers of QQQQ registers. +def : SubRegSet; +def : SubRegSet; Modified: llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td?rev=104571&r1=104570&r2=104571&view=diff ============================================================================== --- llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td (original) +++ llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td Mon May 24 18:03:18 2010 @@ -191,7 +191,7 @@ def LB0 : Ri<6, 2, "lb0">, DwarfRegNum<[48]>; def LB1 : Ri<6, 5, "lb1">, DwarfRegNum<[49]>; -def : SubRegSet<1, +def : SubRegSet; -def : SubRegSet<2, +def : SubRegSet; -def : SubRegSet<1, [A0, A0W, A1, A1W], [A0L, A0L, A1L, A1L]>; -def : SubRegSet<2, [A0, A0W, A1, A1W], [A0H, A0H, A1H, A1H]>; +def : SubRegSet; +def : SubRegSet; // Register classes. def D16 : RegisterClass<"BF", [i16], 16, Modified: llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td?rev=104571&r1=104570&r2=104571&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td (original) +++ llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td Mon May 24 18:03:18 2010 @@ -60,16 +60,16 @@ def R14W : MSP430RegWithSubregs<14, "r14", [R14B]>; def R15W : MSP430RegWithSubregs<15, "r15", [R15B]>; -def : SubRegSet<1, [PCW, SPW, SRW, CGW, FPW, - R5W, R6W, R7W, R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W], - [PCB, SPB, SRB, CGB, FPB, - R5B, R6B, R7B, R8B, R9B, R10B, R11B, R12B, R13B, R14B, R15B]>; - def subreg_8bit : SubRegIndex { let NumberHack = 1; let Namespace = "MSP430"; } +def : SubRegSet; + def GR8 : RegisterClass<"MSP430", [i8], 8, // Volatile registers [R12B, R13B, R14B, R15B, R11B, R10B, R9B, R8B, R7B, R6B, R5B, Modified: llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td?rev=104571&r1=104570&r2=104571&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td (original) +++ llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td Mon May 24 18:03:18 2010 @@ -149,15 +149,15 @@ def sub_fpodd : SubRegIndex { let NumberHack = 2; } } -def : SubRegSet<1, [D0, D1, D2, D3, D4, D5, D6, D7, - D8, D9, D10, D11, D12, D13, D14, D15], - [F0, F2, F4, F6, F8, F10, F12, F14, - F16, F18, F20, F22, F24, F26, F28, F30]>; - -def : SubRegSet<2, [D0, D1, D2, D3, D4, D5, D6, D7, - D8, D9, D10, D11, D12, D13, D14, D15], - [F1, F3, F5, F7, F9, F11, F13, F15, - F17, F19, F21, F23, F25, F27, F29, F31]>; +def : SubRegSet; + +def : SubRegSet; //===----------------------------------------------------------------------===// // Register Classes Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td?rev=104571&r1=104570&r2=104571&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td (original) +++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td Mon May 24 18:03:18 2010 @@ -241,14 +241,18 @@ def sub_un : SubRegIndex { let NumberHack = 4; } } -def : SubRegSet<1, [CR0, CR1, CR2, CR3, CR4, CR5, CR6, CR7], - [CR0LT, CR1LT, CR2LT, CR3LT, CR4LT, CR5LT, CR6LT, CR7LT]>; -def : SubRegSet<2, [CR0, CR1, CR2, CR3, CR4, CR5, CR6, CR7], - [CR0GT, CR1GT, CR2GT, CR3GT, CR4GT, CR5GT, CR6GT, CR7GT]>; -def : SubRegSet<3, [CR0, CR1, CR2, CR3, CR4, CR5, CR6, CR7], - [CR0EQ, CR1EQ, CR2EQ, CR3EQ, CR4EQ, CR5EQ, CR6EQ, CR7EQ]>; -def : SubRegSet<4, [CR0, CR1, CR2, CR3, CR4, CR5, CR6, CR7], - [CR0UN, CR1UN, CR2UN, CR3UN, CR4UN, CR5UN, CR6UN, CR7UN]>; +def : SubRegSet; +def : SubRegSet; +def : SubRegSet; +def : SubRegSet; // Link register def LR : SPR<8, "lr">, DwarfRegNum<[65]>; Modified: llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td?rev=104571&r1=104570&r2=104571&view=diff ============================================================================== --- llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td (original) +++ llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td Mon May 24 18:03:18 2010 @@ -153,28 +153,28 @@ def subreg_odd : SubRegIndex { let NumberHack = 4; } } -def : SubRegSet<1, [R0D, R1D, R2D, R3D, R4D, R5D, R6D, R7D, - R8D, R9D, R10D, R11D, R12D, R13D, R14D, R15D], - [R0W, R1W, R2W, R3W, R4W, R5W, R6W, R7W, - R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W]>; +def : SubRegSet; -def : SubRegSet<3, [R0Q, R2Q, R4Q, R6Q, R8Q, R10Q, R12Q, R14Q], - [R0D, R2D, R4D, R6D, R8D, R10D, R12D, R14D]>; +def : SubRegSet; -def : SubRegSet<4, [R0Q, R2Q, R4Q, R6Q, R8Q, R10Q, R12Q, R14Q], - [R1D, R3D, R5D, R7D, R9D, R11D, R13D, R15D]>; +def : SubRegSet; -def : SubRegSet<1, [R0P, R2P, R4P, R6P, R8P, R10P, R12P, R14P], - [R0W, R2W, R4W, R6W, R8W, R10W, R12W, R14W]>; +def : SubRegSet; -def : SubRegSet<2, [R0P, R2P, R4P, R6P, R8P, R10P, R12P, R14P], - [R1W, R3W, R5W, R7W, R9W, R11W, R13W, R15W]>; +def : SubRegSet; -def : SubRegSet<1, [R0Q, R2Q, R4Q, R6Q, R8Q, R10Q, R12Q, R14Q], - [R0W, R2W, R4W, R6W, R8W, R10W, R12W, R14W]>; +def : SubRegSet; -def : SubRegSet<2, [R0Q, R2Q, R4Q, R6Q, R8Q, R10Q, R12Q, R14Q], - [R1W, R3W, R5W, R7W, R9W, R11W, R13W, R15W]>; +def : SubRegSet; /// Register classes def GR32 : RegisterClass<"SystemZ", [i32], 32, Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.td?rev=104571&r1=104570&r2=104571&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.td Mon May 24 18:03:18 2010 @@ -235,69 +235,69 @@ // sub registers for each register. // -def : SubRegSet<1, [AX, CX, DX, BX, SP, BP, SI, DI, - R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W], - [AL, CL, DL, BL, SPL, BPL, SIL, DIL, - R8B, R9B, R10B, R11B, R12B, R13B, R14B, R15B]>; - -def : SubRegSet<2, [AX, CX, DX, BX], - [AH, CH, DH, BH]>; - -def : SubRegSet<1, [EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI, - R8D, R9D, R10D, R11D, R12D, R13D, R14D, R15D], - [AL, CL, DL, BL, SPL, BPL, SIL, DIL, - R8B, R9B, R10B, R11B, R12B, R13B, R14B, R15B]>; - -def : SubRegSet<2, [EAX, ECX, EDX, EBX], - [AH, CH, DH, BH]>; - -def : SubRegSet<3, [EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI, - R8D, R9D, R10D, R11D, R12D, R13D, R14D, R15D], - [AX, CX, DX, BX, SP, BP, SI, DI, - R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W]>; - -def : SubRegSet<1, [RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, - R8, R9, R10, R11, R12, R13, R14, R15], - [AL, CL, DL, BL, SPL, BPL, SIL, DIL, - R8B, R9B, R10B, R11B, R12B, R13B, R14B, R15B]>; - -def : SubRegSet<2, [RAX, RCX, RDX, RBX], - [AH, CH, DH, BH]>; - -def : SubRegSet<3, [RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, - R8, R9, R10, R11, R12, R13, R14, R15], - [AX, CX, DX, BX, SP, BP, SI, DI, - R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W]>; - -def : SubRegSet<4, [RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, - R8, R9, R10, R11, R12, R13, R14, R15], - [EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI, - R8D, R9D, R10D, R11D, R12D, R13D, R14D, R15D]>; - -def : SubRegSet<1, [YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7, - YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15], - [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, - XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15]>; - -def : SubRegSet<2, [YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7, - YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15], - [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, - XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15]>; - -def : SubRegSet<3, [YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7, - YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15], - [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, - XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15]>; - -def : SubRegSet<1, [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, - XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15], - [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, - XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15]>; - -def : SubRegSet<2, [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, - XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15], - [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, - XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15]>; +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; //===----------------------------------------------------------------------===// // Register Class Definitions... now that we have all of the pieces, define the Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp?rev=104571&r1=104570&r2=104571&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Mon May 24 18:03:18 2010 @@ -456,7 +456,8 @@ std::map, LessRecord> RegisterSubRegs; std::map, LessRecord> RegisterSuperRegs; std::map, LessRecord> RegisterAliases; - std::map > > SubRegVectors; + // Register -> [(SubRegIndex, Register)] + std::map > > SubRegVectors; typedef std::map, LessRecord> DwarfRegNumsMapTy; DwarfRegNumsMapTy DwarfRegNums; @@ -818,7 +819,7 @@ // Calculate the mapping of subregister+index pairs to physical registers. std::vector SubRegs = Records.getAllDerivedDefinitions("SubRegSet"); for (unsigned i = 0, e = SubRegs.size(); i != e; ++i) { - int subRegIndex = SubRegs[i]->getValueAsInt("index"); + Record *subRegIndex = SubRegs[i]->getValueAsDef("Index"); std::vector From = SubRegs[i]->getValueAsListOfDefs("From"); std::vector To = SubRegs[i]->getValueAsListOfDefs("To"); @@ -839,13 +840,14 @@ << "::getSubReg(unsigned RegNo, unsigned Index) const {\n" << " switch (RegNo) {\n" << " default:\n return 0;\n"; - for (std::map > >::iterator + for (std::map > >::iterator I = SubRegVectors.begin(), E = SubRegVectors.end(); I != E; ++I) { OS << " case " << getQualifiedName(I->first) << ":\n"; OS << " switch (Index) {\n"; OS << " default: return 0;\n"; for (unsigned i = 0, e = I->second.size(); i != e; ++i) - OS << " case " << (I->second)[i].first << ": return " + OS << " case " + << getQualifiedName((I->second)[i].first) << ": return " << getQualifiedName((I->second)[i].second) << ";\n"; OS << " };\n" << " break;\n"; } @@ -857,13 +859,14 @@ << "::getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const {\n" << " switch (RegNo) {\n" << " default:\n return 0;\n"; - for (std::map > >::iterator + for (std::map > >::iterator I = SubRegVectors.begin(), E = SubRegVectors.end(); I != E; ++I) { OS << " case " << getQualifiedName(I->first) << ":\n"; for (unsigned i = 0, e = I->second.size(); i != e; ++i) OS << " if (SubRegNo == " << getQualifiedName((I->second)[i].second) - << ") return " << (I->second)[i].first << ";\n"; + << ") return " + << getQualifiedName((I->second)[i].first) << ";\n"; OS << " return 0;\n"; } OS << " };\n"; From isanbard at gmail.com Mon May 24 18:16:04 2010 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 24 May 2010 23:16:04 -0000 Subject: [llvm-commits] [llvm] r104572 - /llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Message-ID: <20100524231604.5C344312800A@llvm.org> Author: void Date: Mon May 24 18:16:04 2010 New Revision: 104572 URL: http://llvm.org/viewvc/llvm-project?rev=104572&view=rev Log: Print out the name of the function during SSC. Modified: llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Modified: llvm/trunk/lib/CodeGen/StackSlotColoring.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackSlotColoring.cpp?rev=104572&r1=104571&r2=104572&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StackSlotColoring.cpp (original) +++ llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Mon May 24 18:16:04 2010 @@ -699,7 +699,11 @@ bool StackSlotColoring::runOnMachineFunction(MachineFunction &MF) { - DEBUG(dbgs() << "********** Stack Slot Coloring **********\n"); + DEBUG({ + dbgs() << "********** Stack Slot Coloring **********\n" + << "********** Function: " + << MF.getFunction()->getName() << '\n'; + }); MFI = MF.getFrameInfo(); MRI = &MF.getRegInfo(); From sliao at google.com Mon May 24 18:37:14 2010 From: sliao at google.com (Shih-wei Liao) Date: Mon, 24 May 2010 16:37:14 -0700 Subject: [llvm-commits] [PATCH] ARM JIT: Add support to MOVimm32 using movt/movw for JIT Message-ID: I agreed with Rafael that the patch is fine. It's more concise than my 29-line patch that I mentioned in my original bug report. E.g., I was adding in ARMCodeEmitter.cpp the "static inline unsigned rotr32" function which is unnecessary under Zonr's solution. Luckily I didn't get time to submit my patch yet, so we can just go ahead with Zonr's patch below. I reviewed and tested Zonr's patch and it passed all our tests. Rafael, if it's OK with you, could you commit Zonr's patch upstream? LGTM. On Thu, May 20, 2010 at 8:54 PM, Zonr Chang??wrote: > Sorry, I forgot to attach the patch ... :( > > Zonr > > >> 2010/5/21 Zonr Chang >> >> Thanks for your patch review (and also to Anton.) >> >> How to reuse the movw/movt logic is indeed a problem. PR7048 is an example. >> To fix this bug, we need to insert more codes into function >> emitDataProcessingInstruction(...) (see attachment.) >> >> It is because, precisely, the previous patch (arm-jit-movt-and-movw.patch) >> implemented the pseudo instruction ARM::MOVi32imm (which according to >> ARMInstrInfo.td should be materialized to movw/movt pair.) However, there's >> a case to use movw or movt as a single instruction to move value and their >> materialization will route to emitDataProcessingInstruction() since both >> movw (opcode ARM::MOVTi16) and movt (opcode ARM::MOVi16) are data processing >> instructions (i.e. ARMII::DPFrm.) >> >> In PR7048, the "1001" to printf(...) will be moved to the register using >> single instruction movw. As you can see in this patch, the logic to encode >> the immediate is reused the third time (one >> in emitDataProcessingInstruction(...) and one in relocation codes.) >> >> Is there a way to reuse the encoding codes? >> >> >> Zonr >> From stoklund at 2pi.dk Mon May 24 19:15:15 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 25 May 2010 00:15:15 -0000 Subject: [llvm-commits] [llvm] r104573 - in /llvm/trunk/lib/Target/ARM: ARMBaseRegisterInfo.cpp AsmPrinter/ARMAsmPrinter.cpp Message-ID: <20100525001515.479C2312800A@llvm.org> Author: stoklund Date: Mon May 24 19:15:15 2010 New Revision: 104573 URL: http://llvm.org/viewvc/llvm-project?rev=104573&view=rev Log: Use enums instead of literals in the ARM backend. Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp?rev=104573&r1=104572&r2=104573&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Mon May 24 19:15:15 2010 @@ -259,10 +259,10 @@ unsigned SubIdx) const { switch (SubIdx) { default: return 0; - case 1: - case 2: - case 3: - case 4: { + case ARM::ssub_0: + case ARM::ssub_1: + case ARM::ssub_2: + case ARM::ssub_3: { // S sub-registers. if (A->getSize() == 8) { if (B == &ARM::SPR_8RegClass) @@ -288,10 +288,10 @@ assert(A->getSize() == 64 && "Expecting a QQQQ register class!"); return 0; // Do not allow coalescing! } - case 5: - case 6: - case 7: - case 8: { + case ARM::dsub_0: + case ARM::dsub_1: + case ARM::dsub_2: + case ARM::dsub_3: { // D sub-registers. if (A->getSize() == 16) { if (B == &ARM::DPR_VFP2RegClass) @@ -314,18 +314,18 @@ return 0; // Do not allow coalescing! return A; } - case 9: - case 10: - case 11: - case 12: { + case ARM::dsub_4: + case ARM::dsub_5: + case ARM::dsub_6: + case ARM::dsub_7: { // D sub-registers of QQQQ registers. if (A->getSize() == 64 && B == &ARM::DPRRegClass) return A; return 0; // Do not allow coalescing! } - case 13: - case 14: { + case ARM::qsub_0: + case ARM::qsub_1: { // Q sub-registers. if (A->getSize() == 32) { if (B == &ARM::QPR_VFP2RegClass) @@ -340,8 +340,8 @@ return A; return 0; // Do not allow coalescing! } - case 15: - case 16: { + case ARM::qsub_2: + case ARM::qsub_3: { // Q sub-registers of QQQQ registers. if (A->getSize() == 64 && B == &ARM::QPRRegClass) return A; Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp?rev=104573&r1=104572&r2=104573&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Mon May 24 19:15:15 2010 @@ -327,8 +327,8 @@ } else if (Modifier && strcmp(Modifier, "lane") == 0) { unsigned RegNum = ARMRegisterInfo::getRegisterNumbering(Reg); unsigned DReg = - TM.getRegisterInfo()->getMatchingSuperReg(Reg, RegNum & 1 ? 2 : 1, - &ARM::DPR_VFP2RegClass); + TM.getRegisterInfo()->getMatchingSuperReg(Reg, + RegNum & 1 ? ARM::ssub_1 : ARM::ssub_0, &ARM::DPR_VFP2RegClass); O << getRegisterName(DReg) << '[' << (RegNum & 1) << ']'; } else { assert(!MO.getSubReg() && "Subregs should be eliminated!"); From stoklund at 2pi.dk Mon May 24 19:15:18 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 25 May 2010 00:15:18 -0000 Subject: [llvm-commits] [llvm] r104574 - /llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Message-ID: <20100525001518.48C203128018@llvm.org> Author: stoklund Date: Mon May 24 19:15:18 2010 New Revision: 104574 URL: http://llvm.org/viewvc/llvm-project?rev=104574&view=rev Log: Disable invalid coalescer assertion. Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp?rev=104574&r1=104573&r2=104574&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp (original) +++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Mon May 24 19:15:18 2010 @@ -853,8 +853,11 @@ // EAX: 1 -> AL, 2 -> AX // So RAX's sub-register 2 is AX, RAX's sub-regsiter 3 is EAX, whose // sub-register 2 is also AX. + // + // FIXME: Properly compose subreg indices for all targets. + // if (SubIdx && OldSubIdx && SubIdx != OldSubIdx) - assert(OldSubIdx < SubIdx && "Conflicting sub-register index!"); + ; else if (SubIdx) O.setSubReg(SubIdx); O.setReg(DstReg); From gkistanova at gmail.com Mon May 24 21:21:23 2010 From: gkistanova at gmail.com (Galina Kistanova) Date: Mon, 24 May 2010 19:21:23 -0700 Subject: [llvm-commits] [PATCH] 2 stage llvm-gcc builder for buildbot Message-ID: Hello everyone, Please find attached 2 patches. They add a new build script and a new builder for cross built self-hosted llvm and llvm-gcc. The build script firstly builds a cross llvm-gcc (--build=x86_64-apple-darwin10 --host=x86_64-apple-darwin10 --target=i686-pc-mingw32), then it cross builds a self-hosted llvm-gcc (--build=x86_64-apple-darwin10 --host=i686-pc-mingw32 --target=i686-pc-mingw32) with just built cross compiler. Please review. Thanks Galina -------------- next part -------------- A non-text attachment was scrubbed... Name: build-self-4-mingw32-script-01.diff Type: text/x-patch Size: 14160 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100524/280c8335/attachment.bin -------------- next part -------------- A non-text attachment was scrubbed... Name: build-self-4-mingw32-builder-01.diff Type: text/x-patch Size: 4850 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100524/280c8335/attachment-0001.bin From xuzhongxing at gmail.com Mon May 24 21:46:12 2010 From: xuzhongxing at gmail.com (Zhongxing Xu) Date: Tue, 25 May 2010 10:46:12 +0800 Subject: [llvm-commits] [PATCH] No need to check SRetReturnReg again In-Reply-To: References: Message-ID: ping? The reason of this change is that in LowerFormalArguments() we have: if (Is64Bit && MF.getFunction()->hasStructRetAttr()) { X86MachineFunctionInfo *FuncInfo = MF.getInfo(); unsigned Reg = FuncInfo->getSRetReturnReg(); if (!Reg) { Reg = MF.getRegInfo().createVirtualRegister(getRegClassFor(MVT::i64)); FuncInfo->setSRetReturnReg(Reg); } SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), dl, Reg, InVals[0]); Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Copy, Chain); } On Fri, May 21, 2010 at 3:45 PM, Zhongxing Xu wrote: > Index: lib/Target/X86/X86ISelLowering.cpp > =================================================================== > --- lib/Target/X86/X86ISelLowering.cpp (?? 104313) > +++ lib/Target/X86/X86ISelLowering.cpp (????) > @@ -1256,10 +1256,8 @@ > MachineFunction &MF = DAG.getMachineFunction(); > X86MachineFunctionInfo *FuncInfo = > MF.getInfo(); > unsigned Reg = FuncInfo->getSRetReturnReg(); > - if (!Reg) { > - Reg = MRI.createVirtualRegister(getRegClassFor(MVT::i64)); > - FuncInfo->setSRetReturnReg(Reg); > - } > + assert(Reg && > + "SRetReturnReg should have been set in > LowerFormalArguments()."); > SDValue Val = DAG.getCopyFromReg(Chain, dl, Reg, getPointerTy()); > > Chain = DAG.getCopyToReg(Chain, dl, X86::RAX, Val, Flag); > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100525/bbe64cc3/attachment.html From sabre at nondot.org Mon May 24 21:55:36 2010 From: sabre at nondot.org (Chris Lattner) Date: Tue, 25 May 2010 02:55:36 -0000 Subject: [llvm-commits] [www] r104579 - /www/trunk/index.html Message-ID: <20100525025536.28D78312800A@llvm.org> Author: lattner Date: Mon May 24 21:55:35 2010 New Revision: 104579 URL: http://llvm.org/viewvc/llvm-project?rev=104579&view=rev Log: llvm is not a vm Modified: www/trunk/index.html Modified: www/trunk/index.html URL: http://llvm.org/viewvc/llvm-project/www/trunk/index.html?rev=104579&r1=104578&r2=104579&view=diff ============================================================================== --- www/trunk/index.html (original) +++ www/trunk/index.html Mon May 24 21:55:35 2010 @@ -10,7 +10,11 @@

The LLVM Project is a collection of modular and reusable compiler and - toolchain technologies. From its humble beginnings as a research project at + toolchain technologies. Despite its name, LLVM has little to do with + traditional virtual machines, though it does provide helpful libraries that + can be used to build them.

+ +

From its humble beginnings as a research project at the University of Illinois, LLVM has grown to be an umbrella project consisting of a number of different subprojects, many of which are being used in production by a wide variety of From zonr.xchg at gmail.com Mon May 24 22:06:12 2010 From: zonr.xchg at gmail.com (Zonr Chang) Date: Tue, 25 May 2010 11:06:12 +0800 Subject: [llvm-commits] [PATCH] ARM JIT: Add support to MOVimm32 using movt/movw for JIT In-Reply-To: References: Message-ID: I just obtained commit-after-approval access. I'll commit this movt/movw patch later. Thanks for your review and approval. Zonr On Mon, May 24, 2010 at 4:05 AM, Rafael Espindola wrote: > Zonr, > > Do you have write access or do you need someone to commit the patch for > you? > > Cheers, > -- > Rafael ?vila de Esp?ndola > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100525/d2384980/attachment.html From bob.wilson at apple.com Mon May 24 22:36:52 2010 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 25 May 2010 03:36:52 -0000 Subject: [llvm-commits] [llvm] r104580 - /llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Message-ID: <20100525033652.A42E0312800A@llvm.org> Author: bwilson Date: Mon May 24 22:36:52 2010 New Revision: 104580 URL: http://llvm.org/viewvc/llvm-project?rev=104580&view=rev Log: Clean up indentation. Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=104580&r1=104579&r2=104580&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Mon May 24 22:36:52 2010 @@ -2395,9 +2395,9 @@ // Okay, we have a 64-bit SRA or SRL of 1. Lower this to an RRX expr. SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, N->getOperand(0), - DAG.getConstant(0, MVT::i32)); + DAG.getConstant(0, MVT::i32)); SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, N->getOperand(0), - DAG.getConstant(1, MVT::i32)); + DAG.getConstant(1, MVT::i32)); // First, build a SRA_FLAG/SRL_FLAG op, which shifts the top part by one and // captures the result into a carry flag. From bob.wilson at apple.com Mon May 24 23:43:09 2010 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 25 May 2010 04:43:09 -0000 Subject: [llvm-commits] [llvm] r104582 - /llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Message-ID: <20100525044309.0CC39312800A@llvm.org> Author: bwilson Date: Mon May 24 23:43:08 2010 New Revision: 104582 URL: http://llvm.org/viewvc/llvm-project?rev=104582&view=rev Log: Fix up instruction classes for Thumb2 RSB instructions to be consistent with Thumb2 ADD and SUB instructions: allow RSB instructions be changed to set the condition codes, and allow RSBS instructions to be predicated. Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=104582&r1=104581&r2=104582&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Mon May 24 23:43:08 2010 @@ -210,7 +210,7 @@ } /// T2I_bin_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a -// binary operation that produces a value. These are predicable and can be +/// binary operation that produces a value. These are predicable and can be /// changed to modify CPSR. multiclass T2I_bin_irs opcod, string opc, PatFrag opnode, bit Commutable = 0, string wide =""> { @@ -259,23 +259,23 @@ /// T2I_bin_irs counterpart. multiclass T2I_rbin_is opcod, string opc, PatFrag opnode> { // shifted imm - def ri : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs), IIC_iALUi, - opc, ".w\t$dst, $rhs, $lhs", - [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]> { + def ri : T2sI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs), IIC_iALUi, + opc, ".w\t$dst, $rhs, $lhs", + [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]> { let Inst{31-27} = 0b11110; let Inst{25} = 0; let Inst{24-21} = opcod; - let Inst{20} = 0; // The S bit. + let Inst{20} = ?; // The S bit. let Inst{15} = 0; } // shifted register - def rs : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs), IIC_iALUsi, - opc, "\t$dst, $rhs, $lhs", - [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]> { + def rs : T2sI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs), IIC_iALUsi, + opc, "\t$dst, $rhs, $lhs", + [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]> { let Inst{31-27} = 0b11101; let Inst{26-25} = 0b01; let Inst{24-21} = opcod; - let Inst{20} = 0; // The S bit. + let Inst{20} = ?; // The S bit. } } @@ -461,9 +461,9 @@ let Defs = [CPSR] in { multiclass T2I_rbin_s_is opcod, string opc, PatFrag opnode> { // shifted imm - def ri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs), IIC_iALUi, - !strconcat(opc, "s.w\t$dst, $rhs, $lhs"), - [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]> { + def ri : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs), IIC_iALUi, + !strconcat(opc, "s"), ".w\t$dst, $rhs, $lhs", + [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]> { let Inst{31-27} = 0b11110; let Inst{25} = 0; let Inst{24-21} = opcod; @@ -471,9 +471,9 @@ let Inst{15} = 0; } // shifted register - def rs : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs), IIC_iALUsi, - !strconcat(opc, "s\t$dst, $rhs, $lhs"), - [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]> { + def rs : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs), IIC_iALUsi, + !strconcat(opc, "s"), "\t$dst, $rhs, $lhs", + [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]> { let Inst{31-27} = 0b11101; let Inst{26-25} = 0b01; let Inst{24-21} = opcod; From bob.wilson at apple.com Mon May 24 23:51:47 2010 From: bob.wilson at apple.com (Bob Wilson) Date: Tue, 25 May 2010 04:51:47 -0000 Subject: [llvm-commits] [llvm] r104583 - /llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Message-ID: <20100525045147.81B56312800A@llvm.org> Author: bwilson Date: Mon May 24 23:51:47 2010 New Revision: 104583 URL: http://llvm.org/viewvc/llvm-project?rev=104583&view=rev Log: Allow t2MOVsrl_flag and t2MOVsra_flag instructions to be predicated. I don't know of any particular reason why that would be important, but neither can I see any reason to disallow it. Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=104583&r1=104582&r2=104583&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Mon May 24 23:51:47 2010 @@ -1575,9 +1575,9 @@ } let Defs = [CPSR] in { -def t2MOVsrl_flag : T2XI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, - "lsrs.w\t$dst, $src, #1", - [(set GPR:$dst, (ARMsrl_flag GPR:$src))]> { +def t2MOVsrl_flag : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, + "lsrs", ".w\t$dst, $src, #1", + [(set GPR:$dst, (ARMsrl_flag GPR:$src))]> { let Inst{31-27} = 0b11101; let Inst{26-25} = 0b01; let Inst{24-21} = 0b0010; @@ -1588,9 +1588,9 @@ let Inst{14-12} = 0b000; let Inst{7-6} = 0b01; } -def t2MOVsra_flag : T2XI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, - "asrs.w\t$dst, $src, #1", - [(set GPR:$dst, (ARMsra_flag GPR:$src))]> { +def t2MOVsra_flag : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, + "asrs", ".w\t$dst, $src, #1", + [(set GPR:$dst, (ARMsra_flag GPR:$src))]> { let Inst{31-27} = 0b11101; let Inst{26-25} = 0b01; let Inst{24-21} = 0b0010; From evan.cheng at apple.com Tue May 25 01:31:33 2010 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 24 May 2010 23:31:33 -0700 Subject: [llvm-commits] Global Merge Pass for ARM In-Reply-To: References: <1274006983.22060.61.camel@aslstation> <85FA0CB8-76CF-42A8-AD4F-C17F08902366@apple.com> Message-ID: On May 22, 2010, at 10:56 AM, Anton Korobeynikov wrote: > Hi, Evan > >> 3. MaxOffset should not be initialized when the pass is created. What if we want to support switching between ARM / Thumb mode on a function to function basis? Can it use TargetLowering::isLegalAddressingMode() or something similar instead? > Looks like this will require 2 new hooks like "getMaxGlobalOffset()" > and "getMinGlobalOffset()". The situation here is a little bit > different compared to the isLegalAddressingMode() - for example we're > still wanting to merge arrays of structs while isLegalAddressingMode() > works on simple types only... Or I'm missing something? Yes, adding a target hook for this seems like the right thing. Why do you need two though? Is getMinGlobalOffset necessary? Evan > > -- > With best regards, Anton Korobeynikov > Faculty of Mathematics and Mechanics, Saint Petersburg State University From sliao at google.com Tue May 25 03:21:03 2010 From: sliao at google.com (Shih-wei Liao) Date: Tue, 25 May 2010 01:21:03 -0700 Subject: [llvm-commits] [PATCH] To handle s* registers in emitVFPLoadStoreMultipleInstruction() Message-ID: Could someone review the patch in http://llvm.org/bugs/show_bug.cgi?id=7221? --- lib/Target/ARM/ARMCodeEmitter.cpp +++ lib/Target/ARM/ARMCodeEmitter.cpp break; ++NumRegs; } - Binary |= NumRegs * 2; + // bit 8 will be set if is consecutive 64-bit registers (e.g., d0) + if(Binary & 0x100) + Binary |= NumRegs * 2; + else + Binary |= NumRegs; emitWordLE(Binary); } Thanks. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100525/41c9295b/attachment.html From zonr.xchg at gmail.com Tue May 25 03:42:45 2010 From: zonr.xchg at gmail.com (Zonr Chang) Date: Tue, 25 May 2010 08:42:45 -0000 Subject: [llvm-commits] [llvm] r104587 - in /llvm/trunk/lib/Target/ARM: ARMCodeEmitter.cpp ARMJITInfo.cpp ARMRelocations.h Message-ID: <20100525084246.0A5F2312800A@llvm.org> Author: zonr Date: Tue May 25 03:42:45 2010 New Revision: 104587 URL: http://llvm.org/viewvc/llvm-project?rev=104587&view=rev Log: Add support to MOVimm32 using movt/movw for ARM JIT Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp llvm/trunk/lib/Target/ARM/ARMJITInfo.cpp llvm/trunk/lib/Target/ARM/ARMRelocations.h Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=104587&r1=104586&r2=104587&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Tue May 25 03:42:45 2010 @@ -88,6 +88,7 @@ void emitWordLE(unsigned Binary); void emitDWordLE(uint64_t Binary); void emitConstPoolInstruction(const MachineInstr &MI); + void emitMOVi32immInstruction(const MachineInstr &MI); void emitMOVi2piecesInstruction(const MachineInstr &MI); void emitLEApcrelJTInstruction(const MachineInstr &MI); void emitPseudoMoveInstruction(const MachineInstr &MI); @@ -145,6 +146,15 @@ return getMachineOpValue(MI, MI.getOperand(OpIdx)); } + /// getMovi32Value - Return binary encoding of operand for movw/movt. If the + /// machine operand requires relocation, record the relocation and return zero. + unsigned getMovi32Value(const MachineInstr &MI,const MachineOperand &MO, + unsigned Reloc); + unsigned getMovi32Value(const MachineInstr &MI, unsigned OpIdx, + unsigned Reloc) { + return getMovi32Value(MI, MI.getOperand(OpIdx), Reloc); + } + /// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value. /// unsigned getShiftOp(unsigned Imm) const ; @@ -217,6 +227,31 @@ return 0; } +/// getMovi32Value - Return binary encoding of operand for movw/movt. If the +/// machine operand requires relocation, record the relocation and return zero. +unsigned ARMCodeEmitter::getMovi32Value(const MachineInstr &MI, + const MachineOperand &MO, + unsigned Reloc) { + assert(((Reloc == ARM::reloc_arm_movt) || (Reloc == ARM::reloc_arm_movw)) + && "Relocation to this function should be for movt or movw"); + + if (MO.isImm()) + return static_cast(MO.getImm()); + else if (MO.isGlobal()) + emitGlobalAddress(MO.getGlobal(), Reloc, true, false); + else if (MO.isSymbol()) + emitExternalSymbolAddress(MO.getSymbolName(), Reloc); + else if (MO.isMBB()) + emitMachineBasicBlock(MO.getMBB(), Reloc); + else { +#ifndef NDEBUG + errs() << MO; +#endif + llvm_unreachable("Unsupported operand type for movw/movt"); + } + return 0; +} + /// getMachineOpValue - Return binary encoding of operand. If the machine /// operand requires relocation, record the relocation and return zero. unsigned ARMCodeEmitter::getMachineOpValue(const MachineInstr &MI, @@ -438,6 +473,42 @@ } } +void ARMCodeEmitter::emitMOVi32immInstruction(const MachineInstr &MI) { + const MachineOperand &MO0 = MI.getOperand(0); + const MachineOperand &MO1 = MI.getOperand(1); + + // Emit the 'movw' instruction. + unsigned Binary = 0x30 << 20; // mov: Insts{27-20} = 0b00110000 + + unsigned Lo16 = getMovi32Value(MI, MO1, ARM::reloc_arm_movw) & 0xFFFF; + + // Set the conditional execution predicate. + Binary |= II->getPredicate(&MI) << ARMII::CondShift; + + // Encode Rd. + Binary |= getMachineOpValue(MI, MO0) << ARMII::RegRdShift; + + // Encode imm16 as imm4:imm12 + Binary |= Lo16 & 0xFFF; // Insts{11-0} = imm12 + Binary |= ((Lo16 >> 12) & 0xF) << 16; // Insts{19-16} = imm4 + emitWordLE(Binary); + + unsigned Hi16 = getMovi32Value(MI, MO1, ARM::reloc_arm_movt) >> 16; + // Emit the 'movt' instruction. + Binary = 0x34 << 20; // movt: Insts{27-20} = 0b00110100 + + // Set the conditional execution predicate. + Binary |= II->getPredicate(&MI) << ARMII::CondShift; + + // Encode Rd. + Binary |= getMachineOpValue(MI, MO0) << ARMII::RegRdShift; + + // Encode imm16 as imm4:imm1, same as movw above. + Binary |= Hi16 & 0xFFF; + Binary |= ((Hi16 >> 12) & 0xF) << 16; + emitWordLE(Binary); +} + void ARMCodeEmitter::emitMOVi2piecesInstruction(const MachineInstr &MI) { const MachineOperand &MO0 = MI.getOperand(0); const MachineOperand &MO1 = MI.getOperand(1); @@ -557,7 +628,6 @@ switch (Opcode) { default: llvm_unreachable("ARMCodeEmitter::emitPseudoInstruction"); - // FIXME: Add support for MOVimm32. case TargetOpcode::INLINEASM: { // We allow inline assembler nodes with empty bodies - they can // implicitly define registers, which is ok for JIT. @@ -604,6 +674,11 @@ emitMiscLoadStoreInstruction(MI, ARM::PC); break; } + + case ARM::MOVi32imm: + emitMOVi32immInstruction(MI); + break; + case ARM::MOVi2pieces: // Two instructions to materialize a constant. emitMOVi2piecesInstruction(MI); @@ -729,6 +804,24 @@ Binary |= (ARMRegisterInfo::getRegisterNumbering(ImplicitRd) << ARMII::RegRdShift); + if (TID.Opcode == ARM::MOVi16) { + // Get immediate from MI. + unsigned Lo16 = getMovi32Value(MI, MI.getOperand(OpIdx), + ARM::reloc_arm_movw); + // Encode imm which is the same as in emitMOVi32immInstruction(). + Binary |= Lo16 & 0xFFF; + Binary |= ((Lo16 >> 12) & 0xF) << 16; + emitWordLE(Binary); + return; + } else if(TID.Opcode == ARM::MOVTi16) { + unsigned Hi16 = (getMovi32Value(MI, MI.getOperand(OpIdx), + ARM::reloc_arm_movt) >> 16); + Binary |= Hi16 & 0xFFF; + Binary |= ((Hi16 >> 12) & 0xF) << 16; + emitWordLE(Binary); + return; + } + // If this is a two-address operand, skip it. e.g. MOVCCr operand 1. if (TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1) ++OpIdx; Modified: llvm/trunk/lib/Target/ARM/ARMJITInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMJITInfo.cpp?rev=104587&r1=104586&r2=104587&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMJITInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMJITInfo.cpp Tue May 25 03:42:45 2010 @@ -318,6 +318,18 @@ *((intptr_t*)RelocPos) |= ResultPtr; break; } + case ARM::reloc_arm_movw: { + ResultPtr = ResultPtr & 0xFFFF; + *((intptr_t*)RelocPos) |= ResultPtr & 0xFFF; + *((intptr_t*)RelocPos) |= ((ResultPtr >> 12) & 0xF) << 16; + break; + } + case ARM::reloc_arm_movt: { + ResultPtr = (ResultPtr >> 16) & 0xFFFF; + *((intptr_t*)RelocPos) |= ResultPtr & 0xFFF; + *((intptr_t*)RelocPos) |= ((ResultPtr >> 12) & 0xF) << 16; + break; + } } } } Modified: llvm/trunk/lib/Target/ARM/ARMRelocations.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRelocations.h?rev=104587&r1=104586&r2=104587&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMRelocations.h (original) +++ llvm/trunk/lib/Target/ARM/ARMRelocations.h Tue May 25 03:42:45 2010 @@ -47,7 +47,13 @@ reloc_arm_pic_jt, // reloc_arm_branch - Branch address relocation. - reloc_arm_branch + reloc_arm_branch, + + // reloc_arm_movt - MOVT immediate relocation. + reloc_arm_movt, + + // reloc_arm_movw - MOVW immediate relocation. + reloc_arm_movw }; } } From sliao at google.com Tue May 25 03:50:54 2010 From: sliao at google.com (Shih-wei Liao) Date: Tue, 25 May 2010 01:50:54 -0700 Subject: [llvm-commits] [PATCH] ARM JIT: Add missing implementation to the materialization of VFP miscellaneous form instructions in JIT Message-ID: I reviewed and tested this patch. First, the code is good. (It corresponds to Table A7-18 in ARM Manual correctly.) Second, it passes all our tests. Thanks for the good patch. LGTM. On Sun, May 23, 2010 at 7:54 AM, Zonr Chang??wrote: > The attached patch adds missing implementation to the materialization of VFP > misc. instructions (i.e. instruction of the class VFPMiscFrm). This includes > vmrs, vmsr and vmov(immediate) (FCONSTD and FCONSTS). This patch should > resolve the PR7049 (http://llvm.org/bugs/show_bug.cgi?id=7049). > > P.S. Before you run the test code in PR7049, you may need to apply my > previous patch (arm-jit-movt-and-movw2.patch) first since printf(...) needs > movw/movt support. Changing "float" to "double" in test code also works. > > > Zonr > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100523/15fc80f2/attachment.html > -------------- next part -------------- > A non-text attachment was scrubbed... > Name: arm-jit-vfp-misc-inst.patch > Type: application/octet-stream > Size: 1838 bytes > Desc: not available > Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100523/15fc80f2/attachment.obj From zonr.xchg at gmail.com Tue May 25 05:24:36 2010 From: zonr.xchg at gmail.com (Zonr Chang) Date: Tue, 25 May 2010 18:24:36 +0800 Subject: [llvm-commits] [PATCH] ARM JIT: Add missing implementation to the materialization of VFP miscellaneous form instructions in JIT In-Reply-To: References: Message-ID: Thanks for your approval and quick review on this patch. Zonr On Tue, May 25, 2010 at 4:50 PM, Shih-wei Liao wrote: > I reviewed and tested this patch. > > First, the code is good. (It corresponds to Table A7-18 in ARM Manual > correctly.) > Second, it passes all our tests. Thanks for the good patch. > LGTM. > > On Sun, May 23, 2010 at 7:54 AM, Zonr Chang wrote: > > The attached patch adds missing implementation to the materialization of > VFP > > misc. instructions (i.e. instruction of the class VFPMiscFrm). This > includes > > vmrs, vmsr and vmov(immediate) (FCONSTD and FCONSTS). This patch should > > resolve the PR7049 (http://llvm.org/bugs/show_bug.cgi?id=7049). > > > > P.S. Before you run the test code in PR7049, you may need to apply my > > previous patch (arm-jit-movt-and-movw2.patch) first since printf(...) > needs > > movw/movt support. Changing "float" to "double" in test code also works. > > > > > > Zonr > > -------------- next part -------------- > > An HTML attachment was scrubbed... > > URL: > http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100523/15fc80f2/attachment.html > > -------------- next part -------------- > > A non-text attachment was scrubbed... > > Name: arm-jit-vfp-misc-inst.patch > > Type: application/octet-stream > > Size: 1838 bytes > > Desc: not available > > Url : > http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100523/15fc80f2/attachment.obj > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100525/24d7621c/attachment.html From zonr.xchg at gmail.com Tue May 25 05:23:52 2010 From: zonr.xchg at gmail.com (Zonr Chang) Date: Tue, 25 May 2010 10:23:52 -0000 Subject: [llvm-commits] [llvm] r104588 - /llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Message-ID: <20100525102352.B2CF4312800A@llvm.org> Author: zonr Date: Tue May 25 05:23:52 2010 New Revision: 104588 URL: http://llvm.org/viewvc/llvm-project?rev=104588&view=rev Log: Add missing implementation to the materialization of VFP misc. instructions (vmrs, vmsr and vmov (immediate)) Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=104588&r1=104587&r2=104588&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Tue May 25 05:23:52 2010 @@ -1465,12 +1465,55 @@ } void ARMCodeEmitter::emitMiscInstruction(const MachineInstr &MI) { + unsigned Opcode = MI.getDesc().Opcode; // Part of binary is determined by TableGn. unsigned Binary = getBinaryCodeForInstr(MI); // Set the conditional execution predicate Binary |= II->getPredicate(&MI) << ARMII::CondShift; + switch(Opcode) { + default: + llvm_unreachable("ARMCodeEmitter::emitMiscInstruction"); + + case ARM::FMSTAT: + // No further encoding needed. + break; + + case ARM::VMRS: + case ARM::VMSR: { + const MachineOperand &MO0 = MI.getOperand(0); + // Encode Rt. + Binary |= ARMRegisterInfo::getRegisterNumbering(MO0.getReg()) + << ARMII::RegRdShift; + break; + } + + case ARM::FCONSTD: + case ARM::FCONSTS: { + // Encode Dd / Sd. + Binary |= encodeVFPRd(MI, 0); + + // Encode imm., Table A7-18 VFP modified immediate constants + const MachineOperand &MO1 = MI.getOperand(1); + unsigned Imm = static_cast(MO1.getFPImm()->getValueAPF() + .bitcastToAPInt().getHiBits(32).getLimitedValue()); + unsigned ModifiedImm; + + if(Opcode == ARM::FCONSTS) + ModifiedImm = (Imm & 0x80000000) >> 24 | // a + (Imm & 0x03F80000) >> 19; // bcdefgh + else // Opcode == ARM::FCONSTD + ModifiedImm = (Imm & 0x80000000) >> 24 | // a + (Imm & 0x007F0000) >> 16; // bcdefgh + + // Insts{19-16} = abcd, Insts{3-0} = efgh + Binary |= ((ModifiedImm & 0xF0) >> 4) << 16; + Binary |= (ModifiedImm & 0xF); + break; + } + } + emitWordLE(Binary); } From zonr.xchg at gmail.com Tue May 25 06:00:05 2010 From: zonr.xchg at gmail.com (Zonr Chang) Date: Tue, 25 May 2010 19:00:05 +0800 Subject: [llvm-commits] [PATCH] To handle s* registers in emitVFPLoadStoreMultipleInstruction() In-Reply-To: References: Message-ID: I reviewed and tested this patch. Thanks for your hard working on reporting and resolving the bug in ARM JIT. LGTM. Zonr From: Shih-wei Liao > Date: Tue, May 25, 2010 at 1:21 AM > Subject: [PATCH] To handle s* registers in > emitVFPLoadStoreMultipleInstruction() > To: llvm-commits > > > Could someone review the patch in > http://llvm.org/bugs/show_bug.cgi?id=7221? > > --- lib/Target/ARM/ARMCodeEmitter.cpp > +++ lib/Target/ARM/ARMCodeEmitter.cpp > break; > ++NumRegs; > } > - Binary |= NumRegs * 2; > + // bit 8 will be set if is consecutive 64-bit registers (e.g., > d0) > + if(Binary & 0x100) > + Binary |= NumRegs * 2; > + else > + Binary |= NumRegs; > > emitWordLE(Binary); > } > > Thanks. > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100525/21615a4a/attachment.html From sliao at google.com Tue May 25 06:12:28 2010 From: sliao at google.com (Shih-wei Liao) Date: Tue, 25 May 2010 04:12:28 -0700 Subject: [llvm-commits] [PATCH] To fix "report_fatal_error("ARMv6t2 JIT is not yet supported.")" Message-ID: Bug 7222 (http://llvm.org/bugs/show_bug.cgi?id=7222) can be taken care of in a straightforward manner from the ARM Architecture Reference Manual. Could someone please examine the solution too? Thanks. From zonr.xchg at gmail.com Tue May 25 06:36:22 2010 From: zonr.xchg at gmail.com (Zonr Chang) Date: Tue, 25 May 2010 19:36:22 +0800 Subject: [llvm-commits] [PATCH] To fix "report_fatal_error("ARMv6t2 JIT is not yet supported.")" In-Reply-To: References: Message-ID: I just reviewed this bug and tried your patch in the bug report. It works and solve the problem. I make this patch in more formal form (see attachement). It looks great. It reuses functions Count[Trailing|Leading]Zeros_32() just like ARMAsmPrinter::printBitfieldInvMaskImmOperand() does to decode special imm. encoded in BFC/BFI's MachineInstr. LGTM. Zonr On Tue, May 25, 2010 at 7:12 PM, Shih-wei Liao wrote: > Bug 7222 (http://llvm.org/bugs/show_bug.cgi?id=7222) can be taken care > of in a straightforward manner from the ARM Architecture Reference > Manual. Could someone please examine the solution too? Thanks. > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100525/90e92e3f/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: arm-jit-bfc-and-bfi.patch Type: application/octet-stream Size: 1131 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100525/90e92e3f/attachment.obj From baldrick at free.fr Tue May 25 06:39:42 2010 From: baldrick at free.fr (Duncan Sands) Date: Tue, 25 May 2010 13:39:42 +0200 Subject: [llvm-commits] [PATCH] Fix for DragonEgg build launcher scripts and switch to ScriptedBuilder In-Reply-To: References: Message-ID: <4BFBB6FE.8070503@free.fr> Hi Galina, > patch07.diff fixes a possible infinite loop linked with ln commands, > and changes directory before the ln command so it could dial well with > the relative to the build root pathes. > > Both buildbot_self_strap and buildbot_self_strap-32 scripts could make > infinite loop of links on Linux if the build directories remain > between builds. This could happen because the second time "form 3 of > ln command" will be used. thanks for working on this. I don't understand what you mean by an infinite loop of links. What might happen is that the link gets placed inside the pre-existing directory. > -ln -sf $LLVM_SOURCE $BUILD_DIR/llvm > -ln -sf $DRAGONEGG_SOURCE $BUILD_DIR/dragonegg > +# Change the current directory to the build root. > +cd $BUILD_DIR Moving the "cd" up seems pointless. > +# Create links only if target directory or link does not exists. exists -> exist Also, the comment is wrong, since if the target link exists you do still create a new link. > +if [ ! -d $BUILD_DIR/llvm ] ; then > + ln -sf $LLVM_SOURCE $BUILD_DIR/llvm > +fi > +if [ ! -d $BUILD_DIR/dragonegg ] ; then > + ln -sf $DRAGONEGG_SOURCE $BUILD_DIR/dragonegg > +fi If the source already exists as a directory, presumably something funny is going on. Wouldn't it be better to bail out with an error in this case? In fact wouldn't it be better to bail out if the target exists and is not a symbol link? Ciao, Duncan. From sliao at google.com Tue May 25 08:58:51 2010 From: sliao at google.com (Shih-wei Liao) Date: Tue, 25 May 2010 06:58:51 -0700 Subject: [llvm-commits] [PATCH] ARM JIT: Add support to MOVimm32 using movt/movw for JIT In-Reply-To: References: Message-ID: Zonr committed it in r104587. On Mon, May 24, 2010 at 8:06 PM, Zonr Chang wrote: > I just obtained commit-after-approval access. I'll commit this movt/movw > patch later. Thanks for your review and approval. > > Zonr > > On Mon, May 24, 2010 at 4:05 AM, Rafael Espindola wrote: > >> Zonr, >> >> Do you have write access or do you need someone to commit the patch for >> you? >> >> Cheers, >> -- >> Rafael ?vila de Esp?ndola >> > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100525/3a60e48a/attachment.html From sliao at google.com Tue May 25 09:01:00 2010 From: sliao at google.com (Shih-wei Liao) Date: Tue, 25 May 2010 07:01:00 -0700 Subject: [llvm-commits] [PATCH] ARM JIT: Add missing implementation to the materialization of VFP miscellaneous form instructions in JIT In-Reply-To: References: Message-ID: Zonr committed it in r104588. Thanks. On Tue, May 25, 2010 at 3:24 AM, Zonr Chang wrote: > Thanks for your approval and quick review on this patch. > > Zonr > > > On Tue, May 25, 2010 at 4:50 PM, Shih-wei Liao wrote: > >> I reviewed and tested this patch. >> >> First, the code is good. (It corresponds to Table A7-18 in ARM Manual >> correctly.) >> Second, it passes all our tests. Thanks for the good patch. >> LGTM. >> >> On Sun, May 23, 2010 at 7:54 AM, Zonr Chang wrote: >> > The attached patch adds missing implementation to the materialization of >> VFP >> > misc. instructions (i.e. instruction of the class VFPMiscFrm). This >> includes >> > vmrs, vmsr and vmov(immediate) (FCONSTD and FCONSTS). This patch should >> > resolve the PR7049 (http://llvm.org/bugs/show_bug.cgi?id=7049). >> > >> > P.S. Before you run the test code in PR7049, you may need to apply my >> > previous patch (arm-jit-movt-and-movw2.patch) first since printf(...) >> needs >> > movw/movt support. Changing "float" to "double" in test code also works. >> > >> > >> > Zonr >> > -------------- next part -------------- >> > An HTML attachment was scrubbed... >> > URL: >> http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100523/15fc80f2/attachment.html >> > -------------- next part -------------- >> > A non-text attachment was scrubbed... >> > Name: arm-jit-vfp-misc-inst.patch >> > Type: application/octet-stream >> > Size: 1838 bytes >> > Desc: not available >> > Url : >> http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100523/15fc80f2/attachment.obj >> > > -- Thanks, Shih-wei -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100525/8aac28ee/attachment.html From baldrick at free.fr Tue May 25 09:09:48 2010 From: baldrick at free.fr (Duncan Sands) Date: Tue, 25 May 2010 16:09:48 +0200 Subject: [llvm-commits] [PATCH] No need to check SRetReturnReg again In-Reply-To: References: Message-ID: <4BFBDA2C.6060508@free.fr> Hi Zhongxing Xu, this looks ok to me. Was it applied? Ciao, Duncan. > ping? > > The reason of this change is that in LowerFormalArguments() we have: > > if (Is64Bit && MF.getFunction()->hasStructRetAttr()) { > X86MachineFunctionInfo *FuncInfo = > MF.getInfo(); > unsigned Reg = FuncInfo->getSRetReturnReg(); > if (!Reg) { > Reg = > MF.getRegInfo().createVirtualRegister(getRegClassFor(MVT::i64)); > FuncInfo->setSRetReturnReg(Reg); > } > SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), dl, Reg, > InVals[0]); > Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Copy, Chain); > } > > On Fri, May 21, 2010 at 3:45 PM, Zhongxing Xu > wrote: > > Index: lib/Target/X86/X86ISelLowering.cpp > =================================================================== > --- lib/Target/X86/X86ISelLowering.cpp (?? 104313) > +++ lib/Target/X86/X86ISelLowering.cpp (????) > @@ -1256,10 +1256,8 @@ > MachineFunction &MF = DAG.getMachineFunction(); > X86MachineFunctionInfo *FuncInfo = > MF.getInfo(); > unsigned Reg = FuncInfo->getSRetReturnReg(); > - if (!Reg) { > - Reg = MRI.createVirtualRegister(getRegClassFor(MVT::i64)); > - FuncInfo->setSRetReturnReg(Reg); > - } > + assert(Reg && > + "SRetReturnReg should have been set in LowerFormalArguments()."); > SDValue Val = DAG.getCopyFromReg(Chain, dl, Reg, getPointerTy()); > > Chain = DAG.getCopyToReg(Chain, dl, X86::RAX, Val, Flag); > > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From baldrick at free.fr Tue May 25 09:43:27 2010 From: baldrick at free.fr (Duncan Sands) Date: Tue, 25 May 2010 14:43:27 -0000 Subject: [llvm-commits] [dragonegg] r104605 - /dragonegg/trunk/llvm-backend.cpp Message-ID: <20100525144327.EAE25312800A@llvm.org> Author: baldrick Date: Tue May 25 09:43:27 2010 New Revision: 104605 URL: http://llvm.org/viewvc/llvm-project?rev=104605&view=rev Log: Don't use ODR linkage for an alias or thunk with DECL_ONE_ONLY unless the language specifies the ODR. I'm just being conservative here, no testcase. Modified: dragonegg/trunk/llvm-backend.cpp Modified: dragonegg/trunk/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-backend.cpp?rev=104605&r1=104604&r2=104605&view=diff ============================================================================== --- dragonegg/trunk/llvm-backend.cpp (original) +++ dragonegg/trunk/llvm-backend.cpp Tue May 25 09:43:27 2010 @@ -1651,7 +1651,7 @@ if (DECL_ONE_ONLY(decl)) // Copies of this DECL in multiple translation units should be merged. - return GlobalValue::WeakODRLinkage; + return GlobalValue::getWeakLinkage(flag_odr); if (DECL_WEAK(decl)) // The user may have explicitly asked for weak linkage - ignore flag_odr. From clattner at apple.com Tue May 25 10:34:47 2010 From: clattner at apple.com (Chris Lattner) Date: Tue, 25 May 2010 08:34:47 -0700 Subject: [llvm-commits] [PATCH] To fix "report_fatal_error("ARMv6t2 JIT is not yet supported.")" In-Reply-To: References: Message-ID: <43B21FD4-7E86-4434-ABDA-B80BA26AD75A@apple.com> On May 25, 2010, at 4:36 AM, Zonr Chang wrote: > I just reviewed this bug and tried your patch in the bug report. It works and solve the problem. I make this patch in more formal form (see attachement). > > It looks great. It reuses functions Count[Trailing|Leading]Zeros_32() just like ARMAsmPrinter::printBitfieldInvMaskImmOperand() does to decode special imm. encoded in BFC/BFI's MachineInstr. > LGTM. Patch looks ok to me, plz commit. -Chris > > Zonr > > > On Tue, May 25, 2010 at 7:12 PM, Shih-wei Liao wrote: > Bug 7222 (http://llvm.org/bugs/show_bug.cgi?id=7222) can be taken care > of in a straightforward manner from the ARM Architecture Reference > Manual. Could someone please examine the solution too? Thanks. > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100525/85a2fd38/attachment.html From stoklund at 2pi.dk Tue May 25 12:04:16 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 25 May 2010 17:04:16 -0000 Subject: [llvm-commits] [llvm] r104611 - in /llvm/trunk/lib/Target/X86: X86InstrInfo.cpp X86RegisterInfo.cpp Message-ID: <20100525170416.7B2993128018@llvm.org> Author: stoklund Date: Tue May 25 12:04:16 2010 New Revision: 104611 URL: http://llvm.org/viewvc/llvm-project?rev=104611&view=rev Log: Use enums instead of literals for X86 subregisters. The cases in getMatchingSuperRegClass cannot be broken up until the enums have unique values. Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=104611&r1=104610&r2=104611&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Tue May 25 12:04:16 2010 @@ -744,17 +744,17 @@ case X86::MOVZX32rr8: case X86::MOVSX64rr8: case X86::MOVZX64rr8: - SubIdx = 1; + SubIdx = X86::sub_8bit; break; case X86::MOVSX32rr16: case X86::MOVZX32rr16: case X86::MOVSX64rr16: case X86::MOVZX64rr16: - SubIdx = 3; + SubIdx = X86::sub_16bit; break; case X86::MOVSX64rr32: case X86::MOVZX64rr32: - SubIdx = 4; + SubIdx = X86::sub_32bit; break; } return true; Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp?rev=104611&r1=104610&r2=104611&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Tue May 25 12:04:16 2010 @@ -157,8 +157,8 @@ unsigned SubIdx) const { switch (SubIdx) { default: return 0; - case 1: - // 8-bit + case X86::sub_8bit: + //case X86::sub_ss: if (B == &X86::GR8RegClass) { if (A->getSize() == 2 || A->getSize() == 4 || A->getSize() == 8) return A; @@ -194,8 +194,8 @@ return A; } break; - case 2: - // 8-bit hi + case X86::sub_8bit_hi: + //case X86::sub_sd: if (B == &X86::GR8_ABCD_HRegClass) { if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass || A == &X86::GR64_NOREXRegClass || @@ -212,8 +212,8 @@ return A; } break; - case 3: - // 16-bit + case X86::sub_16bit: + //case X86::sub_xmm: if (B == &X86::GR16RegClass) { if (A->getSize() == 4 || A->getSize() == 8) return A; @@ -241,8 +241,7 @@ return A; } break; - case 4: - // 32-bit + case X86::sub_32bit: if (B == &X86::GR32RegClass || B == &X86::GR32_NOSPRegClass) { if (A->getSize() == 8) return A; From stoklund at 2pi.dk Tue May 25 12:04:18 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 25 May 2010 17:04:18 -0000 Subject: [llvm-commits] [llvm] r104612 - /llvm/trunk/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp Message-ID: <20100525170418.F1EE13128026@llvm.org> Author: stoklund Date: Tue May 25 12:04:18 2010 New Revision: 104612 URL: http://llvm.org/viewvc/llvm-project?rev=104612&view=rev Log: Use enums instead of literals for SystemZ subregisters Modified: llvm/trunk/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp Modified: llvm/trunk/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp?rev=104612&r1=104611&r2=104612&view=diff ============================================================================== --- llvm/trunk/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp Tue May 25 12:04:18 2010 @@ -30,11 +30,6 @@ #include "llvm/Support/raw_ostream.h" using namespace llvm; -static const unsigned subreg_even32 = 1; -static const unsigned subreg_odd32 = 2; -static const unsigned subreg_even = 3; -static const unsigned subreg_odd = 4; - namespace { /// SystemZRRIAddressMode - This corresponds to rriaddr, but uses SDValue's /// instead of register numbers for the leaves of the matched tree. @@ -644,7 +639,7 @@ Dividend = CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG, dl, ResVT, SDValue(Tmp, 0), SDValue(Dividend, 0), - CurDAG->getTargetConstant(subreg_odd, MVT::i32)); + CurDAG->getTargetConstant(SystemZ::subreg_odd, MVT::i32)); SDNode *Result; SDValue DivVal = SDValue(Dividend, 0); @@ -660,7 +655,8 @@ // Copy the division (odd subreg) result, if it is needed. if (!SDValue(Node, 0).use_empty()) { - unsigned SubRegIdx = (is32Bit ? subreg_odd32 : subreg_odd); + unsigned SubRegIdx = (is32Bit ? + SystemZ::subreg_odd32 : SystemZ::subreg_odd); SDNode *Div = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, NVT, SDValue(Result, 0), @@ -673,7 +669,8 @@ // Copy the remainder (even subreg) result, if it is needed. if (!SDValue(Node, 1).use_empty()) { - unsigned SubRegIdx = (is32Bit ? subreg_even32 : subreg_even); + unsigned SubRegIdx = (is32Bit ? + SystemZ::subreg_even32 : SystemZ::subreg_even); SDNode *Rem = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, NVT, SDValue(Result, 0), @@ -718,7 +715,8 @@ SDNode *Tmp = CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, ResVT); { - unsigned SubRegIdx = (is32Bit ? subreg_odd32 : subreg_odd); + unsigned SubRegIdx = (is32Bit ? + SystemZ::subreg_odd32 : SystemZ::subreg_odd); Dividend = CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG, dl, ResVT, SDValue(Tmp, 0), SDValue(Dividend, 0), @@ -742,7 +740,8 @@ // Copy the division (odd subreg) result, if it is needed. if (!SDValue(Node, 0).use_empty()) { - unsigned SubRegIdx = (is32Bit ? subreg_odd32 : subreg_odd); + unsigned SubRegIdx = (is32Bit ? + SystemZ::subreg_odd32 : SystemZ::subreg_odd); SDNode *Div = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, NVT, SDValue(Result, 0), @@ -754,7 +753,8 @@ // Copy the remainder (even subreg) result, if it is needed. if (!SDValue(Node, 1).use_empty()) { - unsigned SubRegIdx = (is32Bit ? subreg_even32 : subreg_even); + unsigned SubRegIdx = (is32Bit ? + SystemZ::subreg_even32 : SystemZ::subreg_even); SDNode *Rem = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, NVT, SDValue(Result, 0), From stoklund at 2pi.dk Tue May 25 12:21:05 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 25 May 2010 17:21:05 -0000 Subject: [llvm-commits] [llvm] r104615 - in /llvm/trunk: lib/Target/X86/X86RegisterInfo.cpp utils/TableGen/CodeGenTarget.h utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <20100525172105.2EB00312800A@llvm.org> Author: stoklund Date: Tue May 25 12:21:04 2010 New Revision: 104615 URL: http://llvm.org/viewvc/llvm-project?rev=104615&view=rev Log: Ignore NumberHack and give each SubRegIndex instance a unique enum value instead. This passes lit tests, but I'll give it a go through the buildbots to smoke out any remaining places that depend on the old SubRegIndex numbering. Then I'll remove NumberHack entirely. Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp llvm/trunk/utils/TableGen/CodeGenTarget.h llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp?rev=104615&r1=104614&r2=104615&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Tue May 25 12:21:04 2010 @@ -158,7 +158,7 @@ switch (SubIdx) { default: return 0; case X86::sub_8bit: - //case X86::sub_ss: + case X86::sub_ss: if (B == &X86::GR8RegClass) { if (A->getSize() == 2 || A->getSize() == 4 || A->getSize() == 8) return A; @@ -195,7 +195,7 @@ } break; case X86::sub_8bit_hi: - //case X86::sub_sd: + case X86::sub_sd: if (B == &X86::GR8_ABCD_HRegClass) { if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass || A == &X86::GR64_NOREXRegClass || @@ -213,7 +213,7 @@ } break; case X86::sub_16bit: - //case X86::sub_xmm: + case X86::sub_xmm: if (B == &X86::GR16RegClass) { if (A->getSize() == 4 || A->getSize() == 8) return A; Modified: llvm/trunk/utils/TableGen/CodeGenTarget.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenTarget.h?rev=104615&r1=104614&r2=104615&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenTarget.h (original) +++ llvm/trunk/utils/TableGen/CodeGenTarget.h Tue May 25 12:21:04 2010 @@ -107,7 +107,11 @@ // Map a SubRegIndex Record to its number. unsigned getSubRegIndexNo(Record *idx) const { - return idx->getValueAsInt("NumberHack"); + if (SubRegIndices.empty()) ReadSubRegIndices(); + std::vector::const_iterator i = + std::find(SubRegIndices.begin(), SubRegIndices.end(), idx); + assert(i != SubRegIndices.end() && "Not a SubRegIndex"); + return (i - SubRegIndices.begin()) + 1; } const std::vector &getRegisterClasses() const { Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp?rev=104615&r1=104614&r2=104615&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Tue May 25 12:21:04 2010 @@ -52,8 +52,7 @@ OS << "namespace " << Namespace << " {\n"; OS << "enum {\n NoSubRegister,\n"; for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) - OS << " " << SubRegIndices[i]->getName() << " = " - << SubRegIndices[i]->getValueAsInt("NumberHack") << ",\n"; + OS << " " << SubRegIndices[i]->getName() << ",\t// " << i+1 << "\n"; OS << " NUM_TARGET_SUBREGS = " << SubRegIndices.size()+1 << "\n"; OS << "};\n"; if (!Namespace.empty()) From echristo at apple.com Tue May 25 12:33:22 2010 From: echristo at apple.com (Eric Christopher) Date: Tue, 25 May 2010 17:33:22 -0000 Subject: [llvm-commits] [llvm] r104617 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86InstrSSE.td test/MC/AsmParser/X86/x86_32-encoding.s Message-ID: <20100525173322.6FC43312800A@llvm.org> Author: echristo Date: Tue May 25 12:33:22 2010 New Revision: 104617 URL: http://llvm.org/viewvc/llvm-project?rev=104617&view=rev Log: Make sure aeskeygenassist uses an unsigned immediate field. Fixes rdar://8017638 Modified: llvm/trunk/include/llvm/IntrinsicsX86.td llvm/trunk/lib/Target/X86/X86InstrSSE.td llvm/trunk/test/MC/AsmParser/X86/x86_32-encoding.s Modified: llvm/trunk/include/llvm/IntrinsicsX86.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IntrinsicsX86.td?rev=104617&r1=104616&r2=104617&view=diff ============================================================================== --- llvm/trunk/include/llvm/IntrinsicsX86.td (original) +++ llvm/trunk/include/llvm/IntrinsicsX86.td Tue May 25 12:33:22 2010 @@ -786,9 +786,9 @@ def int_x86_aesni_aesdeclast : GCCBuiltin<"__builtin_ia32_aesdeclast128">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; - def int_x86_aesni_aeskeygenassist : + def int_x86_aesni_aeskeygenassist : GCCBuiltin<"__builtin_ia32_aeskeygenassist128">, - Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i8_ty], [IntrNoMem]>; } Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=104617&r1=104616&r2=104617&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Tue May 25 12:33:22 2010 @@ -117,17 +117,17 @@ return cast(N)->getAlignment() >= 16; }]>; -def alignedloadfsf32 : PatFrag<(ops node:$ptr), +def alignedloadfsf32 : PatFrag<(ops node:$ptr), (f32 (alignedload node:$ptr))>; -def alignedloadfsf64 : PatFrag<(ops node:$ptr), +def alignedloadfsf64 : PatFrag<(ops node:$ptr), (f64 (alignedload node:$ptr))>; -def alignedloadv4f32 : PatFrag<(ops node:$ptr), +def alignedloadv4f32 : PatFrag<(ops node:$ptr), (v4f32 (alignedload node:$ptr))>; -def alignedloadv2f64 : PatFrag<(ops node:$ptr), +def alignedloadv2f64 : PatFrag<(ops node:$ptr), (v2f64 (alignedload node:$ptr))>; -def alignedloadv4i32 : PatFrag<(ops node:$ptr), +def alignedloadv4i32 : PatFrag<(ops node:$ptr), (v4i32 (alignedload node:$ptr))>; -def alignedloadv2i64 : PatFrag<(ops node:$ptr), +def alignedloadv2i64 : PatFrag<(ops node:$ptr), (v2i64 (alignedload node:$ptr))>; // Like 'load', but uses special alignment checks suitable for use in @@ -518,25 +518,25 @@ def UCOMISSrm: PSI<0x2E, MRMSrcMem, (outs), (ins FR32:$src1, f32mem:$src2), "ucomiss\t{$src2, $src1|$src1, $src2}", [(set EFLAGS, (X86cmp FR32:$src1, (loadf32 addr:$src2)))]>; - + def COMISSrr: PSI<0x2F, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2), "comiss\t{$src2, $src1|$src1, $src2}", []>; def COMISSrm: PSI<0x2F, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2), "comiss\t{$src2, $src1|$src1, $src2}", []>; - + } // Defs = [EFLAGS] // Aliases to match intrinsics which expect XMM operand(s). let Constraints = "$src1 = $dst" in { def Int_CMPSSrr : SSIi8<0xC2, MRMSrcReg, - (outs VR128:$dst), + (outs VR128:$dst), (ins VR128:$src1, VR128:$src, SSECC:$cc), "cmp${cc}ss\t{$src, $dst|$dst, $src}", - [(set VR128:$dst, (int_x86_sse_cmp_ss + [(set VR128:$dst, (int_x86_sse_cmp_ss VR128:$src1, VR128:$src, imm:$cc))]>; def Int_CMPSSrm : SSIi8<0xC2, MRMSrcMem, - (outs VR128:$dst), + (outs VR128:$dst), (ins VR128:$src1, f32mem:$src, SSECC:$cc), "cmp${cc}ss\t{$src, $dst|$dst, $src}", [(set VR128:$dst, (int_x86_sse_cmp_ss VR128:$src1, @@ -1312,13 +1312,13 @@ // Aliases to match intrinsics which expect XMM operand(s). let Constraints = "$src1 = $dst" in { def Int_CMPSDrr : SDIi8<0xC2, MRMSrcReg, - (outs VR128:$dst), + (outs VR128:$dst), (ins VR128:$src1, VR128:$src, SSECC:$cc), "cmp${cc}sd\t{$src, $dst|$dst, $src}", [(set VR128:$dst, (int_x86_sse2_cmp_sd VR128:$src1, VR128:$src, imm:$cc))]>; def Int_CMPSDrm : SDIi8<0xC2, MRMSrcMem, - (outs VR128:$dst), + (outs VR128:$dst), (ins VR128:$src1, f64mem:$src, SSECC:$cc), "cmp${cc}sd\t{$src, $dst|$dst, $src}", [(set VR128:$dst, (int_x86_sse2_cmp_sd VR128:$src1, @@ -1656,7 +1656,7 @@ def Int_CVTTPS2DQrr : I<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), "cvttps2dq\t{$src, $dst|$dst, $src}", - [(set VR128:$dst, + [(set VR128:$dst, (int_x86_sse2_cvttps2dq VR128:$src))]>, XS, Requires<[HasSSE2]>; def Int_CVTTPS2DQrm : I<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src), @@ -1981,24 +1981,24 @@ multiclass PDI_binop_rm_int opc, string OpcodeStr, Intrinsic IntId, bit Commutable = 0> { - def rr : PDI { let isCommutable = Commutable; } - def rm : PDI; } multiclass PDI_binop_rmi_int opc, bits<8> opc2, Format ImmForm, string OpcodeStr, Intrinsic IntId, Intrinsic IntId2> { - def rr : PDI; @@ -2007,7 +2007,7 @@ !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"), [(set VR128:$dst, (IntId VR128:$src1, (bitconvert (memopv2i64 addr:$src2))))]>; - def ri : PDIi8; @@ -2016,13 +2016,13 @@ /// PDI_binop_rm - Simple SSE2 binary operator. multiclass PDI_binop_rm opc, string OpcodeStr, SDNode OpNode, ValueType OpVT, bit Commutable = 0> { - def rr : PDI { let isCommutable = Commutable; } - def rm : PDI; - + defm PSHUFB : SS3I_binop_rm_int_8 <0x00, "pshufb", int_x86_ssse3_pshuf_b, int_x86_ssse3_pshuf_b_128>; @@ -3469,14 +3469,14 @@ let Constraints = "$src1 = $dst" in { multiclass SS48I_binop_rm opc, string OpcodeStr, SDNode OpNode, ValueType OpVT, bit Commutable = 0> { - def rr : SS48I, OpSize { let isCommutable = Commutable; } - def rm : SS48I, OpSize; def PCMPESTRM128MEM : SS42AI<0, Pseudo, (outs VR128:$dst), (ins VR128:$src1, i128mem:$src3, i8imm:$src5), "#PCMPESTRM128rm PSEUDO!", - [(set VR128:$dst, (int_x86_sse42_pcmpestrm128 - VR128:$src1, EAX, (load addr:$src3), EDX, imm:$src5))]>, + [(set VR128:$dst, (int_x86_sse42_pcmpestrm128 + VR128:$src1, EAX, (load addr:$src3), EDX, imm:$src5))]>, OpSize; } @@ -3977,7 +3977,7 @@ let Defs = [ECX, EFLAGS] in { multiclass SS42AI_pcmpistri { - def rr : SS42AI<0x63, MRMSrcReg, (outs), + def rr : SS42AI<0x63, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2, i8imm:$src3), "pcmpistri\t{$src3, $src2, $src1|$src1, $src2, $src3}", [(set ECX, (IntId128 VR128:$src1, VR128:$src2, imm:$src3)), @@ -4008,7 +4008,7 @@ def rm : SS42AI<0x61, MRMSrcMem, (outs), (ins VR128:$src1, i128mem:$src3, i8imm:$src5), "pcmpestri\t{$src5, $src3, $src1|$src1, $src3, $src5}", - [(set ECX, + [(set ECX, (IntId128 VR128:$src1, EAX, (load addr:$src3), EDX, imm:$src5)), (implicit EFLAGS)]>, OpSize; } @@ -4086,16 +4086,15 @@ OpSize; def AESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst), - (ins VR128:$src1, i32i8imm:$src2), + (ins VR128:$src1, i8imm:$src2), "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}", [(set VR128:$dst, (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>, OpSize; def AESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst), - (ins i128mem:$src1, i32i8imm:$src2), + (ins i128mem:$src1, i8imm:$src2), "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}", [(set VR128:$dst, (int_x86_aesni_aeskeygenassist (bitconvert (memopv2i64 addr:$src1)), imm:$src2))]>, OpSize; - Modified: llvm/trunk/test/MC/AsmParser/X86/x86_32-encoding.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/X86/x86_32-encoding.s?rev=104617&r1=104616&r2=104617&view=diff ============================================================================== --- llvm/trunk/test/MC/AsmParser/X86/x86_32-encoding.s (original) +++ llvm/trunk/test/MC/AsmParser/X86/x86_32-encoding.s Tue May 25 12:33:22 2010 @@ -9962,11 +9962,16 @@ // CHECK: encoding: [0x66,0x0f,0x3a,0xdf,0x14,0x82,0x7d] aeskeygenassist $125, (%edx,%eax,4), %xmm2 +// rdar://8017638 +// CHECK: aeskeygenassist $128, %xmm1, %xmm2 +// CHECK: encoding: [0x66,0x0f,0x3a,0xdf,0x14,0x82,0x80] + aeskeygenassist $128, %xmm1, %xmm2 + // rdar://7840289 // CHECK: pshufb CPI1_0(%rip), %xmm1 // CHECK: encoding: [0x66,0x0f,0x38,0x00,0x0d,A,A,A,A] // CHECK: fixup A - offset: 5, value: CPI1_0-4 -pshufb CPI1_0(%rip), %xmm1 +pshufb CPI1_0(%rip), %xmm1 // rdar://7910087 // CHECK: bsfw %bx, %bx @@ -10018,7 +10023,7 @@ // radr://7914715 // CHECK: fcoml 3735928559(%ebx,%ecx,8) // CHECK: encoding: [0xdc,0x94,0xcb,0xef,0xbe,0xad,0xde] - fcoml 3735928559(%ebx,%ecx,8) + fcoml 3735928559(%ebx,%ecx,8) // CHECK: fcoms 32493 // CHECK: encoding: [0xd8,0x15,0xed,0x7e,0x00,0x00] From echristo at apple.com Tue May 25 12:36:20 2010 From: echristo at apple.com (Eric Christopher) Date: Tue, 25 May 2010 10:36:20 -0700 Subject: [llvm-commits] [llvm] r104617 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86InstrSSE.td test/MC/AsmParser/X86/x86_32-encoding.s In-Reply-To: <20100525173322.6FC43312800A@llvm.org> References: <20100525173322.6FC43312800A@llvm.org> Message-ID: On May 25, 2010, at 10:33 AM, Eric Christopher wrote: > > URL: http://llvm.org/viewvc/llvm-project?rev=104617&view=rev > Log: > Make sure aeskeygenassist uses an unsigned immediate field. And yes, I forgot to turn off my trailing whitespace eradicator. My apologies. -eric From dalej at apple.com Tue May 25 12:50:04 2010 From: dalej at apple.com (Dale Johannesen) Date: Tue, 25 May 2010 17:50:04 -0000 Subject: [llvm-commits] [llvm] r104619 - /llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <20100525175004.1F4FE312800A@llvm.org> Author: johannes Date: Tue May 25 12:50:03 2010 New Revision: 104619 URL: http://llvm.org/viewvc/llvm-project?rev=104619&view=rev Log: Fix PR 7191. I have been unable to create a .ll file that fails, sorry. (oye, a word which should be better known to people writing tree traversals, means grandchild.) Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=104619&r1=104618&r2=104619&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue May 25 12:50:03 2010 @@ -3431,8 +3431,12 @@ // fold (sext (truncate (srl (load x), c))) -> (sext (smaller load (x+c/n))) SDValue NarrowLoad = ReduceLoadWidth(N0.getNode()); if (NarrowLoad.getNode()) { - if (NarrowLoad.getNode() != N0.getNode()) + SDNode* oye = N0.getNode()->getOperand(0).getNode(); + if (NarrowLoad.getNode() != N0.getNode()) { CombineTo(N0.getNode(), NarrowLoad); + // CombineTo deleted the truncate, if needed, but not what's under it. + AddToWorkList(oye); + } return SDValue(N, 0); // Return N so it doesn't get rechecked! } @@ -3619,8 +3623,12 @@ if (N0.getOpcode() == ISD::TRUNCATE) { SDValue NarrowLoad = ReduceLoadWidth(N0.getNode()); if (NarrowLoad.getNode()) { - if (NarrowLoad.getNode() != N0.getNode()) + SDNode* oye = N0.getNode()->getOperand(0).getNode(); + if (NarrowLoad.getNode() != N0.getNode()) { CombineTo(N0.getNode(), NarrowLoad); + // CombineTo deleted the truncate, if needed, but not what's under it. + AddToWorkList(oye); + } return DAG.getNode(ISD::ZERO_EXTEND, N->getDebugLoc(), VT, NarrowLoad); } } From enderby at apple.com Tue May 25 13:16:58 2010 From: enderby at apple.com (Kevin Enderby) Date: Tue, 25 May 2010 18:16:58 -0000 Subject: [llvm-commits] [llvm] r104621 - in /llvm/trunk: lib/Target/X86/X86Instr64bit.td test/MC/AsmParser/X86/x86_64-new-encoder.s Message-ID: <20100525181658.B0DE5312800A@llvm.org> Author: enderby Date: Tue May 25 13:16:58 2010 New Revision: 104621 URL: http://llvm.org/viewvc/llvm-project?rev=104621&view=rev Log: The BT64ri8 record in X86Instr64bit.td was missing a REX_W which is required for the 64-bit version of the Bit Test instruction. Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td llvm/trunk/test/MC/AsmParser/X86/x86_64-new-encoder.s Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Instr64bit.td?rev=104621&r1=104620&r2=104621&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Instr64bit.td (original) +++ llvm/trunk/lib/Target/X86/X86Instr64bit.td Tue May 25 13:16:58 2010 @@ -1313,7 +1313,8 @@ def BT64ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64i8imm:$src2), "bt{q}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86bt GR64:$src1, i64immSExt8:$src2))]>, TB; + [(set EFLAGS, (X86bt GR64:$src1, i64immSExt8:$src2))]>, TB, + REX_W; // Note that these instructions don't need FastBTMem because that // only applies when the other operand is in a register. When it's // an immediate, bt is still fast. Modified: llvm/trunk/test/MC/AsmParser/X86/x86_64-new-encoder.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/X86/x86_64-new-encoder.s?rev=104621&r1=104620&r2=104621&view=diff ============================================================================== --- llvm/trunk/test/MC/AsmParser/X86/x86_64-new-encoder.s (original) +++ llvm/trunk/test/MC/AsmParser/X86/x86_64-new-encoder.s Tue May 25 13:16:58 2010 @@ -126,3 +126,8 @@ // CHECK: jne // CHECK: encoding: [0x75,A] jnz 0 + +// rdar://8017515 +btq $0x01,%rdx +// CHECK: btq $1, %rdx +// CHECK: encoding: [0x48,0x0f,0xba,0xe2,0x01] From daniel at zuster.org Tue May 25 13:40:54 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 25 May 2010 18:40:54 -0000 Subject: [llvm-commits] [llvm] r104622 - in /llvm/trunk: lib/Target/X86/X86InstrSSE.td test/MC/AsmParser/X86/x86_32-new-encoder.s Message-ID: <20100525184054.2F140312800A@llvm.org> Author: ddunbar Date: Tue May 25 13:40:53 2010 New Revision: 104622 URL: http://llvm.org/viewvc/llvm-project?rev=104622&view=rev Log: MC/X86: Define explicit immediate forms of cmp{ss,sd,ps,pd}. Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=104622&r1=104621&r2=104622&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Tue May 25 13:40:53 2010 @@ -509,6 +509,17 @@ def CMPSSrm : SSIi8<0xC2, MRMSrcMem, (outs FR32:$dst), (ins FR32:$src1, f32mem:$src, SSECC:$cc), "cmp${cc}ss\t{$src, $dst|$dst, $src}", []>; + + // Accept explicit immediate argument form instead of comparison code. +let isAsmParserOnly = 1 in { + def CMPSSrr_alt : SSIi8<0xC2, MRMSrcReg, + (outs FR32:$dst), (ins FR32:$src1, FR32:$src, i8imm:$src2), + "cmpss\t{$src2, $src, $dst|$dst, $src, $src2}", []>; +let mayLoad = 1 in + def CMPSSrm_alt : SSIi8<0xC2, MRMSrcMem, + (outs FR32:$dst), (ins FR32:$src1, f32mem:$src, i8imm:$src2), + "cmpss\t{$src2, $src, $dst|$dst, $src, $src2}", []>; +} } let Defs = [EFLAGS] in { @@ -1009,6 +1020,16 @@ "cmp${cc}ps\t{$src, $dst|$dst, $src}", [(set VR128:$dst, (int_x86_sse_cmp_ps VR128:$src1, (memop addr:$src), imm:$cc))]>; + + // Accept explicit immediate argument form instead of comparison code. +let isAsmParserOnly = 1 in { + def CMPPSrri_alt : PSIi8<0xC2, MRMSrcReg, + (outs VR128:$dst), (ins VR128:$src1, VR128:$src, i8imm:$src2), + "cmpps\t{$src2, $src, $dst|$dst, $src, $src}", []>; + def CMPPSrmi_alt : PSIi8<0xC2, MRMSrcMem, + (outs VR128:$dst), (ins VR128:$src1, f128mem:$src, i8imm:$src2), + "cmpps\t{$src2, $src, $dst|$dst, $src, $src}", []>; +} } def : Pat<(v4i32 (X86cmpps (v4f32 VR128:$src1), VR128:$src2, imm:$cc)), (CMPPSrri (v4f32 VR128:$src1), (v4f32 VR128:$src2), imm:$cc)>; @@ -1298,6 +1319,17 @@ def CMPSDrm : SDIi8<0xC2, MRMSrcMem, (outs FR64:$dst), (ins FR64:$src1, f64mem:$src, SSECC:$cc), "cmp${cc}sd\t{$src, $dst|$dst, $src}", []>; + + // Accept explicit immediate argument form instead of comparison code. +let isAsmParserOnly = 1 in { + def CMPSDrr_alt : SDIi8<0xC2, MRMSrcReg, + (outs FR64:$dst), (ins FR64:$src1, FR64:$src, i8imm:$src2), + "cmpsd\t{$src2, $src, $dst|$dst, $src, $src2}", []>; +let mayLoad = 1 in + def CMPSDrm_alt : SDIi8<0xC2, MRMSrcMem, + (outs FR64:$dst), (ins FR64:$src1, f64mem:$src, i8imm:$src2), + "cmpsd\t{$src2, $src, $dst|$dst, $src, $src2}", []>; +} } let Defs = [EFLAGS] in { @@ -1891,6 +1923,16 @@ "cmp${cc}pd\t{$src, $dst|$dst, $src}", [(set VR128:$dst, (int_x86_sse2_cmp_pd VR128:$src1, (memop addr:$src), imm:$cc))]>; + + // Accept explicit immediate argument form instead of comparison code. +let isAsmParserOnly = 1 in { + def CMPPDrri_alt : PDIi8<0xC2, MRMSrcReg, + (outs VR128:$dst), (ins VR128:$src1, VR128:$src, i8imm:$src2), + "cmppd\t{$src2, $src, $dst|$dst, $src, $src2}", []>; + def CMPPDrmi_alt : PDIi8<0xC2, MRMSrcMem, + (outs VR128:$dst), (ins VR128:$src1, f128mem:$src, i8imm:$src2), + "cmppd\t{$src2, $src, $dst|$dst, $src, $src2}", []>; +} } def : Pat<(v2i64 (X86cmppd (v2f64 VR128:$src1), VR128:$src2, imm:$cc)), (CMPPDrri VR128:$src1, VR128:$src2, imm:$cc)>; Modified: llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s?rev=104622&r1=104621&r2=104622&view=diff ============================================================================== --- llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s (original) +++ llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s Tue May 25 13:40:53 2010 @@ -218,3 +218,28 @@ // CHECK: cmovel %eax, %edx // CHECK: encoding: [0x0f,0x44,0xd0] cmovzl %eax,%edx + +// CHECK: cmpps $0, %xmm0, %xmm1 +// CHECK: encoding: [0x0f,0xc2,0xc8,0x00] + cmpps $0, %xmm0, %xmm1 +// CHECK: cmpps $0, (%eax), %xmm1 +// CHECK: encoding: [0x0f,0xc2,0x08,0x00] + cmpps $0, 0(%eax), %xmm1 +// CHECK: cmppd $0, %xmm0, %xmm1 +// CHECK: encoding: [0x66,0x0f,0xc2,0xc8,0x00] + cmppd $0, %xmm0, %xmm1 +// CHECK: cmppd $0, (%eax), %xmm1 +// CHECK: encoding: [0x66,0x0f,0xc2,0x08,0x00] + cmppd $0, 0(%eax), %xmm1 +// CHECK: cmpss $0, %xmm0, %xmm1 +// CHECK: encoding: [0xf3,0x0f,0xc2,0xc8,0x00] + cmpss $0, %xmm0, %xmm1 +// CHECK: cmpss $0, (%eax), %xmm1 +// CHECK: encoding: [0xf3,0x0f,0xc2,0x08,0x00] + cmpss $0, 0(%eax), %xmm1 +// CHECK: cmpsd $0, %xmm0, %xmm1 +// CHECK: encoding: [0xf2,0x0f,0xc2,0xc8,0x00] + cmpsd $0, %xmm0, %xmm1 +// CHECK: cmpsd $0, (%eax), %xmm1 +// CHECK: encoding: [0xf2,0x0f,0xc2,0x08,0x00] + cmpsd $0, 0(%eax), %xmm1 From dalej at apple.com Tue May 25 13:47:23 2010 From: dalej at apple.com (Dale Johannesen) Date: Tue, 25 May 2010 18:47:23 -0000 Subject: [llvm-commits] [llvm] r104624 - in /llvm/trunk: lib/CodeGen/SelectionDAG/DAGCombiner.cpp test/CodeGen/X86/2010-05-25-FP_TO_INT-crash.ll Message-ID: <20100525184723.847DE312800A@llvm.org> Author: johannes Date: Tue May 25 13:47:23 2010 New Revision: 104624 URL: http://llvm.org/viewvc/llvm-project?rev=104624&view=rev Log: Fix another variant of PR 7191. Also add a testcase Mon Ping provided; unfortunately bugpoint failed to reduce it, but I think it's important to have a test for this in the suite. 8023512. Added: llvm/trunk/test/CodeGen/X86/2010-05-25-FP_TO_INT-crash.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=104624&r1=104623&r2=104624&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue May 25 13:47:23 2010 @@ -3832,8 +3832,12 @@ if (N0.getOpcode() == ISD::TRUNCATE) { SDValue NarrowLoad = ReduceLoadWidth(N0.getNode()); if (NarrowLoad.getNode()) { - if (NarrowLoad.getNode() != N0.getNode()) + SDNode* oye = N0.getNode()->getOperand(0).getNode(); + if (NarrowLoad.getNode() != N0.getNode()) { CombineTo(N0.getNode(), NarrowLoad); + // CombineTo deleted the truncate, if needed, but not what's under it. + AddToWorkList(oye); + } return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), VT, NarrowLoad); } } Added: llvm/trunk/test/CodeGen/X86/2010-05-25-FP_TO_INT-crash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2010-05-25-FP_TO_INT-crash.ll?rev=104624&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2010-05-25-FP_TO_INT-crash.ll (added) +++ llvm/trunk/test/CodeGen/X86/2010-05-25-FP_TO_INT-crash.ll Tue May 25 13:47:23 2010 @@ -0,0 +1,2718 @@ +; RUN: llc -O0 -march=x86 -mattr=+sse3 %s +; Formerly crashed - PR 7191 / 8023512 +; ModuleID = '' +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32" +target triple = "i386-apple-darwin11.0" + +%0 = type { i16, i16, i32 } +%1 = type { i32, i32, i16, i16, i16, i16 } +%2 = type { i16, i16, %struct.GLTColor4, %struct.GLTColor4 } +%3 = type { void (i8*, i8*, i32, i8*)*, i32 (i8*, ...)*, i8* (%struct.GLDContextRec*, %struct.GLDFramebufferRec*, i8, i32, i32)* } +%struct.GLDActiveTextureTargets = type { i64, i64, i64, i64, i64, i64 } +%struct.GLDAlphaTest = type { float, i16, i8, i8 } +%struct.GLDArrayRange = type { i8, i8, i8, i8 } +%struct.GLDBlendMode = type { i16, i16, i16, i16, %struct.GLTColor4, i16, i16, i8, i8, i8, i8 } +%struct.GLDBufferData = type { i8*, i32, i32, i16, i16, i8, i8, i8, i8 } +%struct.GLDBufferRec = type { %struct.GLDBufferData*, %struct.GLDPluginBufferData* } +%struct.GLDBufferstate = type { %struct.GLTDimensions, %struct.GLTDimensions, %struct.GLTFixedColor4, %struct.GLTFixedColor4, i8, i8, i8, i8, [0 x i32], %union.GLSBuffer, %union.GLSBuffer, %union.GLSBuffer, [8 x %union.GLSBuffer], %union.GLSBuffer } +%struct.GLDClearColor = type { double, %struct.GLTColor4, %struct.GLTColor4, float, i32 } +%struct.GLDClipPlane = type { i32, [6 x %struct.GLTColor4] } +%struct.GLDColorBuffer = type { i16, i8, i8, [8 x i16], i8, i8, i8, i8 } +%struct.GLDColorMatrix = type { [16 x float]*, %struct.GLDImagingColorScale } +%struct.GLDConfig = type { i32, float, %struct.GLTDimensions, %struct.GLTDimensions, i8, i8, i8, i8, i8, i8, i16, i32, i32, i32, %struct.GLDPixelFormatInfo, %struct.GLDPointLineLimits, %struct.GLDPointLineLimits, %struct.GLDRenderFeatures, i32, i32, i32, i32, i32, i32, i32, i32, %struct.GLDMultisamplePositions, %struct.GLDTextureLimits, [3 x %struct.GLDPipelineProgramLimits], %struct.GLDFragmentProgramLimits, %struct.GLDVertexProgramLimits, %struct.GLDGeometryShaderLimits, %struct.GLDGeometryShaderLimits, %struct.GLDTransformFeedbackLimits, i16, i8, i8, %struct.GLDVertexDescriptor*, %struct.GLDVertexDescriptor*, [4 x i32], [8 x i32], %struct.GLDMultisamplePositions* } +%struct.GLDContextRec = type { float, float, float, float, float, float, float, float, %struct.GLTColor4, %struct.GLTColor4, %struct.GLVMFPContext, [16 x [2 x %union.PPStreamToken]], %struct.GLGProcessor, %struct._GLVMConstants*, void (%struct.GLDContextRec*, i32, i32, %struct.GLVMFragmentAttribRec*, %struct.GLVMFragmentAttribRec*, i32)*, %struct._GLVMFunction*, %union.PPStreamToken*, void (%struct.GLDContextRec*, %struct.GLDVertex*)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, %struct.GLDVertex*)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, %struct.GLDVertex*, %struct.GLDVertex*)*, %struct._GLVMFunction*, %struct._GLVMFunction*, %struct._GLVMFunction*, [4 x i32], [3 x i32], [3 x i32], %union.PPStreamToken, %struct.GLDConfig*, %struct.GLDFramebufferRec*, %struct.GLDFramebufferRec*, %struct.GLDBufferstate, %struct.GLDReadBufferstate, %struct.GLDLayeredBufferstate, [64 x %struct.GLTColor4*], %struct.GLDSharedRec*, %struct.GLDState*, %struct.GLDPluginState*, %stru ct.GLDVertex*, %struct.GLVMFragmentAttribRec*, %struct.GLVMFragmentAttribRec*, %struct.GLVMFragmentAttribRec*, %struct.GLDProgramRec*, %struct.GLDPipelineProgramRec*, %struct.GLVMTextures, %struct.GLDQueryRec*, %struct.GLDQueryRec*, %struct.GLDQueryRec*, %struct.GLTDimensions, i64 ()*, %struct.GLDFallback, %3, %union.GLSDrawable, i32, float, float, %struct.GLDRect, %struct.GLDFormat, %struct.GLDFormat, %struct.GLDFormat, %struct.GLDStippleData, i32, i32, i32, i32, i16, i8, i8, i8, i8, [2 x i8], [0 x i32] } +%struct.GLDConvolution = type { %struct.GLTColor4, %struct.GLDImagingColorScale, i16, i16, [0 x i32], float*, i32, i32 } +%struct.GLDCurrent = type { [8 x %struct.GLTColor4], [16 x %struct.GLTColor4], %struct.GLTColor4, %struct.GLDPointLineLimits, float, %struct.GLDPointLineLimits, float, [4 x float], float, float, float, i8, i8, i8, i8, i32, i32, i32, i32 } +%struct.GLDDepthTest = type { i16, i16, i8, i8, i8, i8, double, double } +%struct.GLDDitherMode = type { i8, i8, i8, i8 } +%struct.GLDDrawableOffscreen = type { i32, i32, i32, [0 x i32], i8* } +%struct.GLDDrawableWindow = type { i32, i32, i32 } +%struct.GLDFallback = type { float*, %struct.GLDRenderDispatch*, %struct.GLDConfig*, i8*, i8*, i32, i32 } +%struct.GLDFixedFunction = type { %union.PPStreamToken* } +%struct.GLDFogMode = type { %struct.GLTColor4, float, float, float, float, float, i16, i16, i16, i8, i8 } +%struct.GLDFormat = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i8, i8, i8, i8, i32, i32, i32 } +%struct.GLDFragmentProgramLimits = type { i32, i32, i32, i16, i16, i32, i16, i16, i16, i16 } +%struct.GLDFramebufferAttachment = type { i16, i16, i32, i32, i32 } +%struct.GLDFramebufferData = type { [10 x %struct.GLDFramebufferAttachment], [8 x i16], i16, i16, i16, i8, i8, i32, i32, i32 } +%struct.GLDFramebufferRec = type { %struct.GLDFramebufferData*, %struct.GLDPluginFramebufferData*, [10 x %struct.GLDFormat], i8, i8, i16, [0 x i32] } +%struct.GLDGeometryShaderLimits = type { i32, i32, i32, i32, i32, i16, i16 } +%struct.GLDHintMode = type { i16, i16, i16, i16, i16, i16, i16, i16, i16, i16 } +%struct.GLDHistogram = type { %struct.GLTFixedColor4*, i32, i16, i8, i8 } +%struct.GLDImagingColorScale = type { %struct.GLDMultisamplePositions, %struct.GLDMultisamplePositions, %struct.GLDMultisamplePositions, %struct.GLDMultisamplePositions } +%struct.GLDImagingSubset = type { %struct.GLDConvolution, %struct.GLDConvolution, %struct.GLDConvolution, %struct.GLDColorMatrix, %struct.GLDMinmax, %struct.GLDHistogram, %struct.GLDImagingColorScale, %struct.GLDImagingColorScale, %struct.GLDImagingColorScale, %struct.GLDImagingColorScale, i32, [0 x i32] } +%struct.GLDLayeredBufferstate = type { %union.GLSBuffer, %union.GLSBuffer, [8 x %union.GLSBuffer] } +%struct.GLDLight = type { %struct.GLTColor4, %struct.GLTColor4, %struct.GLTColor4, %struct.GLTColor4, %struct.GLDPointLineLimits, float, float, float, float, float, %struct.GLDPointLineLimits, float, %struct.GLDPointLineLimits, float, %struct.GLDPointLineLimits, float, float, float, float, float } +%struct.GLDLightModel = type { %struct.GLTColor4, [8 x %struct.GLDLight], [2 x %struct.GLDMaterial], i32, i16, i16, i16, i8, i8, i8, i8, i8, i8 } +%struct.GLDLightProduct = type { %struct.GLTColor4, %struct.GLTColor4, %struct.GLTColor4 } +%struct.GLDLineMode = type { float, i32, i16, i16, i8, i8, i8, i8 } +%struct.GLDLogicOp = type { i16, i8, i8 } +%struct.GLDMaskMode = type { i32, [3 x i32], i8, i8, i8, i8, i8, i8, i8, i8 } +%struct.GLDMaterial = type { %struct.GLTColor4, %struct.GLTColor4, %struct.GLTColor4, %struct.GLTColor4, float, float, float, float, [8 x %struct.GLDLightProduct], %struct.GLTColor4, [8 x i32] } +%struct.GLDMinmax = type { %struct.GLDMinmaxTable*, i16, i8, i8, [0 x i32] } +%struct.GLDMinmaxTable = type { %struct.GLTColor4, %struct.GLTColor4 } +%struct.GLDMipmaplevel = type { [4 x i32], [4 x i32], [4 x float], [4 x i32], i32, i32, float*, i8*, i16, i16, i16, i16, [2 x float] } +%struct.GLDMultisample = type { float, [1 x i32], [0 x i32], i8, i8, i8, i8, i8, i8, i8, i8 } +%struct.GLDMultisamplePositions = type { float, float } +%struct.GLDPipelineProgramData = type { i16, i8, i8, i32, %union.PPStreamToken*, i64, %struct.GLTColor4*, i32, [0 x i32] } +%struct.GLDPipelineProgramLimits = type { i32, i16, i16, i32, i16, i16, i32, i32 } +%struct.GLDPipelineProgramRec = type { %struct.GLDPipelineProgramData*, %union.PPStreamToken*, %struct.GLDContextRec*, %struct.GLVMProgramData*, i32, i32 } +%struct.GLDPipelineProgramState = type { i8, i8, i8, i8, [0 x i32], %struct.GLTColor4* } +%struct.GLDPixelFormatInfo = type { i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8 } +%struct.GLDPixelMap = type { i32*, float*, float*, float*, float*, float*, float*, float*, float*, i32*, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } +%struct.GLDPixelMode = type { float, float, %struct.GLDPixelStore, %struct.GLDPixelTransfer, %struct.GLDPixelMap, %struct.GLDImagingSubset, i32, [0 x i32] } +%struct.GLDPixelPack = type { i32, i32, i32, i32, i32, i32, i32, i32, i8, i8, i8, i8 } +%struct.GLDPixelStore = type { %struct.GLDPixelPack, %struct.GLDPixelPack } +%struct.GLDPixelTransfer = type { float, float, float, float, float, float, float, float, float, float, i32, i32 } +%struct.GLDPluginBufferData = type { i32 } +%struct.GLDPluginFramebufferData = type { [10 x %struct.GLDTextureRec*], i8, i8, i8, i8 } +%struct.GLDPluginProgramData = type { [3 x %struct.GLDPipelineProgramRec*], %struct.GLDBufferRec**, i32, [0 x i32] } +%struct.GLDPluginState = type { [16 x [11 x %struct.GLDTextureRec*]], [3 x %struct.GLDTextureRec*], [3 x %struct.GLDPipelineProgramRec*], [3 x %struct.GLDPipelineProgramRec*], %struct.GLDProgramRec*, %struct.GLDVertexArrayRec*, [16 x %struct.GLDBufferRec*], %struct.GLDFramebufferRec*, %struct.GLDFramebufferRec*, [6 x %struct.GLDQueryRec*], [64 x %struct.GLDBufferRec*] } +%struct.GLDPluginTextureState = type { %struct.GLDBufferRec*, [6 x i16], i8, i8, i16 } +%struct.GLDPointLineLimits = type { float, float, float } +%struct.GLDPointMode = type { float, float, float, float, %struct.GLDPointLineLimits, float, i8, i8, i8, i8, i16, i16, i32, i16, i16 } +%struct.GLDPolygonMode = type { [128 x i8], float, float, i16, i16, i16, i16, i8, i8, i8, i8, i8, i8, i8, i8 } +%struct.GLDPolygonOffset = type { float, float } +%struct.GLDPrimitiveRestart = type { i8, i8, i8, i8, i32 } +%struct.GLDProgramData = type { i32, i32, i32, i32, %union.PPStreamToken*, i32*, i32, i32, i32, i32, i8, i8, i8, i8, i32, [64 x i32] } +%struct.GLDProgramLimits = type { i32, i32, i32, i32, i32, i16, i16 } +%struct.GLDProgramRec = type { %struct.GLDProgramData*, %struct.GLDPluginProgramData*, i32, [0 x i32] } +%struct.GLDProgramState = type { i8, i8, i8, i8 } +%struct.GLDQueryRec = type { i64, i64, i64 } +%struct.GLDQueryState = type { i16, i16 } +%struct.GLDReadBufferstate = type { %struct.GLTDimensions, %struct.GLTDimensions, %union.GLSBuffer, %union.GLSBuffer, %union.GLSBuffer, %union.GLSBuffer } +%struct.GLDRect = type { i32, i32, i32, i32, i32, i32 } +%struct.GLDRenderDispatch = type { void (%struct.GLDContextRec*, i32, float)*, void (%struct.GLDContextRec*, i32)*, i32 (%struct.GLDContextRec*, %struct.GLDMultisamplePositions*, i32, i32, i32, i32, i8*, i32, %struct.GLDBufferRec*)*, void (%struct.GLDContextRec*, %struct.GLDMultisamplePositions*, i32, i32, i32, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, %struct.GLDVertex*, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, i32, i32)*, void (%struct.GLDContext Rec*, %struct.GLDVertex*, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex**, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex**, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex**, i32, i32)*, i8* (%struct.GLDContextRec*, i32, i32*)*, void (%struct.GLDContextRec*, i32, i32, i32)*, i8* (%struct.GLDContextRec*, i32, i32, i32, i32, i32)*, void (%struct.GLDContextRec*, i32, i32, i32, i32, i32, i8*)*, void (%struct.GLDContextRec*)*, void (%struct.GLDContextRec*)*, void (%struct.GLDContextRec*)*, i32 (%struct.GLDContextRec*, i32, i32, i32, i32, i32, i8*, %struct.GLTColor4*, i32)*, i32 (%struct.GLDContextRec*, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32)* } +%struct.GLDRenderFeatures = type { i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8 } +%struct.GLDScissorTest = type { %struct.GLTFixedColor4, i8, i8, i8, i8 } +%struct.GLDSeamlessCubemap = type { i8, i8, i16 } +%struct.GLDSharedData = type {} +%struct.GLDSharedRec = type { %struct.pthread_mutex_t, %struct.GLDSharedData*, %struct.GLGProcessor, i32, i16, i16, i8, i8, i8, i8, [0 x i32] } +%struct.GLDState = type <{ i16, i16, i16, i16, i32, i32, [256 x %struct.GLTColor4], [128 x %struct.GLTColor4], %struct.GLDCurrent, %struct.GLDViewport, %struct.GLDTransform, %struct.GLDLightModel, %struct.GLDActiveTextureTargets, %struct.GLDAlphaTest, %struct.GLDBlendMode, %struct.GLDClearColor, %struct.GLDColorBuffer, %struct.GLDDepthTest, %struct.GLDArrayRange, %struct.GLDFogMode, %struct.GLDHintMode, %struct.GLDLineMode, %struct.GLDLogicOp, %struct.GLDMaskMode, %struct.GLDPixelMode, %struct.GLDPointMode, %struct.GLDPolygonMode, %struct.GLDScissorTest, i32, %struct.GLDStencilTest, [8 x %struct.GLDTextureMode], [16 x %struct.GLDTextureImageMode], [8 x %struct.GLDTextureCoordGen], %struct.GLDClipPlane, %struct.GLDMultisample, %struct.GLDArrayRange, %struct.GLDArrayRange, [3 x %struct.GLDPipelineProgramState], %struct.GLDArrayRange, %struct.GLDTransformFeedback, %struct.GLDUniformBuffer, i32*, %struct.GLDFixedFunction, i32, %struct.GLDQueryState, %struct.GLDSeamlessCubemap, % struct.GLDPrimitiveRestart, [2 x i32] }> +%struct.GLDStencilTest = type { [3 x %1], i32, [4 x i8] } +%struct.GLDStippleData = type { i32, i16, i16, [32 x [32 x i8]] } +%struct.GLDTextureCoordGen = type { %2, %2, %2, %2, i8, i8, i8, i8 } +%struct.GLDTextureGeomState = type { i16, i16, i16, i16, i16, i8, i8, i8, i8, i16, i16, i16, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i16, [6 x i16], [6 x i16] } +%struct.GLDTextureImageMode = type { float } +%struct.GLDTextureLevel = type { i32, i32, i16, i16, i16, i8, i8, i16, i16, i16, i16, i8* } +%struct.GLDTextureLimits = type { float, float, i16, i16, i16, i16, i16, i16, i16, i16, i16, i8, i8, i8, i8, i8, i8, i32, i32 } +%struct.GLDTextureMode = type { %struct.GLTColor4, i32, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, float, float } +%struct.GLDTextureParamState = type { i16, i16, i16, i16, i16, i16, %struct.GLTColor4, float, float, float, float, i16, i16, i16, i16, float, i16, i16, i32, i8* } +%struct.GLDTextureRec = type { [4 x float], %struct.GLDTextureState*, %struct.GLDPluginTextureState*, %struct.GLDMipmaplevel*, %struct.GLDMipmaplevel*, float, float, float, float, i8, i8, i8, i8, i16, i16, i16, i16, i32, float, [0 x i32], [2 x %union.PPStreamToken] } +%struct.GLDTextureState = type { i16, i8, i8, i16, i16, float, i32, %struct.GLISWRSurface*, %struct.GLDTextureParamState, %struct.GLDTextureGeomState, i16, i16, i8*, %struct.GLDTextureLevel, [1 x [15 x %struct.GLDTextureLevel]] } +%struct.GLDTransform = type <{ [24 x [16 x float]], [24 x [16 x float]], [16 x float], float, float, float, float, float, i8, i8, i8, i8, i32, i32, i32, i16, i16, i8, i8, i8, i8, i32 }> +%struct.GLDTransformFeedback = type { i8, i8, i16, [0 x i32], [16 x i32], [16 x i32] } +%struct.GLDTransformFeedbackLimits = type { i32, i32, i32, i32, i32 } +%struct.GLDUniformBuffer = type { [64 x %struct.GLTDimensions] } +%struct.GLDVertex = type { %struct.GLTColor4, %struct.GLTColor4, %struct.GLTColor4, %struct.GLTColor4, %struct.GLTColor4, %struct.GLDPointLineLimits, float, %struct.GLTColor4, float, i8, i8, i8, i8, float, float, i32, i32, i32, [4 x i8], [4 x float], [2 x %struct.GLDMaterial*], [2 x i32], [16 x %struct.GLTColor4] } +%struct.GLDVertexArrayRec = type opaque +%struct.GLDVertexBlend = type { i8, i8, i8, i8 } +%struct.GLDVertexDescriptor = type { i8, i8, i8, i8, [0 x i32] } +%struct.GLDVertexProgramLimits = type { i16, i16, i32, i32, i16, i16 } +%struct.GLDViewport = type { float, float, float, float, float, float, float, float, float, float, float, float, float, float, float, float, double, double, i32, i32, i32, i32, float, float, float, float } +%struct.GLGColorTable = type { i32, i32, i32, i8* } +%struct.GLGOperation = type { i8*, i8*, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, float, float, %struct.GLGColorTable, %struct.GLGColorTable, %struct.GLGColorTable } +%struct.GLGProcessor = type { void (%struct.GLDPixelMode*, %struct.GLGOperation*, %struct._GLGProcessorData*, %union._GLGFunctionKey*)*, %struct._GLVMFunction*, %union._GLGFunctionKey*, %struct._GLGProcessorData* } +%struct.GLISWRSurface = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i8*, i8*, i8*, [4 x i8*], i32 } +%struct.GLSGenericRec = type { %struct.GLTDimensions, %struct.GLTDimensions, i32, i32, %union.GLSDrawable, i8*, i8*, i8*, i8*, i8*, [4 x i8*], i32, i16, i16, i16, i16, i8, i8, i8, i8, i8, i8, i8, i8 } +%struct.GLSOffScreenRec = type { %struct.GLTDimensions, %struct.GLTDimensions, i32, i32, %union.GLSDrawable, i8*, i8*, i8*, i8*, i8*, [4 x i8*], i32, i16, i16, i16, i16, i8, i8, i8, i8, i8, i8, i8, i8, %struct.GLDDrawableOffscreen } +%struct.GLSSWRSurfaceRec = type { %struct.GLTDimensions, %struct.GLTDimensions, i32, i32, %union.GLSDrawable, i8*, i8*, i8*, i8*, i8*, [4 x i8*], i32, i16, i16, i16, i16, i8, i8, i8, i8, i8, i8, i8, i8, %struct.GLISWRSurface*, i32, i32 } +%struct.GLSWindowRec = type { %struct.GLTDimensions, %struct.GLTDimensions, i32, i32, %union.GLSDrawable, i8*, i8*, i8*, i8*, i8*, [4 x i8*], i32, i16, i16, i16, i16, i8, i8, i8, i8, i8, i8, i8, i8, %struct.GLDDrawableWindow, i32, i32, [0 x i32], i8*, i8* } +%struct.GLTColor3 = type { float, float, float } +%struct.GLTColor4 = type { float, float, float, float } +%struct.GLTCoord2 = type { float, float } +%struct.GLTCoord3 = type { float, float, float } +%struct.GLTCoord4 = type { float, float, float, float } +%struct.GLTDimensions = type { i32, i32 } +%struct.GLTFixedColor4 = type { i32, i32, i32, i32 } +%struct.GLTPlane = type { float, float, float, float } +%struct.GLTRectangle = type { i32, i32, i32, i32 } +%struct.GLTTexCoord4 = type { float, float, float, float } +%struct.GLVMFPContext = type { float, i32, i32, i32, i32, [3 x i32] } +%struct.GLVMFragmentAttribRec = type opaque +%struct.GLVMProgramData = type { %struct._GLVMFunction*, %struct.GLVMProgramData*, %struct.GLVMProgramData*, [42 x i32], [64 x i32], i32, i32, i32, [0 x i32] } +%struct.GLVMTextures = type { [16 x %struct.GLDTextureRec*] } +%struct._GLGProcessorData = type opaque +%struct._GLVMConstants = type opaque +%struct._GLVMFunction = type opaque +%struct.anon = type { float, float, float, float } +%struct.mach_timebase_info_data_t = type { i32, i32 } +%struct.pthread_mutex_t = type { i32, [40 x i8] } +%union.GLSBuffer = type { i8* } +%union.GLSDrawable = type { %struct.GLSWindowRec* } +%union.PPStreamToken = type { %0 } +%union._GLGFunctionKey = type opaque +%union.anon = type { %struct.GLTDimensions } + +declare i16 @_OSSwapInt16(i16 zeroext %_data) nounwind inlinehint ssp + +declare i32 @_OSSwapInt32(i32 %_data) nounwind inlinehint ssp + +declare i32 @llvm.bswap.i32(i32) nounwind readnone + +define void @gldAccumReturn(%struct.GLDContextRec* %ctx, %struct.GLDState* %state, float %value) nounwind ssp { +entry: + %ctx_addr = alloca %struct.GLDContextRec* ; <%struct.GLDContextRec**> [#uses=99] + %state_addr = alloca %struct.GLDState* ; <%struct.GLDState**> [#uses=21] + %value_addr = alloca float ; [#uses=33] + %iftmp.210 = alloca float ; [#uses=3] + %iftmp.209 = alloca float ; [#uses=3] + %iftmp.208 = alloca float ; [#uses=3] + %iftmp.207 = alloca float ; [#uses=3] + %iftmp.206 = alloca float ; [#uses=3] + %iftmp.205 = alloca float ; [#uses=3] + %iftmp.204 = alloca float ; [#uses=3] + %iftmp.203 = alloca float ; [#uses=3] + %iftmp.202 = alloca float ; [#uses=3] + %iftmp.201 = alloca float ; [#uses=3] + %iftmp.200 = alloca float ; [#uses=3] + %iftmp.199 = alloca float ; [#uses=3] + %iftmp.198 = alloca float ; [#uses=3] + %iftmp.197 = alloca float ; [#uses=3] + %iftmp.196 = alloca float ; [#uses=3] + %iftmp.195 = alloca float ; [#uses=3] + %iftmp.192 = alloca i8 ; [#uses=3] + %iftmp.190 = alloca i32 ; [#uses=3] + %iftmp.189 = alloca i32 ; [#uses=3] + %iftmp.188 = alloca i32 ; [#uses=3] + %iftmp.187 = alloca i32 ; [#uses=3] + %iftmp.186 = alloca i32 ; [#uses=3] + %iftmp.185 = alloca i32 ; [#uses=3] + %iftmp.184 = alloca i32 ; [#uses=3] + %iftmp.183 = alloca i32 ; [#uses=3] + %iftmp.182 = alloca i8 ; [#uses=3] + %iftmp.181 = alloca i8 ; [#uses=3] + %iftmp.180 = alloca i8 ; [#uses=3] + %iftmp.179 = alloca i8 ; [#uses=3] + %iftmp.178 = alloca i8 ; [#uses=3] + %iftmp.177 = alloca i8 ; [#uses=3] + %iftmp.176 = alloca i8 ; [#uses=3] + %iftmp.175 = alloca i8 ; [#uses=3] + %iftmp.174 = alloca i8 ; [#uses=3] + %iftmp.173 = alloca i8 ; [#uses=3] + %iftmp.172 = alloca i8 ; [#uses=3] + %iftmp.171 = alloca i8 ; [#uses=3] + %iftmp.170 = alloca i8 ; [#uses=3] + %iftmp.169 = alloca i8 ; [#uses=3] + %iftmp.168 = alloca i8 ; [#uses=3] + %iftmp.167 = alloca i8 ; [#uses=3] + %iftmp.164 = alloca i8 ; [#uses=3] + %iftmp.163 = alloca float ; [#uses=3] + %iftmp.162 = alloca float ; [#uses=3] + %iftmp.161 = alloca float ; [#uses=3] + %iftmp.160 = alloca float ; [#uses=3] + %iftmp.159 = alloca float ; [#uses=3] + %iftmp.158 = alloca float ; [#uses=3] + %iftmp.157 = alloca float ; [#uses=3] + %iftmp.156 = alloca float ; [#uses=3] + %iftmp.155 = alloca float ; [#uses=3] + %iftmp.154 = alloca float ; [#uses=3] + %iftmp.153 = alloca float ; [#uses=3] + %iftmp.152 = alloca float ; [#uses=3] + %iftmp.151 = alloca float ; [#uses=3] + %iftmp.150 = alloca float ; [#uses=3] + %iftmp.149 = alloca float ; [#uses=3] + %iftmp.148 = alloca float ; [#uses=3] + %iftmp.145 = alloca i8 ; [#uses=3] + %iftmp.144 = alloca i8 ; [#uses=3] + %iftmp.141 = alloca i8 ; [#uses=3] + %iftmp.140 = alloca i32 ; [#uses=3] + %accum = alloca double* ; [#uses=56] + %accum_end = alloca double* ; [#uses=9] + %y = alloca i32 ; [#uses=12] + %yl = alloca i32 ; [#uses=4] + %cw4 = alloca i32 ; [#uses=4] + %cx = alloca i32 ; [#uses=2] + %cy = alloca i32 ; [#uses=7] + %ch = alloca i32 ; [#uses=3] + %cw = alloca i32 ; [#uses=3] + %offset = alloca i32 ; [#uses=19] + %y_inc = alloca i32 ; [#uses=6] + %swap = alloca i8 ; [#uses=6] + %draw_buffer = alloca i32 ; [#uses=21] + %all_bits_mask = alloca i32 ; [#uses=9] + %color_mask_enabled = alloca i8 ; [#uses=4] + %color_ptr = alloca i16* ; [#uses=8] + %thirtyOne = alloca float ; [#uses=23] + %start_offset = alloca i32 ; [#uses=2] + %cur_draw_buffer_mask_bit = alloca i32 ; [#uses=5] + %r = alloca float ; [#uses=12] + %g = alloca float ; [#uses=12] + %b = alloca float ; [#uses=12] + %a = alloca float ; [#uses=12] + %pixl = alloca i16 ; [#uses=24] + %color_ptr111 = alloca i8* ; [#uses=14] + %twoFiftyFive = alloca float ; [#uses=17] + %start_offset112 = alloca i32 ; [#uses=2] + %cur_draw_buffer_mask_bit115 = alloca i32 ; [#uses=9] + %r119 = alloca float ; [#uses=7] + %g120 = alloca float ; [#uses=7] + %b121 = alloca float ; [#uses=7] + %a122 = alloca float ; [#uses=7] + %r193 = alloca i32 ; [#uses=2] + %g194 = alloca i32 ; [#uses=2] + %b195 = alloca i32 ; [#uses=2] + %a196 = alloca i32 ; [#uses=2] + %color = alloca i32 ; [#uses=4] + %color_ptr235 = alloca float* ; [#uses=13] + %start_offset236 = alloca i32 ; [#uses=2] + %cur_draw_buffer_mask_bit239 = alloca i32 ; [#uses=5] + %r243 = alloca float ; [#uses=4] + %g244 = alloca float ; [#uses=4] + %b245 = alloca float ; [#uses=4] + %a246 = alloca float ; [#uses=4] + %r283 = alloca float ; [#uses=4] + %g284 = alloca float ; [#uses=4] + %b285 = alloca float ; [#uses=4] + %a286 = alloca float ; [#uses=4] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + store %struct.GLDContextRec* %ctx, %struct.GLDContextRec** %ctx_addr + store %struct.GLDState* %state, %struct.GLDState** %state_addr + store float %value, float* %value_addr + %0 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %1 = getelementptr inbounds %struct.GLDContextRec* %0, i32 0, i32 51 ; <%union.GLSDrawable*> [#uses=1] + %2 = getelementptr inbounds %union.GLSDrawable* %1, i32 0, i32 0 ; <%struct.GLSWindowRec**> [#uses=1] + %3 = bitcast %struct.GLSWindowRec** %2 to %struct.GLSGenericRec** ; <%struct.GLSGenericRec**> [#uses=1] + %4 = load %struct.GLSGenericRec** %3, align 4 ; <%struct.GLSGenericRec*> [#uses=1] + %5 = getelementptr inbounds %struct.GLSGenericRec* %4, i32 0, i32 16 ; [#uses=1] + %6 = load i8* %5, align 4 ; [#uses=1] + store i8 %6, i8* %swap, align 1 + store i32 255, i32* %all_bits_mask, align 4 + %7 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] + %8 = getelementptr inbounds %struct.GLDState* %7, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] + %9 = getelementptr inbounds %struct.GLDMaskMode* %8, i32 0, i32 5 ; [#uses=1] + %10 = load i8* %9, align 1 ; [#uses=1] + %11 = zext i8 %10 to i32 ; [#uses=1] + %12 = load i32* %all_bits_mask, align 4 ; [#uses=1] + %13 = and i32 %11, %12 ; [#uses=1] + %14 = load i32* %all_bits_mask, align 4 ; [#uses=1] + %15 = icmp ne i32 %13, %14 ; [#uses=1] + %16 = zext i1 %15 to i8 ; [#uses=1] + %17 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] + %18 = getelementptr inbounds %struct.GLDState* %17, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] + %19 = getelementptr inbounds %struct.GLDMaskMode* %18, i32 0, i32 2 ; [#uses=1] + %20 = load i8* %19, align 16 ; [#uses=1] + %21 = zext i8 %20 to i32 ; [#uses=1] + %22 = load i32* %all_bits_mask, align 4 ; [#uses=1] + %23 = and i32 %21, %22 ; [#uses=1] + %24 = load i32* %all_bits_mask, align 4 ; [#uses=1] + %25 = icmp ne i32 %23, %24 ; [#uses=1] + %26 = zext i1 %25 to i8 ; [#uses=1] + %toBool = icmp ne i8 %16, 0 ; [#uses=1] + %toBool1 = icmp ne i8 %26, 0 ; [#uses=1] + %27 = or i1 %toBool, %toBool1 ; [#uses=1] + %28 = zext i1 %27 to i8 ; [#uses=1] + %29 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] + %30 = getelementptr inbounds %struct.GLDState* %29, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] + %31 = getelementptr inbounds %struct.GLDMaskMode* %30, i32 0, i32 4 ; [#uses=1] + %32 = load i8* %31, align 2 ; [#uses=1] + %33 = zext i8 %32 to i32 ; [#uses=1] + %34 = load i32* %all_bits_mask, align 4 ; [#uses=1] + %35 = and i32 %33, %34 ; [#uses=1] + %36 = load i32* %all_bits_mask, align 4 ; [#uses=1] + %37 = icmp ne i32 %35, %36 ; [#uses=1] + %38 = zext i1 %37 to i8 ; [#uses=1] + %toBool2 = icmp ne i8 %28, 0 ; [#uses=1] + %toBool3 = icmp ne i8 %38, 0 ; [#uses=1] + %39 = or i1 %toBool2, %toBool3 ; [#uses=1] + %40 = zext i1 %39 to i8 ; [#uses=1] + %41 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] + %42 = getelementptr inbounds %struct.GLDState* %41, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] + %43 = getelementptr inbounds %struct.GLDMaskMode* %42, i32 0, i32 3 ; [#uses=1] + %44 = load i8* %43, align 1 ; [#uses=1] + %45 = zext i8 %44 to i32 ; [#uses=1] + %46 = load i32* %all_bits_mask, align 4 ; [#uses=1] + %47 = and i32 %45, %46 ; [#uses=1] + %48 = load i32* %all_bits_mask, align 4 ; [#uses=1] + %49 = icmp ne i32 %47, %48 ; [#uses=1] + %50 = zext i1 %49 to i8 ; [#uses=1] + %toBool4 = icmp ne i8 %40, 0 ; [#uses=1] + %toBool5 = icmp ne i8 %50, 0 ; [#uses=1] + %51 = or i1 %toBool4, %toBool5 ; [#uses=1] + %52 = zext i1 %51 to i8 ; [#uses=1] + store i8 %52, i8* %color_mask_enabled, align 1 + %53 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %54 = getelementptr inbounds %struct.GLDContextRec* %53, i32 0, i32 55 ; <%struct.GLDRect*> [#uses=1] + %55 = getelementptr inbounds %struct.GLDRect* %54, i32 0, i32 0 ; [#uses=1] + %56 = load i32* %55, align 4 ; [#uses=1] + store i32 %56, i32* %cx, align 4 + %57 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %58 = getelementptr inbounds %struct.GLDContextRec* %57, i32 0, i32 55 ; <%struct.GLDRect*> [#uses=1] + %59 = getelementptr inbounds %struct.GLDRect* %58, i32 0, i32 1 ; [#uses=1] + %60 = load i32* %59, align 4 ; [#uses=1] + store i32 %60, i32* %cy, align 4 + %61 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %62 = getelementptr inbounds %struct.GLDContextRec* %61, i32 0, i32 55 ; <%struct.GLDRect*> [#uses=1] + %63 = getelementptr inbounds %struct.GLDRect* %62, i32 0, i32 4 ; [#uses=1] + %64 = load i32* %63, align 4 ; [#uses=1] + store i32 %64, i32* %cw, align 4 + %65 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %66 = getelementptr inbounds %struct.GLDContextRec* %65, i32 0, i32 55 ; <%struct.GLDRect*> [#uses=1] + %67 = getelementptr inbounds %struct.GLDRect* %66, i32 0, i32 5 ; [#uses=1] + %68 = load i32* %67, align 4 ; [#uses=1] + store i32 %68, i32* %ch, align 4 + %69 = load i32* %cw, align 4 ; [#uses=1] + %70 = icmp eq i32 %69, 0 ; [#uses=1] + br i1 %70, label %bb6, label %bb + +bb: ; preds = %entry + %71 = load i32* %ch, align 4 ; [#uses=1] + %72 = icmp eq i32 %71, 0 ; [#uses=1] + br i1 %72, label %bb6, label %bb7 + +bb6: ; preds = %bb, %entry + br label %bb316 + +bb7: ; preds = %bb + %73 = load i32* %cw, align 4 ; [#uses=1] + %74 = mul i32 %73, 4 ; [#uses=1] + store i32 %74, i32* %cw4, align 4 + %75 = load i32* %cy, align 4 ; [#uses=1] + %76 = load i32* %ch, align 4 ; [#uses=1] + %77 = add i32 %75, %76 ; [#uses=1] + store i32 %77, i32* %yl, align 4 + %78 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %79 = getelementptr inbounds %struct.GLDContextRec* %78, i32 0, i32 30 ; <%struct.GLDBufferstate*> [#uses=1] + %80 = getelementptr inbounds %struct.GLDBufferstate* %79, i32 0, i32 1 ; <%struct.GLTDimensions*> [#uses=1] + %81 = getelementptr inbounds %struct.GLTDimensions* %80, i32 0, i32 0 ; [#uses=1] + %82 = load i32* %81, align 4 ; [#uses=1] + %83 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %84 = getelementptr inbounds %struct.GLDContextRec* %83, i32 0, i32 28 ; <%struct.GLDFramebufferRec**> [#uses=1] + %85 = load %struct.GLDFramebufferRec** %84, align 4 ; <%struct.GLDFramebufferRec*> [#uses=1] + %86 = icmp ne %struct.GLDFramebufferRec* %85, null ; [#uses=1] + br i1 %86, label %bb8, label %bb9 + +bb8: ; preds = %bb7 + %87 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %88 = getelementptr inbounds %struct.GLDContextRec* %87, i32 0, i32 57 ; <%struct.GLDFormat*> [#uses=1] + %89 = getelementptr inbounds %struct.GLDFormat* %88, i32 0, i32 12 ; [#uses=1] + %90 = load i8* %89, align 2 ; [#uses=1] + %91 = icmp ne i8 %90, 0 ; [#uses=1] + %92 = zext i1 %91 to i8 ; [#uses=1] + store i8 %92, i8* %iftmp.141, align 1 + br label %bb10 + +bb9: ; preds = %bb7 + %93 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %94 = getelementptr inbounds %struct.GLDContextRec* %93, i32 0, i32 56 ; <%struct.GLDFormat*> [#uses=1] + %95 = getelementptr inbounds %struct.GLDFormat* %94, i32 0, i32 12 ; [#uses=1] + %96 = load i8* %95, align 2 ; [#uses=1] + %97 = icmp ne i8 %96, 0 ; [#uses=1] + %98 = zext i1 %97 to i8 ; [#uses=1] + store i8 %98, i8* %iftmp.141, align 1 + br label %bb10 + +bb10: ; preds = %bb9, %bb8 + %99 = load i8* %iftmp.141, align 1 ; [#uses=1] + %toBool11 = icmp ne i8 %99, 0 ; [#uses=1] + br i1 %toBool11, label %bb12, label %bb13 + +bb12: ; preds = %bb10 + %100 = load i32* %cy, align 4 ; [#uses=1] + store i32 %100, i32* %iftmp.140, align 4 + br label %bb14 + +bb13: ; preds = %bb10 + %101 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %102 = getelementptr inbounds %struct.GLDContextRec* %101, i32 0, i32 30 ; <%struct.GLDBufferstate*> [#uses=1] + %103 = getelementptr inbounds %struct.GLDBufferstate* %102, i32 0, i32 1 ; <%struct.GLTDimensions*> [#uses=1] + %104 = getelementptr inbounds %struct.GLTDimensions* %103, i32 0, i32 1 ; [#uses=1] + %105 = load i32* %104, align 4 ; [#uses=1] + %106 = sub nsw i32 %105, 1 ; [#uses=1] + %107 = load i32* %cy, align 4 ; [#uses=1] + %108 = sub nsw i32 %106, %107 ; [#uses=1] + store i32 %108, i32* %iftmp.140, align 4 + br label %bb14 + +bb14: ; preds = %bb13, %bb12 + %109 = load i32* %iftmp.140, align 4 ; [#uses=1] + %110 = mul nsw i32 %82, %109 ; [#uses=1] + %111 = load i32* %cx, align 4 ; [#uses=1] + %112 = add nsw i32 %110, %111 ; [#uses=1] + store i32 %112, i32* %offset, align 4 + %113 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %114 = getelementptr inbounds %struct.GLDContextRec* %113, i32 0, i32 30 ; <%struct.GLDBufferstate*> [#uses=1] + %115 = getelementptr inbounds %struct.GLDBufferstate* %114, i32 0, i32 1 ; <%struct.GLTDimensions*> [#uses=1] + %116 = getelementptr inbounds %struct.GLTDimensions* %115, i32 0, i32 0 ; [#uses=1] + %117 = load i32* %116, align 4 ; [#uses=1] + store i32 %117, i32* %y_inc, align 4 + %118 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %119 = getelementptr inbounds %struct.GLDContextRec* %118, i32 0, i32 28 ; <%struct.GLDFramebufferRec**> [#uses=1] + %120 = load %struct.GLDFramebufferRec** %119, align 4 ; <%struct.GLDFramebufferRec*> [#uses=1] + %121 = icmp ne %struct.GLDFramebufferRec* %120, null ; [#uses=1] + br i1 %121, label %bb15, label %bb16 + +bb15: ; preds = %bb14 + %122 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %123 = getelementptr inbounds %struct.GLDContextRec* %122, i32 0, i32 57 ; <%struct.GLDFormat*> [#uses=1] + %124 = getelementptr inbounds %struct.GLDFormat* %123, i32 0, i32 12 ; [#uses=1] + %125 = load i8* %124, align 2 ; [#uses=1] + %126 = icmp eq i8 %125, 0 ; [#uses=1] + %127 = zext i1 %126 to i8 ; [#uses=1] + store i8 %127, i8* %iftmp.144, align 1 + br label %bb17 + +bb16: ; preds = %bb14 + %128 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %129 = getelementptr inbounds %struct.GLDContextRec* %128, i32 0, i32 56 ; <%struct.GLDFormat*> [#uses=1] + %130 = getelementptr inbounds %struct.GLDFormat* %129, i32 0, i32 12 ; [#uses=1] + %131 = load i8* %130, align 2 ; [#uses=1] + %132 = icmp eq i8 %131, 0 ; [#uses=1] + %133 = zext i1 %132 to i8 ; [#uses=1] + store i8 %133, i8* %iftmp.144, align 1 + br label %bb17 + +bb17: ; preds = %bb16, %bb15 + %134 = load i8* %iftmp.144, align 1 ; [#uses=1] + %toBool18 = icmp ne i8 %134, 0 ; [#uses=1] + br i1 %toBool18, label %bb19, label %bb20 + +bb19: ; preds = %bb17 + %135 = load i32* %y_inc, align 4 ; [#uses=1] + %136 = sub i32 0, %135 ; [#uses=1] + store i32 %136, i32* %y_inc, align 4 + br label %bb20 + +bb20: ; preds = %bb19, %bb17 + %137 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %138 = getelementptr inbounds %struct.GLDContextRec* %137, i32 0, i32 28 ; <%struct.GLDFramebufferRec**> [#uses=1] + %139 = load %struct.GLDFramebufferRec** %138, align 4 ; <%struct.GLDFramebufferRec*> [#uses=1] + %140 = icmp ne %struct.GLDFramebufferRec* %139, null ; [#uses=1] + br i1 %140, label %bb21, label %bb22 + +bb21: ; preds = %bb20 + %141 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %142 = getelementptr inbounds %struct.GLDContextRec* %141, i32 0, i32 28 ; <%struct.GLDFramebufferRec**> [#uses=1] + %143 = load %struct.GLDFramebufferRec** %142, align 4 ; <%struct.GLDFramebufferRec*> [#uses=1] + %144 = getelementptr inbounds %struct.GLDFramebufferRec* %143, i32 0, i32 2 ; <[10 x %struct.GLDFormat]*> [#uses=1] + %145 = getelementptr inbounds [10 x %struct.GLDFormat]* %144, i32 0, i32 0 ; <%struct.GLDFormat*> [#uses=1] + %146 = getelementptr inbounds %struct.GLDFormat* %145, i32 0, i32 7 ; [#uses=1] + %147 = load i32* %146, align 4 ; [#uses=1] + %148 = icmp eq i32 %147, 33638 ; [#uses=1] + %149 = zext i1 %148 to i8 ; [#uses=1] + store i8 %149, i8* %iftmp.145, align 1 + br label %bb23 + +bb22: ; preds = %bb20 + %150 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %151 = getelementptr inbounds %struct.GLDContextRec* %150, i32 0, i32 56 ; <%struct.GLDFormat*> [#uses=1] + %152 = getelementptr inbounds %struct.GLDFormat* %151, i32 0, i32 7 ; [#uses=1] + %153 = load i32* %152, align 4 ; [#uses=1] + %154 = icmp eq i32 %153, 33638 ; [#uses=1] + %155 = zext i1 %154 to i8 ; [#uses=1] + store i8 %155, i8* %iftmp.145, align 1 + br label %bb23 + +bb23: ; preds = %bb22, %bb21 + %156 = load i8* %iftmp.145, align 1 ; [#uses=1] + %toBool24 = icmp ne i8 %156, 0 ; [#uses=1] + br i1 %toBool24, label %bb25, label %bb105 + +bb25: ; preds = %bb23 + %157 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %158 = getelementptr inbounds %struct.GLDContextRec* %157, i32 0, i32 6 ; [#uses=1] + %159 = load float* %158, align 4 ; [#uses=1] + store float %159, float* %thirtyOne, align 4 + %160 = load i32* %offset, align 4 ; [#uses=1] + store i32 %160, i32* %start_offset, align 4 + store i32 0, i32* %draw_buffer, align 4 + br label %bb104 + +bb26: ; preds = %bb104 + %161 = load i32* %start_offset, align 4 ; [#uses=1] + store i32 %161, i32* %offset, align 4 + %162 = load i32* %draw_buffer, align 4 ; [#uses=1] + %163 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %164 = getelementptr inbounds %struct.GLDContextRec* %163, i32 0, i32 30 ; <%struct.GLDBufferstate*> [#uses=1] + %165 = getelementptr inbounds %struct.GLDBufferstate* %164, i32 0, i32 12 ; <[8 x %union.GLSBuffer]*> [#uses=1] + %166 = getelementptr inbounds [8 x %union.GLSBuffer]* %165, i32 0, i32 %162 ; <%union.GLSBuffer*> [#uses=1] + %167 = getelementptr inbounds %union.GLSBuffer* %166, i32 0, i32 0 ; [#uses=1] + %168 = load i8** %167, align 4 ; [#uses=1] + %169 = icmp ne i8* %168, null ; [#uses=1] + br i1 %169, label %bb27, label %bb103 + +bb27: ; preds = %bb26 + %170 = load i32* %draw_buffer, align 4 ; [#uses=1] + %171 = shl i32 1, %170 ; [#uses=1] + store i32 %171, i32* %cur_draw_buffer_mask_bit, align 4 + %172 = load i32* %cy, align 4 ; [#uses=1] + store i32 %172, i32* %y, align 4 + br label %bb102 + +bb28: ; preds = %bb102 + %173 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %174 = getelementptr inbounds %struct.GLDContextRec* %173, i32 0, i32 30 ; <%struct.GLDBufferstate*> [#uses=1] + %175 = getelementptr inbounds %struct.GLDBufferstate* %174, i32 0, i32 11 ; <%union.GLSBuffer*> [#uses=1] + %176 = getelementptr inbounds %union.GLSBuffer* %175, i32 0, i32 0 ; [#uses=1] + %177 = bitcast i8** %176 to double** ; [#uses=1] + %178 = load double** %177, align 4 ; [#uses=1] + %179 = load i32* %offset, align 4 ; [#uses=1] + %180 = mul i32 %179, 4 ; [#uses=1] + %181 = getelementptr inbounds double* %178, i32 %180 ; [#uses=1] + store double* %181, double** %accum, align 4 + %182 = load double** %accum, align 4 ; [#uses=1] + %183 = load i32* %cw4, align 4 ; [#uses=1] + %184 = getelementptr inbounds double* %182, i32 %183 ; [#uses=1] + store double* %184, double** %accum_end, align 4 + %185 = load i32* %draw_buffer, align 4 ; [#uses=1] + %186 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %187 = getelementptr inbounds %struct.GLDContextRec* %186, i32 0, i32 30 ; <%struct.GLDBufferstate*> [#uses=1] + %188 = getelementptr inbounds %struct.GLDBufferstate* %187, i32 0, i32 12 ; <[8 x %union.GLSBuffer]*> [#uses=1] + %189 = getelementptr inbounds [8 x %union.GLSBuffer]* %188, i32 0, i32 %185 ; <%union.GLSBuffer*> [#uses=1] + %190 = getelementptr inbounds %union.GLSBuffer* %189, i32 0, i32 0 ; [#uses=1] + %191 = bitcast i8** %190 to i16** ; [#uses=1] + %192 = load i16** %191, align 4 ; [#uses=1] + %193 = load i32* %offset, align 4 ; [#uses=1] + %194 = getelementptr inbounds i16* %192, i32 %193 ; [#uses=1] + store i16* %194, i16** %color_ptr, align 4 + %195 = load i8* %color_mask_enabled, align 1 ; [#uses=1] + %196 = icmp ne i8 %195, 0 ; [#uses=1] + br i1 %196, label %bb29, label %bb70 + +bb29: ; preds = %bb28 + br label %bb68 + +bb30: ; preds = %bb68 + %197 = load double** %accum, align 4 ; [#uses=1] + %198 = getelementptr inbounds double* %197, i32 3 ; [#uses=1] + %199 = load double* %198, align 1 ; [#uses=1] + %200 = fptrunc double %199 to float ; [#uses=1] + %201 = load float* %value_addr, align 4 ; [#uses=1] + %202 = fmul float %200, %201 ; [#uses=1] + store float %202, float* %a, align 4 + %203 = load double** %accum, align 4 ; [#uses=1] + %204 = getelementptr inbounds double* %203, i32 0 ; [#uses=1] + %205 = load double* %204, align 1 ; [#uses=1] + %206 = fptrunc double %205 to float ; [#uses=1] + %207 = load float* %thirtyOne, align 4 ; [#uses=1] + %208 = fmul float %206, %207 ; [#uses=1] + %209 = load float* %value_addr, align 4 ; [#uses=1] + %210 = fmul float %208, %209 ; [#uses=1] + %211 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %212 = getelementptr inbounds %struct.GLDContextRec* %211, i32 0, i32 1 ; [#uses=1] + %213 = load float* %212, align 4 ; [#uses=1] + %214 = fadd float %210, %213 ; [#uses=1] + store float %214, float* %r, align 4 + %215 = load double** %accum, align 4 ; [#uses=1] + %216 = getelementptr inbounds double* %215, i32 1 ; [#uses=1] + %217 = load double* %216, align 1 ; [#uses=1] + %218 = fptrunc double %217 to float ; [#uses=1] + %219 = load float* %thirtyOne, align 4 ; [#uses=1] + %220 = fmul float %218, %219 ; [#uses=1] + %221 = load float* %value_addr, align 4 ; [#uses=1] + %222 = fmul float %220, %221 ; [#uses=1] + %223 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %224 = getelementptr inbounds %struct.GLDContextRec* %223, i32 0, i32 1 ; [#uses=1] + %225 = load float* %224, align 4 ; [#uses=1] + %226 = fadd float %222, %225 ; [#uses=1] + store float %226, float* %g, align 4 + %227 = load double** %accum, align 4 ; [#uses=1] + %228 = getelementptr inbounds double* %227, i32 2 ; [#uses=1] + %229 = load double* %228, align 1 ; [#uses=1] + %230 = fptrunc double %229 to float ; [#uses=1] + %231 = load float* %thirtyOne, align 4 ; [#uses=1] + %232 = fmul float %230, %231 ; [#uses=1] + %233 = load float* %value_addr, align 4 ; [#uses=1] + %234 = fmul float %232, %233 ; [#uses=1] + %235 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %236 = getelementptr inbounds %struct.GLDContextRec* %235, i32 0, i32 1 ; [#uses=1] + %237 = load float* %236, align 4 ; [#uses=1] + %238 = fadd float %234, %237 ; [#uses=1] + store float %238, float* %b, align 4 + %239 = load float* %r, align 4 ; [#uses=1] + %240 = fcmp uge float %239, 0.000000e+00 ; [#uses=1] + br i1 %240, label %bb31, label %bb35 + +bb31: ; preds = %bb30 + %241 = load float* %r, align 4 ; [#uses=1] + %242 = load float* %thirtyOne, align 4 ; [#uses=1] + %243 = fcmp ogt float %241, %242 ; [#uses=1] + br i1 %243, label %bb32, label %bb33 + +bb32: ; preds = %bb31 + %244 = load float* %thirtyOne, align 4 ; [#uses=1] + store float %244, float* %iftmp.149, align 4 + br label %bb34 + +bb33: ; preds = %bb31 + %245 = load float* %r, align 4 ; [#uses=1] + store float %245, float* %iftmp.149, align 4 + br label %bb34 + +bb34: ; preds = %bb33, %bb32 + %246 = load float* %iftmp.149, align 4 ; [#uses=1] + store float %246, float* %iftmp.148, align 4 + br label %bb36 + +bb35: ; preds = %bb30 + store float 0.000000e+00, float* %iftmp.148, align 4 + br label %bb36 + +bb36: ; preds = %bb35, %bb34 + %247 = load float* %iftmp.148, align 4 ; [#uses=1] + store float %247, float* %r, align 4 + %248 = load float* %g, align 4 ; [#uses=1] + %249 = fcmp uge float %248, 0.000000e+00 ; [#uses=1] + br i1 %249, label %bb37, label %bb41 + +bb37: ; preds = %bb36 + %250 = load float* %g, align 4 ; [#uses=1] + %251 = load float* %thirtyOne, align 4 ; [#uses=1] + %252 = fcmp ogt float %250, %251 ; [#uses=1] + br i1 %252, label %bb38, label %bb39 + +bb38: ; preds = %bb37 + %253 = load float* %thirtyOne, align 4 ; [#uses=1] + store float %253, float* %iftmp.151, align 4 + br label %bb40 + +bb39: ; preds = %bb37 + %254 = load float* %g, align 4 ; [#uses=1] + store float %254, float* %iftmp.151, align 4 + br label %bb40 + +bb40: ; preds = %bb39, %bb38 + %255 = load float* %iftmp.151, align 4 ; [#uses=1] + store float %255, float* %iftmp.150, align 4 + br label %bb42 + +bb41: ; preds = %bb36 + store float 0.000000e+00, float* %iftmp.150, align 4 + br label %bb42 + +bb42: ; preds = %bb41, %bb40 + %256 = load float* %iftmp.150, align 4 ; [#uses=1] + store float %256, float* %g, align 4 + %257 = load float* %b, align 4 ; [#uses=1] + %258 = fcmp uge float %257, 0.000000e+00 ; [#uses=1] + br i1 %258, label %bb43, label %bb47 + +bb43: ; preds = %bb42 + %259 = load float* %b, align 4 ; [#uses=1] + %260 = load float* %thirtyOne, align 4 ; [#uses=1] + %261 = fcmp ogt float %259, %260 ; [#uses=1] + br i1 %261, label %bb44, label %bb45 + +bb44: ; preds = %bb43 + %262 = load float* %thirtyOne, align 4 ; [#uses=1] + store float %262, float* %iftmp.153, align 4 + br label %bb46 + +bb45: ; preds = %bb43 + %263 = load float* %b, align 4 ; [#uses=1] + store float %263, float* %iftmp.153, align 4 + br label %bb46 + +bb46: ; preds = %bb45, %bb44 + %264 = load float* %iftmp.153, align 4 ; [#uses=1] + store float %264, float* %iftmp.152, align 4 + br label %bb48 + +bb47: ; preds = %bb42 + store float 0.000000e+00, float* %iftmp.152, align 4 + br label %bb48 + +bb48: ; preds = %bb47, %bb46 + %265 = load float* %iftmp.152, align 4 ; [#uses=1] + store float %265, float* %b, align 4 + %266 = load float* %a, align 4 ; [#uses=1] + %267 = fcmp uge float %266, 0.000000e+00 ; [#uses=1] + br i1 %267, label %bb49, label %bb53 + +bb49: ; preds = %bb48 + %268 = load float* %a, align 4 ; [#uses=1] + %269 = load float* %thirtyOne, align 4 ; [#uses=1] + %270 = fcmp ogt float %268, %269 ; [#uses=1] + br i1 %270, label %bb50, label %bb51 + +bb50: ; preds = %bb49 + %271 = load float* %thirtyOne, align 4 ; [#uses=1] + store float %271, float* %iftmp.155, align 4 + br label %bb52 + +bb51: ; preds = %bb49 + %272 = load float* %a, align 4 ; [#uses=1] + store float %272, float* %iftmp.155, align 4 + br label %bb52 + +bb52: ; preds = %bb51, %bb50 + %273 = load float* %iftmp.155, align 4 ; [#uses=1] + store float %273, float* %iftmp.154, align 4 + br label %bb54 + +bb53: ; preds = %bb48 + store float 0.000000e+00, float* %iftmp.154, align 4 + br label %bb54 + +bb54: ; preds = %bb53, %bb52 + %274 = load float* %iftmp.154, align 4 ; [#uses=1] + store float %274, float* %a, align 4 + %275 = load i16** %color_ptr, align 4 ; [#uses=1] + %276 = load i16* %275, align 2 ; [#uses=1] + store i16 %276, i16* %pixl, align 2 + %277 = load i8* %swap, align 1 ; [#uses=1] + %278 = icmp ne i8 %277, 0 ; [#uses=1] + br i1 %278, label %bb55, label %bb56 + +bb55: ; preds = %bb54 + %279 = load i16* %pixl, align 2 ; [#uses=1] + %280 = zext i16 %279 to i32 ; [#uses=1] + %281 = trunc i32 %280 to i16 ; [#uses=1] + %282 = call zeroext i16 @_OSSwapInt16(i16 zeroext %281) nounwind ; [#uses=1] + store i16 %282, i16* %pixl, align 2 + br label %bb56 + +bb56: ; preds = %bb55, %bb54 + %283 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] + %284 = getelementptr inbounds %struct.GLDState* %283, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] + %285 = getelementptr inbounds %struct.GLDMaskMode* %284, i32 0, i32 2 ; [#uses=1] + %286 = load i8* %285, align 16 ; [#uses=1] + %287 = zext i8 %286 to i32 ; [#uses=1] + %288 = load i32* %cur_draw_buffer_mask_bit, align 4 ; [#uses=1] + %289 = and i32 %287, %288 ; [#uses=1] + %290 = icmp ne i32 %289, 0 ; [#uses=1] + br i1 %290, label %bb57, label %bb58 + +bb57: ; preds = %bb56 + %291 = load i16* %pixl, align 2 ; [#uses=1] + %292 = and i16 %291, -32257 ; [#uses=1] + %293 = load float* %r, align 4 ; [#uses=1] + %294 = fptoui float %293 to i32 ; [#uses=1] + %295 = trunc i32 %294 to i16 ; [#uses=1] + %296 = shl i16 %295, 10 ; [#uses=1] + %297 = and i16 %296, 31744 ; [#uses=1] + %298 = or i16 %292, %297 ; [#uses=1] + store i16 %298, i16* %pixl, align 2 + br label %bb58 + +bb58: ; preds = %bb57, %bb56 + %299 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] + %300 = getelementptr inbounds %struct.GLDState* %299, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] + %301 = getelementptr inbounds %struct.GLDMaskMode* %300, i32 0, i32 3 ; [#uses=1] + %302 = load i8* %301, align 1 ; [#uses=1] + %303 = zext i8 %302 to i32 ; [#uses=1] + %304 = load i32* %cur_draw_buffer_mask_bit, align 4 ; [#uses=1] + %305 = and i32 %303, %304 ; [#uses=1] + %306 = icmp ne i32 %305, 0 ; [#uses=1] + br i1 %306, label %bb59, label %bb60 + +bb59: ; preds = %bb58 + %307 = load i16* %pixl, align 2 ; [#uses=1] + %308 = and i16 %307, -993 ; [#uses=1] + %309 = load float* %g, align 4 ; [#uses=1] + %310 = fptoui float %309 to i32 ; [#uses=1] + %311 = trunc i32 %310 to i16 ; [#uses=1] + %312 = shl i16 %311, 5 ; [#uses=1] + %313 = and i16 %312, 992 ; [#uses=1] + %314 = or i16 %308, %313 ; [#uses=1] + store i16 %314, i16* %pixl, align 2 + br label %bb60 + +bb60: ; preds = %bb59, %bb58 + %315 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] + %316 = getelementptr inbounds %struct.GLDState* %315, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] + %317 = getelementptr inbounds %struct.GLDMaskMode* %316, i32 0, i32 4 ; [#uses=1] + %318 = load i8* %317, align 2 ; [#uses=1] + %319 = zext i8 %318 to i32 ; [#uses=1] + %320 = load i32* %cur_draw_buffer_mask_bit, align 4 ; [#uses=1] + %321 = and i32 %319, %320 ; [#uses=1] + %322 = icmp ne i32 %321, 0 ; [#uses=1] + br i1 %322, label %bb61, label %bb62 + +bb61: ; preds = %bb60 + %323 = load i16* %pixl, align 2 ; [#uses=1] + %324 = and i16 %323, -32 ; [#uses=1] + %325 = load float* %b, align 4 ; [#uses=1] + %326 = fptoui float %325 to i32 ; [#uses=1] + %327 = trunc i32 %326 to i16 ; [#uses=1] + %328 = and i16 %327, 31 ; [#uses=1] + %329 = or i16 %324, %328 ; [#uses=1] + store i16 %329, i16* %pixl, align 2 + br label %bb62 + +bb62: ; preds = %bb61, %bb60 + %330 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] + %331 = getelementptr inbounds %struct.GLDState* %330, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] + %332 = getelementptr inbounds %struct.GLDMaskMode* %331, i32 0, i32 5 ; [#uses=1] + %333 = load i8* %332, align 1 ; [#uses=1] + %334 = zext i8 %333 to i32 ; [#uses=1] + %335 = load i32* %cur_draw_buffer_mask_bit, align 4 ; [#uses=1] + %336 = and i32 %334, %335 ; [#uses=1] + %337 = icmp ne i32 %336, 0 ; [#uses=1] + br i1 %337, label %bb63, label %bb65 + +bb63: ; preds = %bb62 + %338 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %339 = getelementptr inbounds %struct.GLDContextRec* %338, i32 0, i32 1 ; [#uses=1] + %340 = load float* %339, align 4 ; [#uses=1] + %341 = load float* %a, align 4 ; [#uses=1] + %342 = fcmp olt float %340, %341 ; [#uses=1] + br i1 %342, label %bb64, label %bb65 + +bb64: ; preds = %bb63 + %343 = load i16* %pixl, align 2 ; [#uses=1] + %344 = or i16 %343, -32768 ; [#uses=1] + store i16 %344, i16* %pixl, align 2 + br label %bb65 + +bb65: ; preds = %bb64, %bb63, %bb62 + %345 = load i8* %swap, align 1 ; [#uses=1] + %346 = icmp ne i8 %345, 0 ; [#uses=1] + br i1 %346, label %bb66, label %bb67 + +bb66: ; preds = %bb65 + %347 = load i16* %pixl, align 2 ; [#uses=1] + %348 = zext i16 %347 to i32 ; [#uses=1] + %349 = trunc i32 %348 to i16 ; [#uses=1] + %350 = call zeroext i16 @_OSSwapInt16(i16 zeroext %349) nounwind ; [#uses=1] + store i16 %350, i16* %pixl, align 2 + br label %bb67 + +bb67: ; preds = %bb66, %bb65 + %351 = load i16** %color_ptr, align 4 ; [#uses=1] + %352 = load i16* %pixl, align 2 ; [#uses=1] + store i16 %352, i16* %351, align 2 + %353 = load double** %accum, align 4 ; [#uses=1] + %354 = getelementptr inbounds double* %353, i32 4 ; [#uses=1] + store double* %354, double** %accum, align 4 + %355 = load i16** %color_ptr, align 4 ; [#uses=1] + %356 = getelementptr inbounds i16* %355, i32 1 ; [#uses=1] + store i16* %356, i16** %color_ptr, align 4 + br label %bb68 + +bb68: ; preds = %bb67, %bb29 + %357 = load double** %accum, align 4 ; [#uses=1] + %358 = load double** %accum_end, align 4 ; [#uses=1] + %359 = icmp ult double* %357, %358 ; [#uses=1] + br i1 %359, label %bb30, label %bb69 + +bb69: ; preds = %bb68 + br label %bb101 + +bb70: ; preds = %bb28 + br label %bb100 + +bb71: ; preds = %bb100 + %360 = load double** %accum, align 4 ; [#uses=1] + %361 = getelementptr inbounds double* %360, i32 3 ; [#uses=1] + %362 = load double* %361, align 1 ; [#uses=1] + %363 = fptrunc double %362 to float ; [#uses=1] + %364 = load float* %value_addr, align 4 ; [#uses=1] + %365 = fmul float %363, %364 ; [#uses=1] + store float %365, float* %a, align 4 + %366 = load double** %accum, align 4 ; [#uses=1] + %367 = getelementptr inbounds double* %366, i32 0 ; [#uses=1] + %368 = load double* %367, align 1 ; [#uses=1] + %369 = fptrunc double %368 to float ; [#uses=1] + %370 = load float* %thirtyOne, align 4 ; [#uses=1] + %371 = fmul float %369, %370 ; [#uses=1] + %372 = load float* %value_addr, align 4 ; [#uses=1] + %373 = fmul float %371, %372 ; [#uses=1] + %374 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %375 = getelementptr inbounds %struct.GLDContextRec* %374, i32 0, i32 1 ; [#uses=1] + %376 = load float* %375, align 4 ; [#uses=1] + %377 = fadd float %373, %376 ; [#uses=1] + store float %377, float* %r, align 4 + %378 = load double** %accum, align 4 ; [#uses=1] + %379 = getelementptr inbounds double* %378, i32 1 ; [#uses=1] + %380 = load double* %379, align 1 ; [#uses=1] + %381 = fptrunc double %380 to float ; [#uses=1] + %382 = load float* %thirtyOne, align 4 ; [#uses=1] + %383 = fmul float %381, %382 ; [#uses=1] + %384 = load float* %value_addr, align 4 ; [#uses=1] + %385 = fmul float %383, %384 ; [#uses=1] + %386 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %387 = getelementptr inbounds %struct.GLDContextRec* %386, i32 0, i32 1 ; [#uses=1] + %388 = load float* %387, align 4 ; [#uses=1] + %389 = fadd float %385, %388 ; [#uses=1] + store float %389, float* %g, align 4 + %390 = load double** %accum, align 4 ; [#uses=1] + %391 = getelementptr inbounds double* %390, i32 2 ; [#uses=1] + %392 = load double* %391, align 1 ; [#uses=1] + %393 = fptrunc double %392 to float ; [#uses=1] + %394 = load float* %thirtyOne, align 4 ; [#uses=1] + %395 = fmul float %393, %394 ; [#uses=1] + %396 = load float* %value_addr, align 4 ; [#uses=1] + %397 = fmul float %395, %396 ; [#uses=1] + %398 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %399 = getelementptr inbounds %struct.GLDContextRec* %398, i32 0, i32 1 ; [#uses=1] + %400 = load float* %399, align 4 ; [#uses=1] + %401 = fadd float %397, %400 ; [#uses=1] + store float %401, float* %b, align 4 + %402 = load float* %r, align 4 ; [#uses=1] + %403 = fcmp uge float %402, 0.000000e+00 ; [#uses=1] + br i1 %403, label %bb72, label %bb76 + +bb72: ; preds = %bb71 + %404 = load float* %r, align 4 ; [#uses=1] + %405 = load float* %thirtyOne, align 4 ; [#uses=1] + %406 = fcmp ogt float %404, %405 ; [#uses=1] + br i1 %406, label %bb73, label %bb74 + +bb73: ; preds = %bb72 + %407 = load float* %thirtyOne, align 4 ; [#uses=1] + store float %407, float* %iftmp.157, align 4 + br label %bb75 + +bb74: ; preds = %bb72 + %408 = load float* %r, align 4 ; [#uses=1] + store float %408, float* %iftmp.157, align 4 + br label %bb75 + +bb75: ; preds = %bb74, %bb73 + %409 = load float* %iftmp.157, align 4 ; [#uses=1] + store float %409, float* %iftmp.156, align 4 + br label %bb77 + +bb76: ; preds = %bb71 + store float 0.000000e+00, float* %iftmp.156, align 4 + br label %bb77 + +bb77: ; preds = %bb76, %bb75 + %410 = load float* %iftmp.156, align 4 ; [#uses=1] + store float %410, float* %r, align 4 + %411 = load float* %g, align 4 ; [#uses=1] + %412 = fcmp uge float %411, 0.000000e+00 ; [#uses=1] + br i1 %412, label %bb78, label %bb82 + +bb78: ; preds = %bb77 + %413 = load float* %g, align 4 ; [#uses=1] + %414 = load float* %thirtyOne, align 4 ; [#uses=1] + %415 = fcmp ogt float %413, %414 ; [#uses=1] + br i1 %415, label %bb79, label %bb80 + +bb79: ; preds = %bb78 + %416 = load float* %thirtyOne, align 4 ; [#uses=1] + store float %416, float* %iftmp.159, align 4 + br label %bb81 + +bb80: ; preds = %bb78 + %417 = load float* %g, align 4 ; [#uses=1] + store float %417, float* %iftmp.159, align 4 + br label %bb81 + +bb81: ; preds = %bb80, %bb79 + %418 = load float* %iftmp.159, align 4 ; [#uses=1] + store float %418, float* %iftmp.158, align 4 + br label %bb83 + +bb82: ; preds = %bb77 + store float 0.000000e+00, float* %iftmp.158, align 4 + br label %bb83 + +bb83: ; preds = %bb82, %bb81 + %419 = load float* %iftmp.158, align 4 ; [#uses=1] + store float %419, float* %g, align 4 + %420 = load float* %b, align 4 ; [#uses=1] + %421 = fcmp uge float %420, 0.000000e+00 ; [#uses=1] + br i1 %421, label %bb84, label %bb88 + +bb84: ; preds = %bb83 + %422 = load float* %b, align 4 ; [#uses=1] + %423 = load float* %thirtyOne, align 4 ; [#uses=1] + %424 = fcmp ogt float %422, %423 ; [#uses=1] + br i1 %424, label %bb85, label %bb86 + +bb85: ; preds = %bb84 + %425 = load float* %thirtyOne, align 4 ; [#uses=1] + store float %425, float* %iftmp.161, align 4 + br label %bb87 + +bb86: ; preds = %bb84 + %426 = load float* %b, align 4 ; [#uses=1] + store float %426, float* %iftmp.161, align 4 + br label %bb87 + +bb87: ; preds = %bb86, %bb85 + %427 = load float* %iftmp.161, align 4 ; [#uses=1] + store float %427, float* %iftmp.160, align 4 + br label %bb89 + +bb88: ; preds = %bb83 + store float 0.000000e+00, float* %iftmp.160, align 4 + br label %bb89 + +bb89: ; preds = %bb88, %bb87 + %428 = load float* %iftmp.160, align 4 ; [#uses=1] + store float %428, float* %b, align 4 + %429 = load float* %a, align 4 ; [#uses=1] + %430 = fcmp uge float %429, 0.000000e+00 ; [#uses=1] + br i1 %430, label %bb90, label %bb94 + +bb90: ; preds = %bb89 + %431 = load float* %a, align 4 ; [#uses=1] + %432 = load float* %thirtyOne, align 4 ; [#uses=1] + %433 = fcmp ogt float %431, %432 ; [#uses=1] + br i1 %433, label %bb91, label %bb92 + +bb91: ; preds = %bb90 + %434 = load float* %thirtyOne, align 4 ; [#uses=1] + store float %434, float* %iftmp.163, align 4 + br label %bb93 + +bb92: ; preds = %bb90 + %435 = load float* %a, align 4 ; [#uses=1] + store float %435, float* %iftmp.163, align 4 + br label %bb93 + +bb93: ; preds = %bb92, %bb91 + %436 = load float* %iftmp.163, align 4 ; [#uses=1] + store float %436, float* %iftmp.162, align 4 + br label %bb95 + +bb94: ; preds = %bb89 + store float 0.000000e+00, float* %iftmp.162, align 4 + br label %bb95 + +bb95: ; preds = %bb94, %bb93 + %437 = load float* %iftmp.162, align 4 ; [#uses=1] + store float %437, float* %a, align 4 + %438 = load float* %r, align 4 ; [#uses=1] + %439 = fptoui float %438 to i32 ; [#uses=1] + %440 = trunc i32 %439 to i16 ; [#uses=1] + %441 = shl i16 %440, 10 ; [#uses=1] + %442 = and i16 %441, 31744 ; [#uses=1] + store i16 %442, i16* %pixl, align 2 + %443 = load float* %g, align 4 ; [#uses=1] + %444 = fptoui float %443 to i32 ; [#uses=1] + %445 = trunc i32 %444 to i16 ; [#uses=1] + %446 = shl i16 %445, 5 ; [#uses=1] + %447 = and i16 %446, 992 ; [#uses=1] + %448 = load i16* %pixl, align 2 ; [#uses=1] + %449 = or i16 %447, %448 ; [#uses=1] + store i16 %449, i16* %pixl, align 2 + %450 = load float* %b, align 4 ; [#uses=1] + %451 = fptoui float %450 to i32 ; [#uses=1] + %452 = trunc i32 %451 to i16 ; [#uses=1] + %453 = and i16 %452, 31 ; [#uses=1] + %454 = load i16* %pixl, align 2 ; [#uses=1] + %455 = or i16 %453, %454 ; [#uses=1] + store i16 %455, i16* %pixl, align 2 + %456 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %457 = getelementptr inbounds %struct.GLDContextRec* %456, i32 0, i32 1 ; [#uses=1] + %458 = load float* %457, align 4 ; [#uses=1] + %459 = load float* %a, align 4 ; [#uses=1] + %460 = fcmp olt float %458, %459 ; [#uses=1] + br i1 %460, label %bb96, label %bb97 + +bb96: ; preds = %bb95 + %461 = load i16* %pixl, align 2 ; [#uses=1] + %462 = or i16 %461, -32768 ; [#uses=1] + store i16 %462, i16* %pixl, align 2 + br label %bb97 + +bb97: ; preds = %bb96, %bb95 + %463 = load i8* %swap, align 1 ; [#uses=1] + %464 = icmp ne i8 %463, 0 ; [#uses=1] + br i1 %464, label %bb98, label %bb99 + +bb98: ; preds = %bb97 + %465 = load i16* %pixl, align 2 ; [#uses=1] + %466 = zext i16 %465 to i32 ; [#uses=1] + %467 = trunc i32 %466 to i16 ; [#uses=1] + %468 = call zeroext i16 @_OSSwapInt16(i16 zeroext %467) nounwind ; [#uses=1] + store i16 %468, i16* %pixl, align 2 + br label %bb99 + +bb99: ; preds = %bb98, %bb97 + %469 = load i16** %color_ptr, align 4 ; [#uses=1] + %470 = load i16* %pixl, align 2 ; [#uses=1] + store i16 %470, i16* %469, align 2 + %471 = load double** %accum, align 4 ; [#uses=1] + %472 = getelementptr inbounds double* %471, i32 4 ; [#uses=1] + store double* %472, double** %accum, align 4 + %473 = load i16** %color_ptr, align 4 ; [#uses=1] + %474 = getelementptr inbounds i16* %473, i32 1 ; [#uses=1] + store i16* %474, i16** %color_ptr, align 4 + br label %bb100 + +bb100: ; preds = %bb99, %bb70 + %475 = load double** %accum, align 4 ; [#uses=1] + %476 = load double** %accum_end, align 4 ; [#uses=1] + %477 = icmp ult double* %475, %476 ; [#uses=1] + br i1 %477, label %bb71, label %bb101 + +bb101: ; preds = %bb100, %bb69 + %478 = load i32* %y, align 4 ; [#uses=1] + %479 = add i32 %478, 1 ; [#uses=1] + store i32 %479, i32* %y, align 4 + %480 = load i32* %offset, align 4 ; [#uses=1] + %481 = load i32* %y_inc, align 4 ; [#uses=1] + %482 = add i32 %480, %481 ; [#uses=1] + store i32 %482, i32* %offset, align 4 + br label %bb102 + +bb102: ; preds = %bb101, %bb27 + %483 = load i32* %y, align 4 ; [#uses=1] + %484 = load i32* %yl, align 4 ; [#uses=1] + %485 = icmp ult i32 %483, %484 ; [#uses=1] + br i1 %485, label %bb28, label %bb103 + +bb103: ; preds = %bb102, %bb26 + %486 = load i32* %draw_buffer, align 4 ; [#uses=1] + %487 = add nsw i32 %486, 1 ; [#uses=1] + store i32 %487, i32* %draw_buffer, align 4 + br label %bb104 + +bb104: ; preds = %bb103, %bb25 + %488 = load i32* %draw_buffer, align 4 ; [#uses=1] + %489 = icmp sle i32 %488, 7 ; [#uses=1] + br i1 %489, label %bb26, label %bb105 + +bb105: ; preds = %bb104, %bb23 + %490 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %491 = getelementptr inbounds %struct.GLDContextRec* %490, i32 0, i32 28 ; <%struct.GLDFramebufferRec**> [#uses=1] + %492 = load %struct.GLDFramebufferRec** %491, align 4 ; <%struct.GLDFramebufferRec*> [#uses=1] + %493 = icmp ne %struct.GLDFramebufferRec* %492, null ; [#uses=1] + br i1 %493, label %bb106, label %bb107 + +bb106: ; preds = %bb105 + %494 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %495 = getelementptr inbounds %struct.GLDContextRec* %494, i32 0, i32 28 ; <%struct.GLDFramebufferRec**> [#uses=1] + %496 = load %struct.GLDFramebufferRec** %495, align 4 ; <%struct.GLDFramebufferRec*> [#uses=1] + %497 = getelementptr inbounds %struct.GLDFramebufferRec* %496, i32 0, i32 2 ; <[10 x %struct.GLDFormat]*> [#uses=1] + %498 = getelementptr inbounds [10 x %struct.GLDFormat]* %497, i32 0, i32 0 ; <%struct.GLDFormat*> [#uses=1] + %499 = getelementptr inbounds %struct.GLDFormat* %498, i32 0, i32 7 ; [#uses=1] + %500 = load i32* %499, align 4 ; [#uses=1] + %501 = icmp eq i32 %500, 33639 ; [#uses=1] + %502 = zext i1 %501 to i8 ; [#uses=1] + store i8 %502, i8* %iftmp.164, align 1 + br label %bb108 + +bb107: ; preds = %bb105 + %503 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %504 = getelementptr inbounds %struct.GLDContextRec* %503, i32 0, i32 56 ; <%struct.GLDFormat*> [#uses=1] + %505 = getelementptr inbounds %struct.GLDFormat* %504, i32 0, i32 7 ; [#uses=1] + %506 = load i32* %505, align 4 ; [#uses=1] + %507 = icmp eq i32 %506, 33639 ; [#uses=1] + %508 = zext i1 %507 to i8 ; [#uses=1] + store i8 %508, i8* %iftmp.164, align 1 + br label %bb108 + +bb108: ; preds = %bb107, %bb106 + %509 = load i8* %iftmp.164, align 1 ; [#uses=1] + %toBool109 = icmp ne i8 %509, 0 ; [#uses=1] + br i1 %toBool109, label %bb110, label %bb229 + +bb110: ; preds = %bb108 + %510 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %511 = getelementptr inbounds %struct.GLDContextRec* %510, i32 0, i32 7 ; [#uses=1] + %512 = load float* %511, align 4 ; [#uses=1] + store float %512, float* %twoFiftyFive, align 4 + %513 = load i32* %offset, align 4 ; [#uses=1] + store i32 %513, i32* %start_offset112, align 4 + store i32 0, i32* %draw_buffer, align 4 + br label %bb227 + +bb113: ; preds = %bb227 + %514 = load i32* %start_offset112, align 4 ; [#uses=1] + store i32 %514, i32* %offset, align 4 + %515 = load i32* %draw_buffer, align 4 ; [#uses=1] + %516 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %517 = getelementptr inbounds %struct.GLDContextRec* %516, i32 0, i32 30 ; <%struct.GLDBufferstate*> [#uses=1] + %518 = getelementptr inbounds %struct.GLDBufferstate* %517, i32 0, i32 12 ; <[8 x %union.GLSBuffer]*> [#uses=1] + %519 = getelementptr inbounds [8 x %union.GLSBuffer]* %518, i32 0, i32 %515 ; <%union.GLSBuffer*> [#uses=1] + %520 = getelementptr inbounds %union.GLSBuffer* %519, i32 0, i32 0 ; [#uses=1] + %521 = load i8** %520, align 4 ; [#uses=1] + %522 = icmp ne i8* %521, null ; [#uses=1] + br i1 %522, label %bb114, label %bb226 + +bb114: ; preds = %bb113 + %523 = load i32* %draw_buffer, align 4 ; [#uses=1] + %524 = shl i32 1, %523 ; [#uses=1] + store i32 %524, i32* %cur_draw_buffer_mask_bit115, align 4 + %525 = load i32* %cy, align 4 ; [#uses=1] + store i32 %525, i32* %y, align 4 + br label %bb225 + +bb116: ; preds = %bb225 + %526 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %527 = getelementptr inbounds %struct.GLDContextRec* %526, i32 0, i32 30 ; <%struct.GLDBufferstate*> [#uses=1] + %528 = getelementptr inbounds %struct.GLDBufferstate* %527, i32 0, i32 11 ; <%union.GLSBuffer*> [#uses=1] + %529 = getelementptr inbounds %union.GLSBuffer* %528, i32 0, i32 0 ; [#uses=1] + %530 = bitcast i8** %529 to double** ; [#uses=1] + %531 = load double** %530, align 4 ; [#uses=1] + %532 = load i32* %offset, align 4 ; [#uses=1] + %533 = mul i32 %532, 4 ; [#uses=1] + %534 = getelementptr inbounds double* %531, i32 %533 ; [#uses=1] + store double* %534, double** %accum, align 4 + %535 = load double** %accum, align 4 ; [#uses=1] + %536 = load i32* %cw4, align 4 ; [#uses=1] + %537 = getelementptr inbounds double* %535, i32 %536 ; [#uses=1] + store double* %537, double** %accum_end, align 4 + %538 = load i32* %draw_buffer, align 4 ; [#uses=1] + %539 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %540 = getelementptr inbounds %struct.GLDContextRec* %539, i32 0, i32 30 ; <%struct.GLDBufferstate*> [#uses=1] + %541 = getelementptr inbounds %struct.GLDBufferstate* %540, i32 0, i32 12 ; <[8 x %union.GLSBuffer]*> [#uses=1] + %542 = getelementptr inbounds [8 x %union.GLSBuffer]* %541, i32 0, i32 %538 ; <%union.GLSBuffer*> [#uses=1] + %543 = getelementptr inbounds %union.GLSBuffer* %542, i32 0, i32 0 ; [#uses=1] + %544 = bitcast i8** %543 to i32** ; [#uses=1] + %545 = load i32** %544, align 4 ; [#uses=1] + %546 = load i32* %offset, align 4 ; [#uses=1] + %547 = getelementptr inbounds i32* %545, i32 %546 ; [#uses=1] + %548 = bitcast i32* %547 to i8* ; [#uses=1] + store i8* %548, i8** %color_ptr111, align 4 + %549 = load i8* %color_mask_enabled, align 1 ; [#uses=1] + %550 = icmp ne i8 %549, 0 ; [#uses=1] + br i1 %550, label %bb117, label %bb191 + +bb117: ; preds = %bb116 + br label %bb189 + +bb118: ; preds = %bb189 + %551 = load double** %accum, align 4 ; [#uses=1] + %552 = getelementptr inbounds double* %551, i32 0 ; [#uses=1] + %553 = load double* %552, align 1 ; [#uses=1] + %554 = fptrunc double %553 to float ; [#uses=1] + %555 = load float* %value_addr, align 4 ; [#uses=1] + %556 = fmul float %554, %555 ; [#uses=1] + %557 = load float* %twoFiftyFive, align 4 ; [#uses=1] + %558 = fmul float %556, %557 ; [#uses=1] + %559 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %560 = getelementptr inbounds %struct.GLDContextRec* %559, i32 0, i32 1 ; [#uses=1] + %561 = load float* %560, align 4 ; [#uses=1] + %562 = fadd float %558, %561 ; [#uses=1] + store float %562, float* %r119, align 4 + %563 = load double** %accum, align 4 ; [#uses=1] + %564 = getelementptr inbounds double* %563, i32 1 ; [#uses=1] + %565 = load double* %564, align 1 ; [#uses=1] + %566 = fptrunc double %565 to float ; [#uses=1] + %567 = load float* %value_addr, align 4 ; [#uses=1] + %568 = fmul float %566, %567 ; [#uses=1] + %569 = load float* %twoFiftyFive, align 4 ; [#uses=1] + %570 = fmul float %568, %569 ; [#uses=1] + %571 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %572 = getelementptr inbounds %struct.GLDContextRec* %571, i32 0, i32 1 ; [#uses=1] + %573 = load float* %572, align 4 ; [#uses=1] + %574 = fadd float %570, %573 ; [#uses=1] + store float %574, float* %g120, align 4 + %575 = load double** %accum, align 4 ; [#uses=1] + %576 = getelementptr inbounds double* %575, i32 2 ; [#uses=1] + %577 = load double* %576, align 1 ; [#uses=1] + %578 = fptrunc double %577 to float ; [#uses=1] + %579 = load float* %value_addr, align 4 ; [#uses=1] + %580 = fmul float %578, %579 ; [#uses=1] + %581 = load float* %twoFiftyFive, align 4 ; [#uses=1] + %582 = fmul float %580, %581 ; [#uses=1] + %583 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %584 = getelementptr inbounds %struct.GLDContextRec* %583, i32 0, i32 1 ; [#uses=1] + %585 = load float* %584, align 4 ; [#uses=1] + %586 = fadd float %582, %585 ; [#uses=1] + store float %586, float* %b121, align 4 + %587 = load double** %accum, align 4 ; [#uses=1] + %588 = getelementptr inbounds double* %587, i32 3 ; [#uses=1] + %589 = load double* %588, align 1 ; [#uses=1] + %590 = fptrunc double %589 to float ; [#uses=1] + %591 = load float* %value_addr, align 4 ; [#uses=1] + %592 = fmul float %590, %591 ; [#uses=1] + %593 = load float* %twoFiftyFive, align 4 ; [#uses=1] + %594 = fmul float %592, %593 ; [#uses=1] + %595 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %596 = getelementptr inbounds %struct.GLDContextRec* %595, i32 0, i32 1 ; [#uses=1] + %597 = load float* %596, align 4 ; [#uses=1] + %598 = fadd float %594, %597 ; [#uses=1] + store float %598, float* %a122, align 4 + %599 = load i8* %swap, align 1 ; [#uses=1] + %600 = icmp ne i8 %599, 0 ; [#uses=1] + br i1 %600, label %bb123, label %bb156 + +bb123: ; preds = %bb118 + %601 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] + %602 = getelementptr inbounds %struct.GLDState* %601, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] + %603 = getelementptr inbounds %struct.GLDMaskMode* %602, i32 0, i32 5 ; [#uses=1] + %604 = load i8* %603, align 1 ; [#uses=1] + %605 = zext i8 %604 to i32 ; [#uses=1] + %606 = load i32* %cur_draw_buffer_mask_bit115, align 4 ; [#uses=1] + %607 = and i32 %605, %606 ; [#uses=1] + %608 = icmp ne i32 %607, 0 ; [#uses=1] + br i1 %608, label %bb124, label %bb131 + +bb124: ; preds = %bb123 + %609 = load float* %a122, align 4 ; [#uses=1] + %610 = fcmp uge float %609, 0.000000e+00 ; [#uses=1] + br i1 %610, label %bb125, label %bb129 + +bb125: ; preds = %bb124 + %611 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %612 = getelementptr inbounds %struct.GLDContextRec* %611, i32 0, i32 7 ; [#uses=1] + %613 = load float* %612, align 4 ; [#uses=1] + %614 = load float* %a122, align 4 ; [#uses=1] + %615 = fcmp olt float %613, %614 ; [#uses=1] + br i1 %615, label %bb126, label %bb127 + +bb126: ; preds = %bb125 + %616 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %617 = getelementptr inbounds %struct.GLDContextRec* %616, i32 0, i32 7 ; [#uses=1] + %618 = load float* %617, align 4 ; [#uses=1] + %619 = fptoui float %618 to i8 ; [#uses=1] + store i8 %619, i8* %iftmp.168, align 1 + br label %bb128 + +bb127: ; preds = %bb125 + %620 = load float* %a122, align 4 ; [#uses=1] + %621 = fptoui float %620 to i8 ; [#uses=1] + store i8 %621, i8* %iftmp.168, align 1 + br label %bb128 + +bb128: ; preds = %bb127, %bb126 + %622 = load i8* %iftmp.168, align 1 ; [#uses=1] + store i8 %622, i8* %iftmp.167, align 1 + br label %bb130 + +bb129: ; preds = %bb124 + store i8 0, i8* %iftmp.167, align 1 + br label %bb130 + +bb130: ; preds = %bb129, %bb128 + %623 = load i8** %color_ptr111, align 4 ; [#uses=1] + %624 = getelementptr inbounds i8* %623, i32 0 ; [#uses=1] + %625 = load i8* %iftmp.167, align 1 ; [#uses=1] + store i8 %625, i8* %624, align 1 + br label %bb131 + +bb131: ; preds = %bb130, %bb123 + %626 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] + %627 = getelementptr inbounds %struct.GLDState* %626, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] + %628 = getelementptr inbounds %struct.GLDMaskMode* %627, i32 0, i32 2 ; [#uses=1] + %629 = load i8* %628, align 16 ; [#uses=1] + %630 = zext i8 %629 to i32 ; [#uses=1] + %631 = load i32* %cur_draw_buffer_mask_bit115, align 4 ; [#uses=1] + %632 = and i32 %630, %631 ; [#uses=1] + %633 = icmp ne i32 %632, 0 ; [#uses=1] + br i1 %633, label %bb132, label %bb139 + +bb132: ; preds = %bb131 + %634 = load float* %r119, align 4 ; [#uses=1] + %635 = fcmp uge float %634, 0.000000e+00 ; [#uses=1] + br i1 %635, label %bb133, label %bb137 + +bb133: ; preds = %bb132 + %636 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %637 = getelementptr inbounds %struct.GLDContextRec* %636, i32 0, i32 7 ; [#uses=1] + %638 = load float* %637, align 4 ; [#uses=1] + %639 = load float* %r119, align 4 ; [#uses=1] + %640 = fcmp olt float %638, %639 ; [#uses=1] + br i1 %640, label %bb134, label %bb135 + +bb134: ; preds = %bb133 + %641 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %642 = getelementptr inbounds %struct.GLDContextRec* %641, i32 0, i32 7 ; [#uses=1] + %643 = load float* %642, align 4 ; [#uses=1] + %644 = fptoui float %643 to i8 ; [#uses=1] + store i8 %644, i8* %iftmp.170, align 1 + br label %bb136 + +bb135: ; preds = %bb133 + %645 = load float* %r119, align 4 ; [#uses=1] + %646 = fptoui float %645 to i8 ; [#uses=1] + store i8 %646, i8* %iftmp.170, align 1 + br label %bb136 + +bb136: ; preds = %bb135, %bb134 + %647 = load i8* %iftmp.170, align 1 ; [#uses=1] + store i8 %647, i8* %iftmp.169, align 1 + br label %bb138 + +bb137: ; preds = %bb132 + store i8 0, i8* %iftmp.169, align 1 + br label %bb138 + +bb138: ; preds = %bb137, %bb136 + %648 = load i8** %color_ptr111, align 4 ; [#uses=1] + %649 = getelementptr inbounds i8* %648, i32 1 ; [#uses=1] + %650 = load i8* %iftmp.169, align 1 ; [#uses=1] + store i8 %650, i8* %649, align 1 + br label %bb139 + +bb139: ; preds = %bb138, %bb131 + %651 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] + %652 = getelementptr inbounds %struct.GLDState* %651, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] + %653 = getelementptr inbounds %struct.GLDMaskMode* %652, i32 0, i32 3 ; [#uses=1] + %654 = load i8* %653, align 1 ; [#uses=1] + %655 = zext i8 %654 to i32 ; [#uses=1] + %656 = load i32* %cur_draw_buffer_mask_bit115, align 4 ; [#uses=1] + %657 = and i32 %655, %656 ; [#uses=1] + %658 = icmp ne i32 %657, 0 ; [#uses=1] + br i1 %658, label %bb140, label %bb147 + +bb140: ; preds = %bb139 + %659 = load float* %g120, align 4 ; [#uses=1] + %660 = fcmp uge float %659, 0.000000e+00 ; [#uses=1] + br i1 %660, label %bb141, label %bb145 + +bb141: ; preds = %bb140 + %661 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %662 = getelementptr inbounds %struct.GLDContextRec* %661, i32 0, i32 7 ; [#uses=1] + %663 = load float* %662, align 4 ; [#uses=1] + %664 = load float* %g120, align 4 ; [#uses=1] + %665 = fcmp olt float %663, %664 ; [#uses=1] + br i1 %665, label %bb142, label %bb143 + +bb142: ; preds = %bb141 + %666 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %667 = getelementptr inbounds %struct.GLDContextRec* %666, i32 0, i32 7 ; [#uses=1] + %668 = load float* %667, align 4 ; [#uses=1] + %669 = fptoui float %668 to i8 ; [#uses=1] + store i8 %669, i8* %iftmp.172, align 1 + br label %bb144 + +bb143: ; preds = %bb141 + %670 = load float* %g120, align 4 ; [#uses=1] + %671 = fptoui float %670 to i8 ; [#uses=1] + store i8 %671, i8* %iftmp.172, align 1 + br label %bb144 + +bb144: ; preds = %bb143, %bb142 + %672 = load i8* %iftmp.172, align 1 ; [#uses=1] + store i8 %672, i8* %iftmp.171, align 1 + br label %bb146 + +bb145: ; preds = %bb140 + store i8 0, i8* %iftmp.171, align 1 + br label %bb146 + +bb146: ; preds = %bb145, %bb144 + %673 = load i8** %color_ptr111, align 4 ; [#uses=1] + %674 = getelementptr inbounds i8* %673, i32 2 ; [#uses=1] + %675 = load i8* %iftmp.171, align 1 ; [#uses=1] + store i8 %675, i8* %674, align 1 + br label %bb147 + +bb147: ; preds = %bb146, %bb139 + %676 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] + %677 = getelementptr inbounds %struct.GLDState* %676, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] + %678 = getelementptr inbounds %struct.GLDMaskMode* %677, i32 0, i32 4 ; [#uses=1] + %679 = load i8* %678, align 2 ; [#uses=1] + %680 = zext i8 %679 to i32 ; [#uses=1] + %681 = load i32* %cur_draw_buffer_mask_bit115, align 4 ; [#uses=1] + %682 = and i32 %680, %681 ; [#uses=1] + %683 = icmp ne i32 %682, 0 ; [#uses=1] + br i1 %683, label %bb148, label %bb155 + +bb148: ; preds = %bb147 + %684 = load float* %b121, align 4 ; [#uses=1] + %685 = fcmp uge float %684, 0.000000e+00 ; [#uses=1] + br i1 %685, label %bb149, label %bb153 + +bb149: ; preds = %bb148 + %686 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %687 = getelementptr inbounds %struct.GLDContextRec* %686, i32 0, i32 7 ; [#uses=1] + %688 = load float* %687, align 4 ; [#uses=1] + %689 = load float* %b121, align 4 ; [#uses=1] + %690 = fcmp olt float %688, %689 ; [#uses=1] + br i1 %690, label %bb150, label %bb151 + +bb150: ; preds = %bb149 + %691 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %692 = getelementptr inbounds %struct.GLDContextRec* %691, i32 0, i32 7 ; [#uses=1] + %693 = load float* %692, align 4 ; [#uses=1] + %694 = fptoui float %693 to i8 ; [#uses=1] + store i8 %694, i8* %iftmp.174, align 1 + br label %bb152 + +bb151: ; preds = %bb149 + %695 = load float* %b121, align 4 ; [#uses=1] + %696 = fptoui float %695 to i8 ; [#uses=1] + store i8 %696, i8* %iftmp.174, align 1 + br label %bb152 + +bb152: ; preds = %bb151, %bb150 + %697 = load i8* %iftmp.174, align 1 ; [#uses=1] + store i8 %697, i8* %iftmp.173, align 1 + br label %bb154 + +bb153: ; preds = %bb148 + store i8 0, i8* %iftmp.173, align 1 + br label %bb154 + +bb154: ; preds = %bb153, %bb152 + %698 = load i8** %color_ptr111, align 4 ; [#uses=1] + %699 = getelementptr inbounds i8* %698, i32 3 ; [#uses=1] + %700 = load i8* %iftmp.173, align 1 ; [#uses=1] + store i8 %700, i8* %699, align 1 + br label %bb155 + +bb155: ; preds = %bb154, %bb147 + br label %bb188 + +bb156: ; preds = %bb118 + %701 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] + %702 = getelementptr inbounds %struct.GLDState* %701, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] + %703 = getelementptr inbounds %struct.GLDMaskMode* %702, i32 0, i32 5 ; [#uses=1] + %704 = load i8* %703, align 1 ; [#uses=1] + %705 = zext i8 %704 to i32 ; [#uses=1] + %706 = load i32* %cur_draw_buffer_mask_bit115, align 4 ; [#uses=1] + %707 = and i32 %705, %706 ; [#uses=1] + %708 = icmp ne i32 %707, 0 ; [#uses=1] + br i1 %708, label %bb157, label %bb164 + +bb157: ; preds = %bb156 + %709 = load float* %a122, align 4 ; [#uses=1] + %710 = fcmp uge float %709, 0.000000e+00 ; [#uses=1] + br i1 %710, label %bb158, label %bb162 + +bb158: ; preds = %bb157 + %711 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %712 = getelementptr inbounds %struct.GLDContextRec* %711, i32 0, i32 7 ; [#uses=1] + %713 = load float* %712, align 4 ; [#uses=1] + %714 = load float* %a122, align 4 ; [#uses=1] + %715 = fcmp olt float %713, %714 ; [#uses=1] + br i1 %715, label %bb159, label %bb160 + +bb159: ; preds = %bb158 + %716 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %717 = getelementptr inbounds %struct.GLDContextRec* %716, i32 0, i32 7 ; [#uses=1] + %718 = load float* %717, align 4 ; [#uses=1] + %719 = fptoui float %718 to i8 ; [#uses=1] + store i8 %719, i8* %iftmp.176, align 1 + br label %bb161 + +bb160: ; preds = %bb158 + %720 = load float* %a122, align 4 ; [#uses=1] + %721 = fptoui float %720 to i8 ; [#uses=1] + store i8 %721, i8* %iftmp.176, align 1 + br label %bb161 + +bb161: ; preds = %bb160, %bb159 + %722 = load i8* %iftmp.176, align 1 ; [#uses=1] + store i8 %722, i8* %iftmp.175, align 1 + br label %bb163 + +bb162: ; preds = %bb157 + store i8 0, i8* %iftmp.175, align 1 + br label %bb163 + +bb163: ; preds = %bb162, %bb161 + %723 = load i8** %color_ptr111, align 4 ; [#uses=1] + %724 = getelementptr inbounds i8* %723, i32 3 ; [#uses=1] + %725 = load i8* %iftmp.175, align 1 ; [#uses=1] + store i8 %725, i8* %724, align 1 + br label %bb164 + +bb164: ; preds = %bb163, %bb156 + %726 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] + %727 = getelementptr inbounds %struct.GLDState* %726, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] + %728 = getelementptr inbounds %struct.GLDMaskMode* %727, i32 0, i32 2 ; [#uses=1] + %729 = load i8* %728, align 16 ; [#uses=1] + %730 = zext i8 %729 to i32 ; [#uses=1] + %731 = load i32* %cur_draw_buffer_mask_bit115, align 4 ; [#uses=1] + %732 = and i32 %730, %731 ; [#uses=1] + %733 = icmp ne i32 %732, 0 ; [#uses=1] + br i1 %733, label %bb165, label %bb172 + +bb165: ; preds = %bb164 + %734 = load float* %r119, align 4 ; [#uses=1] + %735 = fcmp uge float %734, 0.000000e+00 ; [#uses=1] + br i1 %735, label %bb166, label %bb170 + +bb166: ; preds = %bb165 + %736 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %737 = getelementptr inbounds %struct.GLDContextRec* %736, i32 0, i32 7 ; [#uses=1] + %738 = load float* %737, align 4 ; [#uses=1] + %739 = load float* %r119, align 4 ; [#uses=1] + %740 = fcmp olt float %738, %739 ; [#uses=1] + br i1 %740, label %bb167, label %bb168 + +bb167: ; preds = %bb166 + %741 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %742 = getelementptr inbounds %struct.GLDContextRec* %741, i32 0, i32 7 ; [#uses=1] + %743 = load float* %742, align 4 ; [#uses=1] + %744 = fptoui float %743 to i8 ; [#uses=1] + store i8 %744, i8* %iftmp.178, align 1 + br label %bb169 + +bb168: ; preds = %bb166 + %745 = load float* %r119, align 4 ; [#uses=1] + %746 = fptoui float %745 to i8 ; [#uses=1] + store i8 %746, i8* %iftmp.178, align 1 + br label %bb169 + +bb169: ; preds = %bb168, %bb167 + %747 = load i8* %iftmp.178, align 1 ; [#uses=1] + store i8 %747, i8* %iftmp.177, align 1 + br label %bb171 + +bb170: ; preds = %bb165 + store i8 0, i8* %iftmp.177, align 1 + br label %bb171 + +bb171: ; preds = %bb170, %bb169 + %748 = load i8** %color_ptr111, align 4 ; [#uses=1] + %749 = getelementptr inbounds i8* %748, i32 2 ; [#uses=1] + %750 = load i8* %iftmp.177, align 1 ; [#uses=1] + store i8 %750, i8* %749, align 1 + br label %bb172 + +bb172: ; preds = %bb171, %bb164 + %751 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] + %752 = getelementptr inbounds %struct.GLDState* %751, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] + %753 = getelementptr inbounds %struct.GLDMaskMode* %752, i32 0, i32 3 ; [#uses=1] + %754 = load i8* %753, align 1 ; [#uses=1] + %755 = zext i8 %754 to i32 ; [#uses=1] + %756 = load i32* %cur_draw_buffer_mask_bit115, align 4 ; [#uses=1] + %757 = and i32 %755, %756 ; [#uses=1] + %758 = icmp ne i32 %757, 0 ; [#uses=1] + br i1 %758, label %bb173, label %bb180 + +bb173: ; preds = %bb172 + %759 = load float* %g120, align 4 ; [#uses=1] + %760 = fcmp uge float %759, 0.000000e+00 ; [#uses=1] + br i1 %760, label %bb174, label %bb178 + +bb174: ; preds = %bb173 + %761 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %762 = getelementptr inbounds %struct.GLDContextRec* %761, i32 0, i32 7 ; [#uses=1] + %763 = load float* %762, align 4 ; [#uses=1] + %764 = load float* %g120, align 4 ; [#uses=1] + %765 = fcmp olt float %763, %764 ; [#uses=1] + br i1 %765, label %bb175, label %bb176 + +bb175: ; preds = %bb174 + %766 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %767 = getelementptr inbounds %struct.GLDContextRec* %766, i32 0, i32 7 ; [#uses=1] + %768 = load float* %767, align 4 ; [#uses=1] + %769 = fptoui float %768 to i8 ; [#uses=1] + store i8 %769, i8* %iftmp.180, align 1 + br label %bb177 + +bb176: ; preds = %bb174 + %770 = load float* %g120, align 4 ; [#uses=1] + %771 = fptoui float %770 to i8 ; [#uses=1] + store i8 %771, i8* %iftmp.180, align 1 + br label %bb177 + +bb177: ; preds = %bb176, %bb175 + %772 = load i8* %iftmp.180, align 1 ; [#uses=1] + store i8 %772, i8* %iftmp.179, align 1 + br label %bb179 + +bb178: ; preds = %bb173 + store i8 0, i8* %iftmp.179, align 1 + br label %bb179 + +bb179: ; preds = %bb178, %bb177 + %773 = load i8** %color_ptr111, align 4 ; [#uses=1] + %774 = getelementptr inbounds i8* %773, i32 1 ; [#uses=1] + %775 = load i8* %iftmp.179, align 1 ; [#uses=1] + store i8 %775, i8* %774, align 1 + br label %bb180 + +bb180: ; preds = %bb179, %bb172 + %776 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] + %777 = getelementptr inbounds %struct.GLDState* %776, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] + %778 = getelementptr inbounds %struct.GLDMaskMode* %777, i32 0, i32 4 ; [#uses=1] + %779 = load i8* %778, align 2 ; [#uses=1] + %780 = zext i8 %779 to i32 ; [#uses=1] + %781 = load i32* %cur_draw_buffer_mask_bit115, align 4 ; [#uses=1] + %782 = and i32 %780, %781 ; [#uses=1] + %783 = icmp ne i32 %782, 0 ; [#uses=1] + br i1 %783, label %bb181, label %bb188 + +bb181: ; preds = %bb180 + %784 = load float* %b121, align 4 ; [#uses=1] + %785 = fcmp uge float %784, 0.000000e+00 ; [#uses=1] + br i1 %785, label %bb182, label %bb186 + +bb182: ; preds = %bb181 + %786 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %787 = getelementptr inbounds %struct.GLDContextRec* %786, i32 0, i32 7 ; [#uses=1] + %788 = load float* %787, align 4 ; [#uses=1] + %789 = load float* %b121, align 4 ; [#uses=1] + %790 = fcmp olt float %788, %789 ; [#uses=1] + br i1 %790, label %bb183, label %bb184 + +bb183: ; preds = %bb182 + %791 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %792 = getelementptr inbounds %struct.GLDContextRec* %791, i32 0, i32 7 ; [#uses=1] + %793 = load float* %792, align 4 ; [#uses=1] + %794 = fptoui float %793 to i8 ; [#uses=1] + store i8 %794, i8* %iftmp.182, align 1 + br label %bb185 + +bb184: ; preds = %bb182 + %795 = load float* %b121, align 4 ; [#uses=1] + %796 = fptoui float %795 to i8 ; [#uses=1] + store i8 %796, i8* %iftmp.182, align 1 + br label %bb185 + +bb185: ; preds = %bb184, %bb183 + %797 = load i8* %iftmp.182, align 1 ; [#uses=1] + store i8 %797, i8* %iftmp.181, align 1 + br label %bb187 + +bb186: ; preds = %bb181 + store i8 0, i8* %iftmp.181, align 1 + br label %bb187 + +bb187: ; preds = %bb186, %bb185 + %798 = load i8** %color_ptr111, align 4 ; [#uses=1] + %799 = getelementptr inbounds i8* %798, i32 0 ; [#uses=1] + %800 = load i8* %iftmp.181, align 1 ; [#uses=1] + store i8 %800, i8* %799, align 1 + br label %bb188 + +bb188: ; preds = %bb187, %bb180, %bb155 + %801 = load double** %accum, align 4 ; [#uses=1] + %802 = getelementptr inbounds double* %801, i32 4 ; [#uses=1] + store double* %802, double** %accum, align 4 + %803 = load i8** %color_ptr111, align 4 ; [#uses=1] + %804 = getelementptr inbounds i8* %803, i32 4 ; [#uses=1] + store i8* %804, i8** %color_ptr111, align 4 + br label %bb189 + +bb189: ; preds = %bb188, %bb117 + %805 = load double** %accum, align 4 ; [#uses=1] + %806 = load double** %accum_end, align 4 ; [#uses=1] + %807 = icmp ult double* %805, %806 ; [#uses=1] + br i1 %807, label %bb118, label %bb190 + +bb190: ; preds = %bb189 + br label %bb224 + +bb191: ; preds = %bb116 + br label %bb223 + +bb192: ; preds = %bb223 + %808 = load double** %accum, align 4 ; [#uses=1] + %809 = getelementptr inbounds double* %808, i32 0 ; [#uses=1] + %810 = load double* %809, align 1 ; [#uses=1] + %811 = fptrunc double %810 to float ; [#uses=1] + %812 = load float* %value_addr, align 4 ; [#uses=1] + %813 = fmul float %811, %812 ; [#uses=1] + %814 = load float* %twoFiftyFive, align 4 ; [#uses=1] + %815 = fmul float %813, %814 ; [#uses=1] + %816 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %817 = getelementptr inbounds %struct.GLDContextRec* %816, i32 0, i32 1 ; [#uses=1] + %818 = load float* %817, align 4 ; [#uses=1] + %819 = fadd float %815, %818 ; [#uses=1] + %820 = fcmp uge float %819, 0.000000e+00 ; [#uses=1] + br i1 %820, label %bb197, label %bb201 + +bb197: ; preds = %bb192 + %821 = load double** %accum, align 4 ; [#uses=1] + %822 = getelementptr inbounds double* %821, i32 0 ; [#uses=1] + %823 = load double* %822, align 1 ; [#uses=1] + %824 = fptrunc double %823 to float ; [#uses=1] + %825 = load float* %value_addr, align 4 ; [#uses=1] + %826 = fmul float %824, %825 ; [#uses=1] + %827 = load float* %twoFiftyFive, align 4 ; [#uses=1] + %828 = fmul float %826, %827 ; [#uses=1] + %829 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %830 = getelementptr inbounds %struct.GLDContextRec* %829, i32 0, i32 1 ; [#uses=1] + %831 = load float* %830, align 4 ; [#uses=1] + %832 = fadd float %828, %831 ; [#uses=1] + %833 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %834 = getelementptr inbounds %struct.GLDContextRec* %833, i32 0, i32 7 ; [#uses=1] + %835 = load float* %834, align 4 ; [#uses=1] + %836 = fcmp ogt float %832, %835 ; [#uses=1] + br i1 %836, label %bb198, label %bb199 + +bb198: ; preds = %bb197 + %837 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %838 = getelementptr inbounds %struct.GLDContextRec* %837, i32 0, i32 7 ; [#uses=1] + %839 = load float* %838, align 4 ; [#uses=1] + %840 = fptoui float %839 to i8 ; [#uses=1] + %841 = zext i8 %840 to i32 ; [#uses=1] + store i32 %841, i32* %iftmp.184, align 4 + br label %bb200 + +bb199: ; preds = %bb197 + %842 = load double** %accum, align 4 ; [#uses=1] + %843 = getelementptr inbounds double* %842, i32 0 ; [#uses=1] + %844 = load double* %843, align 1 ; [#uses=1] + %845 = fptrunc double %844 to float ; [#uses=1] + %846 = load float* %value_addr, align 4 ; [#uses=1] + %847 = fmul float %845, %846 ; [#uses=1] + %848 = load float* %twoFiftyFive, align 4 ; [#uses=1] + %849 = fmul float %847, %848 ; [#uses=1] + %850 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %851 = getelementptr inbounds %struct.GLDContextRec* %850, i32 0, i32 1 ; [#uses=1] + %852 = load float* %851, align 4 ; [#uses=1] + %853 = fadd float %849, %852 ; [#uses=1] + %854 = fptoui float %853 to i8 ; [#uses=1] + %855 = zext i8 %854 to i32 ; [#uses=1] + store i32 %855, i32* %iftmp.184, align 4 + br label %bb200 + +bb200: ; preds = %bb199, %bb198 + %856 = load i32* %iftmp.184, align 4 ; [#uses=1] + store i32 %856, i32* %iftmp.183, align 4 + br label %bb202 + +bb201: ; preds = %bb192 + store i32 0, i32* %iftmp.183, align 4 + br label %bb202 + +bb202: ; preds = %bb201, %bb200 + %857 = load i32* %iftmp.183, align 4 ; [#uses=1] + store i32 %857, i32* %r193, align 4 + %858 = load double** %accum, align 4 ; [#uses=1] + %859 = getelementptr inbounds double* %858, i32 1 ; [#uses=1] + %860 = load double* %859, align 1 ; [#uses=1] + %861 = fptrunc double %860 to float ; [#uses=1] + %862 = load float* %value_addr, align 4 ; [#uses=1] + %863 = fmul float %861, %862 ; [#uses=1] + %864 = load float* %twoFiftyFive, align 4 ; [#uses=1] + %865 = fmul float %863, %864 ; [#uses=1] + %866 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %867 = getelementptr inbounds %struct.GLDContextRec* %866, i32 0, i32 1 ; [#uses=1] + %868 = load float* %867, align 4 ; [#uses=1] + %869 = fadd float %865, %868 ; [#uses=1] + %870 = fcmp uge float %869, 0.000000e+00 ; [#uses=1] + br i1 %870, label %bb203, label %bb207 + +bb203: ; preds = %bb202 + %871 = load double** %accum, align 4 ; [#uses=1] + %872 = getelementptr inbounds double* %871, i32 1 ; [#uses=1] + %873 = load double* %872, align 1 ; [#uses=1] + %874 = fptrunc double %873 to float ; [#uses=1] + %875 = load float* %value_addr, align 4 ; [#uses=1] + %876 = fmul float %874, %875 ; [#uses=1] + %877 = load float* %twoFiftyFive, align 4 ; [#uses=1] + %878 = fmul float %876, %877 ; [#uses=1] + %879 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %880 = getelementptr inbounds %struct.GLDContextRec* %879, i32 0, i32 1 ; [#uses=1] + %881 = load float* %880, align 4 ; [#uses=1] + %882 = fadd float %878, %881 ; [#uses=1] + %883 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %884 = getelementptr inbounds %struct.GLDContextRec* %883, i32 0, i32 7 ; [#uses=1] + %885 = load float* %884, align 4 ; [#uses=1] + %886 = fcmp ogt float %882, %885 ; [#uses=1] + br i1 %886, label %bb204, label %bb205 + +bb204: ; preds = %bb203 + %887 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %888 = getelementptr inbounds %struct.GLDContextRec* %887, i32 0, i32 7 ; [#uses=1] + %889 = load float* %888, align 4 ; [#uses=1] + %890 = fptoui float %889 to i8 ; [#uses=1] + %891 = zext i8 %890 to i32 ; [#uses=1] + store i32 %891, i32* %iftmp.186, align 4 + br label %bb206 + +bb205: ; preds = %bb203 + %892 = load double** %accum, align 4 ; [#uses=1] + %893 = getelementptr inbounds double* %892, i32 1 ; [#uses=1] + %894 = load double* %893, align 1 ; [#uses=1] + %895 = fptrunc double %894 to float ; [#uses=1] + %896 = load float* %value_addr, align 4 ; [#uses=1] + %897 = fmul float %895, %896 ; [#uses=1] + %898 = load float* %twoFiftyFive, align 4 ; [#uses=1] + %899 = fmul float %897, %898 ; [#uses=1] + %900 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %901 = getelementptr inbounds %struct.GLDContextRec* %900, i32 0, i32 1 ; [#uses=1] + %902 = load float* %901, align 4 ; [#uses=1] + %903 = fadd float %899, %902 ; [#uses=1] + %904 = fptoui float %903 to i8 ; [#uses=1] + %905 = zext i8 %904 to i32 ; [#uses=1] + store i32 %905, i32* %iftmp.186, align 4 + br label %bb206 + +bb206: ; preds = %bb205, %bb204 + %906 = load i32* %iftmp.186, align 4 ; [#uses=1] + store i32 %906, i32* %iftmp.185, align 4 + br label %bb208 + +bb207: ; preds = %bb202 + store i32 0, i32* %iftmp.185, align 4 + br label %bb208 + +bb208: ; preds = %bb207, %bb206 + %907 = load i32* %iftmp.185, align 4 ; [#uses=1] + store i32 %907, i32* %g194, align 4 + %908 = load double** %accum, align 4 ; [#uses=1] + %909 = getelementptr inbounds double* %908, i32 2 ; [#uses=1] + %910 = load double* %909, align 1 ; [#uses=1] + %911 = fptrunc double %910 to float ; [#uses=1] + %912 = load float* %value_addr, align 4 ; [#uses=1] + %913 = fmul float %911, %912 ; [#uses=1] + %914 = load float* %twoFiftyFive, align 4 ; [#uses=1] + %915 = fmul float %913, %914 ; [#uses=1] + %916 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %917 = getelementptr inbounds %struct.GLDContextRec* %916, i32 0, i32 1 ; [#uses=1] + %918 = load float* %917, align 4 ; [#uses=1] + %919 = fadd float %915, %918 ; [#uses=1] + %920 = fcmp uge float %919, 0.000000e+00 ; [#uses=1] + br i1 %920, label %bb209, label %bb213 + +bb209: ; preds = %bb208 + %921 = load double** %accum, align 4 ; [#uses=1] + %922 = getelementptr inbounds double* %921, i32 2 ; [#uses=1] + %923 = load double* %922, align 1 ; [#uses=1] + %924 = fptrunc double %923 to float ; [#uses=1] + %925 = load float* %value_addr, align 4 ; [#uses=1] + %926 = fmul float %924, %925 ; [#uses=1] + %927 = load float* %twoFiftyFive, align 4 ; [#uses=1] + %928 = fmul float %926, %927 ; [#uses=1] + %929 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %930 = getelementptr inbounds %struct.GLDContextRec* %929, i32 0, i32 1 ; [#uses=1] + %931 = load float* %930, align 4 ; [#uses=1] + %932 = fadd float %928, %931 ; [#uses=1] + %933 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %934 = getelementptr inbounds %struct.GLDContextRec* %933, i32 0, i32 7 ; [#uses=1] + %935 = load float* %934, align 4 ; [#uses=1] + %936 = fcmp ogt float %932, %935 ; [#uses=1] + br i1 %936, label %bb210, label %bb211 + +bb210: ; preds = %bb209 + %937 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %938 = getelementptr inbounds %struct.GLDContextRec* %937, i32 0, i32 7 ; [#uses=1] + %939 = load float* %938, align 4 ; [#uses=1] + %940 = fptoui float %939 to i8 ; [#uses=1] + %941 = zext i8 %940 to i32 ; [#uses=1] + store i32 %941, i32* %iftmp.188, align 4 + br label %bb212 + +bb211: ; preds = %bb209 + %942 = load double** %accum, align 4 ; [#uses=1] + %943 = getelementptr inbounds double* %942, i32 2 ; [#uses=1] + %944 = load double* %943, align 1 ; [#uses=1] + %945 = fptrunc double %944 to float ; [#uses=1] + %946 = load float* %value_addr, align 4 ; [#uses=1] + %947 = fmul float %945, %946 ; [#uses=1] + %948 = load float* %twoFiftyFive, align 4 ; [#uses=1] + %949 = fmul float %947, %948 ; [#uses=1] + %950 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %951 = getelementptr inbounds %struct.GLDContextRec* %950, i32 0, i32 1 ; [#uses=1] + %952 = load float* %951, align 4 ; [#uses=1] + %953 = fadd float %949, %952 ; [#uses=1] + %954 = fptoui float %953 to i8 ; [#uses=1] + %955 = zext i8 %954 to i32 ; [#uses=1] + store i32 %955, i32* %iftmp.188, align 4 + br label %bb212 + +bb212: ; preds = %bb211, %bb210 + %956 = load i32* %iftmp.188, align 4 ; [#uses=1] + store i32 %956, i32* %iftmp.187, align 4 + br label %bb214 + +bb213: ; preds = %bb208 + store i32 0, i32* %iftmp.187, align 4 + br label %bb214 + +bb214: ; preds = %bb213, %bb212 + %957 = load i32* %iftmp.187, align 4 ; [#uses=1] + store i32 %957, i32* %b195, align 4 + %958 = load double** %accum, align 4 ; [#uses=1] + %959 = getelementptr inbounds double* %958, i32 3 ; [#uses=1] + %960 = load double* %959, align 1 ; [#uses=1] + %961 = fptrunc double %960 to float ; [#uses=1] + %962 = load float* %value_addr, align 4 ; [#uses=1] + %963 = fmul float %961, %962 ; [#uses=1] + %964 = load float* %twoFiftyFive, align 4 ; [#uses=1] + %965 = fmul float %963, %964 ; [#uses=1] + %966 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %967 = getelementptr inbounds %struct.GLDContextRec* %966, i32 0, i32 1 ; [#uses=1] + %968 = load float* %967, align 4 ; [#uses=1] + %969 = fadd float %965, %968 ; [#uses=1] + %970 = fcmp uge float %969, 0.000000e+00 ; [#uses=1] + br i1 %970, label %bb215, label %bb219 + +bb215: ; preds = %bb214 + %971 = load double** %accum, align 4 ; [#uses=1] + %972 = getelementptr inbounds double* %971, i32 3 ; [#uses=1] + %973 = load double* %972, align 1 ; [#uses=1] + %974 = fptrunc double %973 to float ; [#uses=1] + %975 = load float* %value_addr, align 4 ; [#uses=1] + %976 = fmul float %974, %975 ; [#uses=1] + %977 = load float* %twoFiftyFive, align 4 ; [#uses=1] + %978 = fmul float %976, %977 ; [#uses=1] + %979 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %980 = getelementptr inbounds %struct.GLDContextRec* %979, i32 0, i32 1 ; [#uses=1] + %981 = load float* %980, align 4 ; [#uses=1] + %982 = fadd float %978, %981 ; [#uses=1] + %983 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %984 = getelementptr inbounds %struct.GLDContextRec* %983, i32 0, i32 7 ; [#uses=1] + %985 = load float* %984, align 4 ; [#uses=1] + %986 = fcmp ogt float %982, %985 ; [#uses=1] + br i1 %986, label %bb216, label %bb217 + +bb216: ; preds = %bb215 + %987 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %988 = getelementptr inbounds %struct.GLDContextRec* %987, i32 0, i32 7 ; [#uses=1] + %989 = load float* %988, align 4 ; [#uses=1] + %990 = fptoui float %989 to i8 ; [#uses=1] + %991 = zext i8 %990 to i32 ; [#uses=1] + store i32 %991, i32* %iftmp.190, align 4 + br label %bb218 + +bb217: ; preds = %bb215 + %992 = load double** %accum, align 4 ; [#uses=1] + %993 = getelementptr inbounds double* %992, i32 3 ; [#uses=1] + %994 = load double* %993, align 1 ; [#uses=1] + %995 = fptrunc double %994 to float ; [#uses=1] + %996 = load float* %value_addr, align 4 ; [#uses=1] + %997 = fmul float %995, %996 ; [#uses=1] + %998 = load float* %twoFiftyFive, align 4 ; [#uses=1] + %999 = fmul float %997, %998 ; [#uses=1] + %1000 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %1001 = getelementptr inbounds %struct.GLDContextRec* %1000, i32 0, i32 1 ; [#uses=1] + %1002 = load float* %1001, align 4 ; [#uses=1] + %1003 = fadd float %999, %1002 ; [#uses=1] + %1004 = fptoui float %1003 to i8 ; [#uses=1] + %1005 = zext i8 %1004 to i32 ; [#uses=1] + store i32 %1005, i32* %iftmp.190, align 4 + br label %bb218 + +bb218: ; preds = %bb217, %bb216 + %1006 = load i32* %iftmp.190, align 4 ; [#uses=1] + store i32 %1006, i32* %iftmp.189, align 4 + br label %bb220 + +bb219: ; preds = %bb214 + store i32 0, i32* %iftmp.189, align 4 + br label %bb220 + +bb220: ; preds = %bb219, %bb218 + %1007 = load i32* %iftmp.189, align 4 ; [#uses=1] + store i32 %1007, i32* %a196, align 4 + %1008 = load i32* %a196, align 4 ; [#uses=1] + %1009 = shl i32 %1008, 24 ; [#uses=1] + %1010 = load i32* %r193, align 4 ; [#uses=1] + %1011 = shl i32 %1010, 16 ; [#uses=1] + %1012 = or i32 %1009, %1011 ; [#uses=1] + %1013 = load i32* %g194, align 4 ; [#uses=1] + %1014 = shl i32 %1013, 8 ; [#uses=1] + %1015 = or i32 %1012, %1014 ; [#uses=1] + %1016 = load i32* %b195, align 4 ; [#uses=1] + %1017 = or i32 %1015, %1016 ; [#uses=1] + store i32 %1017, i32* %color, align 4 + %1018 = load i8* %swap, align 1 ; [#uses=1] + %1019 = icmp ne i8 %1018, 0 ; [#uses=1] + br i1 %1019, label %bb221, label %bb222 + +bb221: ; preds = %bb220 + %1020 = load i32* %color, align 4 ; [#uses=1] + %1021 = call i32 @_OSSwapInt32(i32 %1020) nounwind inlinehint ssp ; [#uses=1] + store i32 %1021, i32* %color, align 4 + br label %bb222 + +bb222: ; preds = %bb221, %bb220 + %1022 = load i8** %color_ptr111, align 4 ; [#uses=1] + %1023 = bitcast i8* %1022 to i32* ; [#uses=1] + %1024 = getelementptr inbounds i32* %1023, i32 0 ; [#uses=1] + %1025 = load i32* %color, align 4 ; [#uses=1] + store i32 %1025, i32* %1024, align 1 + %1026 = load double** %accum, align 4 ; [#uses=1] + %1027 = getelementptr inbounds double* %1026, i32 4 ; [#uses=1] + store double* %1027, double** %accum, align 4 + %1028 = load i8** %color_ptr111, align 4 ; [#uses=1] + %1029 = getelementptr inbounds i8* %1028, i32 4 ; [#uses=1] + store i8* %1029, i8** %color_ptr111, align 4 + br label %bb223 + +bb223: ; preds = %bb222, %bb191 + %1030 = load double** %accum, align 4 ; [#uses=1] + %1031 = load double** %accum_end, align 4 ; [#uses=1] + %1032 = icmp ult double* %1030, %1031 ; [#uses=1] + br i1 %1032, label %bb192, label %bb224 + +bb224: ; preds = %bb223, %bb190 + %1033 = load i32* %y, align 4 ; [#uses=1] + %1034 = add i32 %1033, 1 ; [#uses=1] + store i32 %1034, i32* %y, align 4 + %1035 = load i32* %offset, align 4 ; [#uses=1] + %1036 = load i32* %y_inc, align 4 ; [#uses=1] + %1037 = add i32 %1035, %1036 ; [#uses=1] + store i32 %1037, i32* %offset, align 4 + br label %bb225 + +bb225: ; preds = %bb224, %bb114 + %1038 = load i32* %y, align 4 ; [#uses=1] + %1039 = load i32* %yl, align 4 ; [#uses=1] + %1040 = icmp ult i32 %1038, %1039 ; [#uses=1] + br i1 %1040, label %bb116, label %bb226 + +bb226: ; preds = %bb225, %bb113 + %1041 = load i32* %draw_buffer, align 4 ; [#uses=1] + %1042 = add nsw i32 %1041, 1 ; [#uses=1] + store i32 %1042, i32* %draw_buffer, align 4 + br label %bb227 + +bb227: ; preds = %bb226, %bb110 + %1043 = load i32* %draw_buffer, align 4 ; [#uses=1] + %1044 = icmp sle i32 %1043, 7 ; [#uses=1] + br i1 %1044, label %bb113, label %bb228 + +bb228: ; preds = %bb227 + br label %bb316 + +bb229: ; preds = %bb108 + %1045 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %1046 = getelementptr inbounds %struct.GLDContextRec* %1045, i32 0, i32 28 ; <%struct.GLDFramebufferRec**> [#uses=1] + %1047 = load %struct.GLDFramebufferRec** %1046, align 4 ; <%struct.GLDFramebufferRec*> [#uses=1] + %1048 = icmp ne %struct.GLDFramebufferRec* %1047, null ; [#uses=1] + br i1 %1048, label %bb230, label %bb231 + +bb230: ; preds = %bb229 + %1049 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %1050 = getelementptr inbounds %struct.GLDContextRec* %1049, i32 0, i32 28 ; <%struct.GLDFramebufferRec**> [#uses=1] + %1051 = load %struct.GLDFramebufferRec** %1050, align 4 ; <%struct.GLDFramebufferRec*> [#uses=1] + %1052 = getelementptr inbounds %struct.GLDFramebufferRec* %1051, i32 0, i32 2 ; <[10 x %struct.GLDFormat]*> [#uses=1] + %1053 = getelementptr inbounds [10 x %struct.GLDFormat]* %1052, i32 0, i32 0 ; <%struct.GLDFormat*> [#uses=1] + %1054 = getelementptr inbounds %struct.GLDFormat* %1053, i32 0, i32 7 ; [#uses=1] + %1055 = load i32* %1054, align 4 ; [#uses=1] + %1056 = icmp eq i32 %1055, 5123 ; [#uses=1] + %1057 = zext i1 %1056 to i8 ; [#uses=1] + store i8 %1057, i8* %iftmp.192, align 1 + br label %bb232 + +bb231: ; preds = %bb229 + %1058 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %1059 = getelementptr inbounds %struct.GLDContextRec* %1058, i32 0, i32 56 ; <%struct.GLDFormat*> [#uses=1] + %1060 = getelementptr inbounds %struct.GLDFormat* %1059, i32 0, i32 7 ; [#uses=1] + %1061 = load i32* %1060, align 4 ; [#uses=1] + %1062 = icmp eq i32 %1061, 5123 ; [#uses=1] + %1063 = zext i1 %1062 to i8 ; [#uses=1] + store i8 %1063, i8* %iftmp.192, align 1 + br label %bb232 + +bb232: ; preds = %bb231, %bb230 + %1064 = load i8* %iftmp.192, align 1 ; [#uses=1] + %toBool233 = icmp ne i8 %1064, 0 ; [#uses=1] + br i1 %toBool233, label %bb316, label %bb234 + +bb234: ; preds = %bb232 + %1065 = load i32* %offset, align 4 ; [#uses=1] + store i32 %1065, i32* %start_offset236, align 4 + store i32 0, i32* %draw_buffer, align 4 + br label %bb315 + +bb237: ; preds = %bb315 + %1066 = load i32* %draw_buffer, align 4 ; [#uses=1] + %1067 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %1068 = getelementptr inbounds %struct.GLDContextRec* %1067, i32 0, i32 30 ; <%struct.GLDBufferstate*> [#uses=1] + %1069 = getelementptr inbounds %struct.GLDBufferstate* %1068, i32 0, i32 12 ; <[8 x %union.GLSBuffer]*> [#uses=1] + %1070 = getelementptr inbounds [8 x %union.GLSBuffer]* %1069, i32 0, i32 %1066 ; <%union.GLSBuffer*> [#uses=1] + %1071 = getelementptr inbounds %union.GLSBuffer* %1070, i32 0, i32 0 ; [#uses=1] + %1072 = load i8** %1071, align 4 ; [#uses=1] + %1073 = icmp ne i8* %1072, null ; [#uses=1] + br i1 %1073, label %bb238, label %bb314 + +bb238: ; preds = %bb237 + %1074 = load i32* %draw_buffer, align 4 ; [#uses=1] + %1075 = shl i32 1, %1074 ; [#uses=1] + store i32 %1075, i32* %cur_draw_buffer_mask_bit239, align 4 + %1076 = load i32* %start_offset236, align 4 ; [#uses=1] + store i32 %1076, i32* %offset, align 4 + %1077 = load i32* %cy, align 4 ; [#uses=1] + store i32 %1077, i32* %y, align 4 + br label %bb313 + +bb240: ; preds = %bb313 + %1078 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %1079 = getelementptr inbounds %struct.GLDContextRec* %1078, i32 0, i32 30 ; <%struct.GLDBufferstate*> [#uses=1] + %1080 = getelementptr inbounds %struct.GLDBufferstate* %1079, i32 0, i32 11 ; <%union.GLSBuffer*> [#uses=1] + %1081 = getelementptr inbounds %union.GLSBuffer* %1080, i32 0, i32 0 ; [#uses=1] + %1082 = bitcast i8** %1081 to double** ; [#uses=1] + %1083 = load double** %1082, align 4 ; [#uses=1] + %1084 = load i32* %offset, align 4 ; [#uses=1] + %1085 = mul i32 %1084, 4 ; [#uses=1] + %1086 = getelementptr inbounds double* %1083, i32 %1085 ; [#uses=1] + store double* %1086, double** %accum, align 4 + %1087 = load double** %accum, align 4 ; [#uses=1] + %1088 = load i32* %cw4, align 4 ; [#uses=1] + %1089 = getelementptr inbounds double* %1087, i32 %1088 ; [#uses=1] + store double* %1089, double** %accum_end, align 4 + %1090 = load i32* %draw_buffer, align 4 ; [#uses=1] + %1091 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %1092 = getelementptr inbounds %struct.GLDContextRec* %1091, i32 0, i32 30 ; <%struct.GLDBufferstate*> [#uses=1] + %1093 = getelementptr inbounds %struct.GLDBufferstate* %1092, i32 0, i32 12 ; <[8 x %union.GLSBuffer]*> [#uses=1] + %1094 = getelementptr inbounds [8 x %union.GLSBuffer]* %1093, i32 0, i32 %1090 ; <%union.GLSBuffer*> [#uses=1] + %1095 = getelementptr inbounds %union.GLSBuffer* %1094, i32 0, i32 0 ; [#uses=1] + %1096 = bitcast i8** %1095 to float** ; [#uses=1] + %1097 = load float** %1096, align 4 ; [#uses=1] + %1098 = load i32* %offset, align 4 ; [#uses=1] + %1099 = mul i32 %1098, 4 ; [#uses=1] + %1100 = getelementptr inbounds float* %1097, i32 %1099 ; [#uses=1] + store float* %1100, float** %color_ptr235, align 4 + %1101 = load i8* %color_mask_enabled, align 1 ; [#uses=1] + %1102 = icmp ne i8 %1101, 0 ; [#uses=1] + br i1 %1102, label %bb241, label %bb281 + +bb241: ; preds = %bb240 + br label %bb279 + +bb242: ; preds = %bb279 + %1103 = load double** %accum, align 4 ; [#uses=1] + %1104 = getelementptr inbounds double* %1103, i32 0 ; [#uses=1] + %1105 = load double* %1104, align 1 ; [#uses=1] + %1106 = fptrunc double %1105 to float ; [#uses=1] + %1107 = load float* %value_addr, align 4 ; [#uses=1] + %1108 = fmul float %1106, %1107 ; [#uses=1] + store float %1108, float* %r243, align 4 + %1109 = load double** %accum, align 4 ; [#uses=1] + %1110 = getelementptr inbounds double* %1109, i32 1 ; [#uses=1] + %1111 = load double* %1110, align 1 ; [#uses=1] + %1112 = fptrunc double %1111 to float ; [#uses=1] + %1113 = load float* %value_addr, align 4 ; [#uses=1] + %1114 = fmul float %1112, %1113 ; [#uses=1] + store float %1114, float* %g244, align 4 + %1115 = load double** %accum, align 4 ; [#uses=1] + %1116 = getelementptr inbounds double* %1115, i32 2 ; [#uses=1] + %1117 = load double* %1116, align 1 ; [#uses=1] + %1118 = fptrunc double %1117 to float ; [#uses=1] + %1119 = load float* %value_addr, align 4 ; [#uses=1] + %1120 = fmul float %1118, %1119 ; [#uses=1] + store float %1120, float* %b245, align 4 + %1121 = load double** %accum, align 4 ; [#uses=1] + %1122 = getelementptr inbounds double* %1121, i32 3 ; [#uses=1] + %1123 = load double* %1122, align 1 ; [#uses=1] + %1124 = fptrunc double %1123 to float ; [#uses=1] + %1125 = load float* %value_addr, align 4 ; [#uses=1] + %1126 = fmul float %1124, %1125 ; [#uses=1] + store float %1126, float* %a246, align 4 + %1127 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] + %1128 = getelementptr inbounds %struct.GLDState* %1127, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] + %1129 = getelementptr inbounds %struct.GLDMaskMode* %1128, i32 0, i32 2 ; [#uses=1] + %1130 = load i8* %1129, align 16 ; [#uses=1] + %1131 = zext i8 %1130 to i32 ; [#uses=1] + %1132 = load i32* %cur_draw_buffer_mask_bit239, align 4 ; [#uses=1] + %1133 = and i32 %1131, %1132 ; [#uses=1] + %1134 = icmp ne i32 %1133, 0 ; [#uses=1] + br i1 %1134, label %bb247, label %bb254 + +bb247: ; preds = %bb242 + %1135 = load float* %r243, align 4 ; [#uses=1] + %1136 = fcmp uge float %1135, 0.000000e+00 ; [#uses=1] + br i1 %1136, label %bb248, label %bb252 + +bb248: ; preds = %bb247 + %1137 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %1138 = getelementptr inbounds %struct.GLDContextRec* %1137, i32 0, i32 2 ; [#uses=1] + %1139 = load float* %1138, align 4 ; [#uses=1] + %1140 = load float* %r243, align 4 ; [#uses=1] + %1141 = fcmp olt float %1139, %1140 ; [#uses=1] + br i1 %1141, label %bb249, label %bb250 + +bb249: ; preds = %bb248 + %1142 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %1143 = getelementptr inbounds %struct.GLDContextRec* %1142, i32 0, i32 2 ; [#uses=1] + %1144 = load float* %1143, align 4 ; [#uses=1] + store float %1144, float* %iftmp.196, align 4 + br label %bb251 + +bb250: ; preds = %bb248 + %1145 = load float* %r243, align 4 ; [#uses=1] + store float %1145, float* %iftmp.196, align 4 + br label %bb251 + +bb251: ; preds = %bb250, %bb249 + %1146 = load float* %iftmp.196, align 4 ; [#uses=1] + store float %1146, float* %iftmp.195, align 4 + br label %bb253 + +bb252: ; preds = %bb247 + store float 0.000000e+00, float* %iftmp.195, align 4 + br label %bb253 + +bb253: ; preds = %bb252, %bb251 + %1147 = load float** %color_ptr235, align 4 ; [#uses=1] + %1148 = getelementptr inbounds float* %1147, i32 0 ; [#uses=1] + %1149 = load float* %iftmp.195, align 4 ; [#uses=1] + store float %1149, float* %1148, align 1 + br label %bb254 + +bb254: ; preds = %bb253, %bb242 + %1150 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] + %1151 = getelementptr inbounds %struct.GLDState* %1150, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] + %1152 = getelementptr inbounds %struct.GLDMaskMode* %1151, i32 0, i32 3 ; [#uses=1] + %1153 = load i8* %1152, align 1 ; [#uses=1] + %1154 = zext i8 %1153 to i32 ; [#uses=1] + %1155 = load i32* %cur_draw_buffer_mask_bit239, align 4 ; [#uses=1] + %1156 = and i32 %1154, %1155 ; [#uses=1] + %1157 = icmp ne i32 %1156, 0 ; [#uses=1] + br i1 %1157, label %bb255, label %bb262 + +bb255: ; preds = %bb254 + %1158 = load float* %g244, align 4 ; [#uses=1] + %1159 = fcmp uge float %1158, 0.000000e+00 ; [#uses=1] + br i1 %1159, label %bb256, label %bb260 + +bb256: ; preds = %bb255 + %1160 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %1161 = getelementptr inbounds %struct.GLDContextRec* %1160, i32 0, i32 2 ; [#uses=1] + %1162 = load float* %1161, align 4 ; [#uses=1] + %1163 = load float* %g244, align 4 ; [#uses=1] + %1164 = fcmp olt float %1162, %1163 ; [#uses=1] + br i1 %1164, label %bb257, label %bb258 + +bb257: ; preds = %bb256 + %1165 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %1166 = getelementptr inbounds %struct.GLDContextRec* %1165, i32 0, i32 2 ; [#uses=1] + %1167 = load float* %1166, align 4 ; [#uses=1] + store float %1167, float* %iftmp.198, align 4 + br label %bb259 + +bb258: ; preds = %bb256 + %1168 = load float* %g244, align 4 ; [#uses=1] + store float %1168, float* %iftmp.198, align 4 + br label %bb259 + +bb259: ; preds = %bb258, %bb257 + %1169 = load float* %iftmp.198, align 4 ; [#uses=1] + store float %1169, float* %iftmp.197, align 4 + br label %bb261 + +bb260: ; preds = %bb255 + store float 0.000000e+00, float* %iftmp.197, align 4 + br label %bb261 + +bb261: ; preds = %bb260, %bb259 + %1170 = load float** %color_ptr235, align 4 ; [#uses=1] + %1171 = getelementptr inbounds float* %1170, i32 1 ; [#uses=1] + %1172 = load float* %iftmp.197, align 4 ; [#uses=1] + store float %1172, float* %1171, align 1 + br label %bb262 + +bb262: ; preds = %bb261, %bb254 + %1173 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] + %1174 = getelementptr inbounds %struct.GLDState* %1173, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] + %1175 = getelementptr inbounds %struct.GLDMaskMode* %1174, i32 0, i32 4 ; [#uses=1] + %1176 = load i8* %1175, align 2 ; [#uses=1] + %1177 = zext i8 %1176 to i32 ; [#uses=1] + %1178 = load i32* %cur_draw_buffer_mask_bit239, align 4 ; [#uses=1] + %1179 = and i32 %1177, %1178 ; [#uses=1] + %1180 = icmp ne i32 %1179, 0 ; [#uses=1] + br i1 %1180, label %bb263, label %bb270 + +bb263: ; preds = %bb262 + %1181 = load float* %b245, align 4 ; [#uses=1] + %1182 = fcmp uge float %1181, 0.000000e+00 ; [#uses=1] + br i1 %1182, label %bb264, label %bb268 + +bb264: ; preds = %bb263 + %1183 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %1184 = getelementptr inbounds %struct.GLDContextRec* %1183, i32 0, i32 2 ; [#uses=1] + %1185 = load float* %1184, align 4 ; [#uses=1] + %1186 = load float* %b245, align 4 ; [#uses=1] + %1187 = fcmp olt float %1185, %1186 ; [#uses=1] + br i1 %1187, label %bb265, label %bb266 + +bb265: ; preds = %bb264 + %1188 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %1189 = getelementptr inbounds %struct.GLDContextRec* %1188, i32 0, i32 2 ; [#uses=1] + %1190 = load float* %1189, align 4 ; [#uses=1] + store float %1190, float* %iftmp.200, align 4 + br label %bb267 + +bb266: ; preds = %bb264 + %1191 = load float* %b245, align 4 ; [#uses=1] + store float %1191, float* %iftmp.200, align 4 + br label %bb267 + +bb267: ; preds = %bb266, %bb265 + %1192 = load float* %iftmp.200, align 4 ; [#uses=1] + store float %1192, float* %iftmp.199, align 4 + br label %bb269 + +bb268: ; preds = %bb263 + store float 0.000000e+00, float* %iftmp.199, align 4 + br label %bb269 + +bb269: ; preds = %bb268, %bb267 + %1193 = load float** %color_ptr235, align 4 ; [#uses=1] + %1194 = getelementptr inbounds float* %1193, i32 2 ; [#uses=1] + %1195 = load float* %iftmp.199, align 4 ; [#uses=1] + store float %1195, float* %1194, align 1 + br label %bb270 + +bb270: ; preds = %bb269, %bb262 + %1196 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] + %1197 = getelementptr inbounds %struct.GLDState* %1196, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] + %1198 = getelementptr inbounds %struct.GLDMaskMode* %1197, i32 0, i32 5 ; [#uses=1] + %1199 = load i8* %1198, align 1 ; [#uses=1] + %1200 = zext i8 %1199 to i32 ; [#uses=1] + %1201 = load i32* %cur_draw_buffer_mask_bit239, align 4 ; [#uses=1] + %1202 = and i32 %1200, %1201 ; [#uses=1] + %1203 = icmp ne i32 %1202, 0 ; [#uses=1] + br i1 %1203, label %bb271, label %bb278 + +bb271: ; preds = %bb270 + %1204 = load float* %a246, align 4 ; [#uses=1] + %1205 = fcmp uge float %1204, 0.000000e+00 ; [#uses=1] + br i1 %1205, label %bb272, label %bb276 + +bb272: ; preds = %bb271 + %1206 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %1207 = getelementptr inbounds %struct.GLDContextRec* %1206, i32 0, i32 2 ; [#uses=1] + %1208 = load float* %1207, align 4 ; [#uses=1] + %1209 = load float* %a246, align 4 ; [#uses=1] + %1210 = fcmp olt float %1208, %1209 ; [#uses=1] + br i1 %1210, label %bb273, label %bb274 + +bb273: ; preds = %bb272 + %1211 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %1212 = getelementptr inbounds %struct.GLDContextRec* %1211, i32 0, i32 2 ; [#uses=1] + %1213 = load float* %1212, align 4 ; [#uses=1] + store float %1213, float* %iftmp.202, align 4 + br label %bb275 + +bb274: ; preds = %bb272 + %1214 = load float* %a246, align 4 ; [#uses=1] + store float %1214, float* %iftmp.202, align 4 + br label %bb275 + +bb275: ; preds = %bb274, %bb273 + %1215 = load float* %iftmp.202, align 4 ; [#uses=1] + store float %1215, float* %iftmp.201, align 4 + br label %bb277 + +bb276: ; preds = %bb271 + store float 0.000000e+00, float* %iftmp.201, align 4 + br label %bb277 + +bb277: ; preds = %bb276, %bb275 + %1216 = load float** %color_ptr235, align 4 ; [#uses=1] + %1217 = getelementptr inbounds float* %1216, i32 3 ; [#uses=1] + %1218 = load float* %iftmp.201, align 4 ; [#uses=1] + store float %1218, float* %1217, align 1 + br label %bb278 + +bb278: ; preds = %bb277, %bb270 + %1219 = load double** %accum, align 4 ; [#uses=1] + %1220 = getelementptr inbounds double* %1219, i32 4 ; [#uses=1] + store double* %1220, double** %accum, align 4 + %1221 = load float** %color_ptr235, align 4 ; [#uses=1] + %1222 = getelementptr inbounds float* %1221, i32 4 ; [#uses=1] + store float* %1222, float** %color_ptr235, align 4 + br label %bb279 + +bb279: ; preds = %bb278, %bb241 + %1223 = load double** %accum, align 4 ; [#uses=1] + %1224 = load double** %accum_end, align 4 ; [#uses=1] + %1225 = icmp ult double* %1223, %1224 ; [#uses=1] + br i1 %1225, label %bb242, label %bb280 + +bb280: ; preds = %bb279 + br label %bb312 + +bb281: ; preds = %bb240 + br label %bb311 + +bb282: ; preds = %bb311 + %1226 = load double** %accum, align 4 ; [#uses=1] + %1227 = getelementptr inbounds double* %1226, i32 0 ; [#uses=1] + %1228 = load double* %1227, align 1 ; [#uses=1] + %1229 = fptrunc double %1228 to float ; [#uses=1] + %1230 = load float* %value_addr, align 4 ; [#uses=1] + %1231 = fmul float %1229, %1230 ; [#uses=1] + store float %1231, float* %r283, align 4 + %1232 = load double** %accum, align 4 ; [#uses=1] + %1233 = getelementptr inbounds double* %1232, i32 1 ; [#uses=1] + %1234 = load double* %1233, align 1 ; [#uses=1] + %1235 = fptrunc double %1234 to float ; [#uses=1] + %1236 = load float* %value_addr, align 4 ; [#uses=1] + %1237 = fmul float %1235, %1236 ; [#uses=1] + store float %1237, float* %g284, align 4 + %1238 = load double** %accum, align 4 ; [#uses=1] + %1239 = getelementptr inbounds double* %1238, i32 2 ; [#uses=1] + %1240 = load double* %1239, align 1 ; [#uses=1] + %1241 = fptrunc double %1240 to float ; [#uses=1] + %1242 = load float* %value_addr, align 4 ; [#uses=1] + %1243 = fmul float %1241, %1242 ; [#uses=1] + store float %1243, float* %b285, align 4 + %1244 = load double** %accum, align 4 ; [#uses=1] + %1245 = getelementptr inbounds double* %1244, i32 3 ; [#uses=1] + %1246 = load double* %1245, align 1 ; [#uses=1] + %1247 = fptrunc double %1246 to float ; [#uses=1] + %1248 = load float* %value_addr, align 4 ; [#uses=1] + %1249 = fmul float %1247, %1248 ; [#uses=1] + store float %1249, float* %a286, align 4 + %1250 = load float* %r283, align 4 ; [#uses=1] + %1251 = fcmp uge float %1250, 0.000000e+00 ; [#uses=1] + br i1 %1251, label %bb287, label %bb291 + +bb287: ; preds = %bb282 + %1252 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %1253 = getelementptr inbounds %struct.GLDContextRec* %1252, i32 0, i32 2 ; [#uses=1] + %1254 = load float* %1253, align 4 ; [#uses=1] + %1255 = load float* %r283, align 4 ; [#uses=1] + %1256 = fcmp olt float %1254, %1255 ; [#uses=1] + br i1 %1256, label %bb288, label %bb289 + +bb288: ; preds = %bb287 + %1257 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %1258 = getelementptr inbounds %struct.GLDContextRec* %1257, i32 0, i32 2 ; [#uses=1] + %1259 = load float* %1258, align 4 ; [#uses=1] + store float %1259, float* %iftmp.204, align 4 + br label %bb290 + +bb289: ; preds = %bb287 + %1260 = load float* %r283, align 4 ; [#uses=1] + store float %1260, float* %iftmp.204, align 4 + br label %bb290 + +bb290: ; preds = %bb289, %bb288 + %1261 = load float* %iftmp.204, align 4 ; [#uses=1] + store float %1261, float* %iftmp.203, align 4 + br label %bb292 + +bb291: ; preds = %bb282 + store float 0.000000e+00, float* %iftmp.203, align 4 + br label %bb292 + +bb292: ; preds = %bb291, %bb290 + %1262 = load float** %color_ptr235, align 4 ; [#uses=1] + %1263 = getelementptr inbounds float* %1262, i32 0 ; [#uses=1] + %1264 = load float* %iftmp.203, align 4 ; [#uses=1] + store float %1264, float* %1263, align 1 + %1265 = load float* %g284, align 4 ; [#uses=1] + %1266 = fcmp uge float %1265, 0.000000e+00 ; [#uses=1] + br i1 %1266, label %bb293, label %bb297 + +bb293: ; preds = %bb292 + %1267 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %1268 = getelementptr inbounds %struct.GLDContextRec* %1267, i32 0, i32 2 ; [#uses=1] + %1269 = load float* %1268, align 4 ; [#uses=1] + %1270 = load float* %g284, align 4 ; [#uses=1] + %1271 = fcmp olt float %1269, %1270 ; [#uses=1] + br i1 %1271, label %bb294, label %bb295 + +bb294: ; preds = %bb293 + %1272 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %1273 = getelementptr inbounds %struct.GLDContextRec* %1272, i32 0, i32 2 ; [#uses=1] + %1274 = load float* %1273, align 4 ; [#uses=1] + store float %1274, float* %iftmp.206, align 4 + br label %bb296 + +bb295: ; preds = %bb293 + %1275 = load float* %g284, align 4 ; [#uses=1] + store float %1275, float* %iftmp.206, align 4 + br label %bb296 + +bb296: ; preds = %bb295, %bb294 + %1276 = load float* %iftmp.206, align 4 ; [#uses=1] + store float %1276, float* %iftmp.205, align 4 + br label %bb298 + +bb297: ; preds = %bb292 + store float 0.000000e+00, float* %iftmp.205, align 4 + br label %bb298 + +bb298: ; preds = %bb297, %bb296 + %1277 = load float** %color_ptr235, align 4 ; [#uses=1] + %1278 = getelementptr inbounds float* %1277, i32 1 ; [#uses=1] + %1279 = load float* %iftmp.205, align 4 ; [#uses=1] + store float %1279, float* %1278, align 1 + %1280 = load float* %b285, align 4 ; [#uses=1] + %1281 = fcmp uge float %1280, 0.000000e+00 ; [#uses=1] + br i1 %1281, label %bb299, label %bb303 + +bb299: ; preds = %bb298 + %1282 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %1283 = getelementptr inbounds %struct.GLDContextRec* %1282, i32 0, i32 2 ; [#uses=1] + %1284 = load float* %1283, align 4 ; [#uses=1] + %1285 = load float* %b285, align 4 ; [#uses=1] + %1286 = fcmp olt float %1284, %1285 ; [#uses=1] + br i1 %1286, label %bb300, label %bb301 + +bb300: ; preds = %bb299 + %1287 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %1288 = getelementptr inbounds %struct.GLDContextRec* %1287, i32 0, i32 2 ; [#uses=1] + %1289 = load float* %1288, align 4 ; [#uses=1] + store float %1289, float* %iftmp.208, align 4 + br label %bb302 + +bb301: ; preds = %bb299 + %1290 = load float* %b285, align 4 ; [#uses=1] + store float %1290, float* %iftmp.208, align 4 + br label %bb302 + +bb302: ; preds = %bb301, %bb300 + %1291 = load float* %iftmp.208, align 4 ; [#uses=1] + store float %1291, float* %iftmp.207, align 4 + br label %bb304 + +bb303: ; preds = %bb298 + store float 0.000000e+00, float* %iftmp.207, align 4 + br label %bb304 + +bb304: ; preds = %bb303, %bb302 + %1292 = load float** %color_ptr235, align 4 ; [#uses=1] + %1293 = getelementptr inbounds float* %1292, i32 2 ; [#uses=1] + %1294 = load float* %iftmp.207, align 4 ; [#uses=1] + store float %1294, float* %1293, align 1 + %1295 = load float* %a286, align 4 ; [#uses=1] + %1296 = fcmp uge float %1295, 0.000000e+00 ; [#uses=1] + br i1 %1296, label %bb305, label %bb309 + +bb305: ; preds = %bb304 + %1297 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %1298 = getelementptr inbounds %struct.GLDContextRec* %1297, i32 0, i32 2 ; [#uses=1] + %1299 = load float* %1298, align 4 ; [#uses=1] + %1300 = load float* %a286, align 4 ; [#uses=1] + %1301 = fcmp olt float %1299, %1300 ; [#uses=1] + br i1 %1301, label %bb306, label %bb307 + +bb306: ; preds = %bb305 + %1302 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] + %1303 = getelementptr inbounds %struct.GLDContextRec* %1302, i32 0, i32 2 ; [#uses=1] + %1304 = load float* %1303, align 4 ; [#uses=1] + store float %1304, float* %iftmp.210, align 4 + br label %bb308 + +bb307: ; preds = %bb305 + %1305 = load float* %a286, align 4 ; [#uses=1] + store float %1305, float* %iftmp.210, align 4 + br label %bb308 + +bb308: ; preds = %bb307, %bb306 + %1306 = load float* %iftmp.210, align 4 ; [#uses=1] + store float %1306, float* %iftmp.209, align 4 + br label %bb310 + +bb309: ; preds = %bb304 + store float 0.000000e+00, float* %iftmp.209, align 4 + br label %bb310 + +bb310: ; preds = %bb309, %bb308 + %1307 = load float** %color_ptr235, align 4 ; [#uses=1] + %1308 = getelementptr inbounds float* %1307, i32 3 ; [#uses=1] + %1309 = load float* %iftmp.209, align 4 ; [#uses=1] + store float %1309, float* %1308, align 1 + %1310 = load double** %accum, align 4 ; [#uses=1] + %1311 = getelementptr inbounds double* %1310, i32 4 ; [#uses=1] + store double* %1311, double** %accum, align 4 + %1312 = load float** %color_ptr235, align 4 ; [#uses=1] + %1313 = getelementptr inbounds float* %1312, i32 4 ; [#uses=1] + store float* %1313, float** %color_ptr235, align 4 + br label %bb311 + +bb311: ; preds = %bb310, %bb281 + %1314 = load double** %accum, align 4 ; [#uses=1] + %1315 = load double** %accum_end, align 4 ; [#uses=1] + %1316 = icmp ult double* %1314, %1315 ; [#uses=1] + br i1 %1316, label %bb282, label %bb312 + +bb312: ; preds = %bb311, %bb280 + %1317 = load i32* %y, align 4 ; [#uses=1] + %1318 = add i32 %1317, 1 ; [#uses=1] + store i32 %1318, i32* %y, align 4 + %1319 = load i32* %offset, align 4 ; [#uses=1] + %1320 = load i32* %y_inc, align 4 ; [#uses=1] + %1321 = add i32 %1319, %1320 ; [#uses=1] + store i32 %1321, i32* %offset, align 4 + br label %bb313 + +bb313: ; preds = %bb312, %bb238 + %1322 = load i32* %y, align 4 ; [#uses=1] + %1323 = load i32* %yl, align 4 ; [#uses=1] + %1324 = icmp ult i32 %1322, %1323 ; [#uses=1] + br i1 %1324, label %bb240, label %bb314 + +bb314: ; preds = %bb313, %bb237 + %1325 = load i32* %draw_buffer, align 4 ; [#uses=1] + %1326 = add nsw i32 %1325, 1 ; [#uses=1] + store i32 %1326, i32* %draw_buffer, align 4 + br label %bb315 + +bb315: ; preds = %bb314, %bb234 + %1327 = load i32* %draw_buffer, align 4 ; [#uses=1] + %1328 = icmp sle i32 %1327, 7 ; [#uses=1] + br i1 %1328, label %bb237, label %bb316 + +bb316: ; preds = %bb315, %bb232, %bb228, %bb6 + br label %return + +return: ; preds = %bb316 + ret void +} From daniel at zuster.org Tue May 25 14:49:33 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 25 May 2010 19:49:33 -0000 Subject: [llvm-commits] [llvm] r104626 - in /llvm/trunk: lib/Target/X86/AsmParser/X86AsmParser.cpp test/MC/AsmParser/X86/x86_32-new-encoder.s Message-ID: <20100525194933.1DE95312800A@llvm.org> Author: ddunbar Date: Tue May 25 14:49:32 2010 New Revision: 104626 URL: http://llvm.org/viewvc/llvm-project?rev=104626&view=rev Log: MC/X86: Add a hack to allow recognizing 'cmpltps' and friends. Modified: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s Modified: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp?rev=104626&r1=104625&r2=104626&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp (original) +++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp Tue May 25 14:49:32 2010 @@ -632,8 +632,43 @@ .Case("cmovnzl", "cmovnel") .Case("cmovzl", "cmovel") .Default(Name); + + // FIXME: Hack to recognize cmp{ss,sd,ps,pd}. + const MCExpr *ExtraImmOp = 0; + if (PatchedName.startswith("cmp") && + (PatchedName.endswith("ss") || PatchedName.endswith("sd") || + PatchedName.endswith("ps") || PatchedName.endswith("pd"))) { + unsigned SSEComparisonCode = StringSwitch( + PatchedName.slice(3, PatchedName.size() - 2)) + .Case("eq", 0) + .Case("lt", 1) + .Case("le", 2) + .Case("unord", 3) + .Case("neq", 4) + .Case("nlt", 5) + .Case("nle", 6) + .Case("ord", 7) + .Default(~0U); + if (SSEComparisonCode != ~0U) { + ExtraImmOp = MCConstantExpr::Create(SSEComparisonCode, + getParser().getContext()); + if (PatchedName.endswith("ss")) { + PatchedName = "cmpss"; + } else if (PatchedName.endswith("sd")) { + PatchedName = "cmpsd"; + } else if (PatchedName.endswith("ps")) { + PatchedName = "cmpps"; + } else { + assert(PatchedName.endswith("pd") && "Unexpected mnemonic!"); + PatchedName = "cmppd"; + } + } + } Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc)); + if (ExtraImmOp) + Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc)); + if (getLexer().isNot(AsmToken::EndOfStatement)) { // Parse '*' modifier. @@ -648,7 +683,7 @@ Operands.push_back(Op); else return true; - + while (getLexer().is(AsmToken::Comma)) { Parser.Lex(); // Eat the comma. Modified: llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s?rev=104626&r1=104625&r2=104626&view=diff ============================================================================== --- llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s (original) +++ llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s Tue May 25 14:49:32 2010 @@ -243,3 +243,37 @@ // CHECK: cmpsd $0, (%eax), %xmm1 // CHECK: encoding: [0xf2,0x0f,0xc2,0x08,0x00] cmpsd $0, 0(%eax), %xmm1 + +// Check matching of instructions which embed the SSE comparison code. + +// CHECK: cmpps $0, %xmm0, %xmm1 +// CHECK: encoding: [0x0f,0xc2,0xc8,0x00] + cmpeqps %xmm0, %xmm1 + +// CHECK: cmppd $1, %xmm0, %xmm1 +// CHECK: encoding: [0x66,0x0f,0xc2,0xc8,0x01] + cmpltpd %xmm0, %xmm1 + +// CHECK: cmpss $2, %xmm0, %xmm1 +// CHECK: encoding: [0xf3,0x0f,0xc2,0xc8,0x02] + cmpless %xmm0, %xmm1 + +// CHECK: cmppd $3, %xmm0, %xmm1 +// CHECK: encoding: [0x66,0x0f,0xc2,0xc8,0x03] + cmpunordpd %xmm0, %xmm1 + +// CHECK: cmpps $4, %xmm0, %xmm1 +// CHECK: encoding: [0x0f,0xc2,0xc8,0x04] + cmpneqps %xmm0, %xmm1 + +// CHECK: cmppd $5, %xmm0, %xmm1 +// CHECK: encoding: [0x66,0x0f,0xc2,0xc8,0x05] + cmpnltpd %xmm0, %xmm1 + +// CHECK: cmpss $6, %xmm0, %xmm1 +// CHECK: encoding: [0xf3,0x0f,0xc2,0xc8,0x06] + cmpnless %xmm0, %xmm1 + +// CHECK: cmpsd $7, %xmm0, %xmm1 +// CHECK: encoding: [0xf2,0x0f,0xc2,0xc8,0x07] + cmpordsd %xmm0, %xmm1 From stoklund at 2pi.dk Tue May 25 14:49:38 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 25 May 2010 19:49:38 -0000 Subject: [llvm-commits] [llvm] r104628 - in /llvm/trunk: include/llvm/Target/TargetRegisterInfo.h lib/CodeGen/MachineInstr.cpp lib/Target/TargetRegisterInfo.cpp utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <20100525194938.6FC593128026@llvm.org> Author: stoklund Date: Tue May 25 14:49:38 2010 New Revision: 104628 URL: http://llvm.org/viewvc/llvm-project?rev=104628&view=rev Log: Print symbolic SubRegIndex names on machine operands. Modified: llvm/trunk/include/llvm/Target/TargetRegisterInfo.h llvm/trunk/lib/CodeGen/MachineInstr.cpp llvm/trunk/lib/Target/TargetRegisterInfo.cpp llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Modified: llvm/trunk/include/llvm/Target/TargetRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetRegisterInfo.h?rev=104628&r1=104627&r2=104628&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetRegisterInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetRegisterInfo.h Tue May 25 14:49:38 2010 @@ -268,6 +268,7 @@ typedef const TargetRegisterClass * const * regclass_iterator; private: const TargetRegisterDesc *Desc; // Pointer to the descriptor array + const char *const *SubRegIndexNames; // Names of subreg indexes. unsigned NumRegs; // Number of entries in the array regclass_iterator RegClassBegin, RegClassEnd; // List of regclasses @@ -278,6 +279,7 @@ TargetRegisterInfo(const TargetRegisterDesc *D, unsigned NR, regclass_iterator RegClassBegin, regclass_iterator RegClassEnd, + const char *const *subregindexnames, int CallFrameSetupOpcode = -1, int CallFrameDestroyOpcode = -1, const unsigned* subregs = 0, @@ -378,6 +380,13 @@ return NumRegs; } + /// getSubRegIndexName - Return the human-readable symbolic target-specific + /// name for the specified SubRegIndex. + const char *getSubRegIndexName(unsigned SubIdx) const { + assert(SubIdx && "This is not a subregister index"); + return SubRegIndexNames[SubIdx-1]; + } + /// regsOverlap - Returns true if the two registers are equal or alias each /// other. The registers may be virtual register. bool regsOverlap(unsigned regA, unsigned regB) const { Modified: llvm/trunk/lib/CodeGen/MachineInstr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineInstr.cpp?rev=104628&r1=104627&r2=104628&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineInstr.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineInstr.cpp Tue May 25 14:49:38 2010 @@ -219,8 +219,12 @@ OS << "%physreg" << getReg(); } - if (getSubReg() != 0) - OS << ':' << getSubReg(); + if (getSubReg() != 0) { + if (TM) + OS << ':' << TM->getRegisterInfo()->getSubRegIndexName(getSubReg()); + else + OS << ':' << getSubReg(); + } if (isDef() || isKill() || isDead() || isImplicit() || isUndef() || isEarlyClobber()) { Modified: llvm/trunk/lib/Target/TargetRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetRegisterInfo.cpp?rev=104628&r1=104627&r2=104628&view=diff ============================================================================== --- llvm/trunk/lib/Target/TargetRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/TargetRegisterInfo.cpp Tue May 25 14:49:38 2010 @@ -22,6 +22,7 @@ TargetRegisterInfo::TargetRegisterInfo(const TargetRegisterDesc *D, unsigned NR, regclass_iterator RCB, regclass_iterator RCE, + const char *const *subregindexnames, int CFSO, int CFDO, const unsigned* subregs, const unsigned subregsize, const unsigned* superregs, const unsigned superregsize, @@ -29,7 +30,8 @@ : SubregHash(subregs), SubregHashSize(subregsize), SuperregHash(superregs), SuperregHashSize(superregsize), AliasesHash(aliases), AliasesHashSize(aliasessize), - Desc(D), NumRegs(NR), RegClassBegin(RCB), RegClassEnd(RCE) { + Desc(D), SubRegIndexNames(subregindexnames), NumRegs(NR), + RegClassBegin(RCB), RegClassEnd(RCE) { assert(NumRegs < FirstVirtualRegister && "Target has too many physical registers!"); Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp?rev=104628&r1=104627&r2=104628&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Tue May 25 14:49:38 2010 @@ -811,6 +811,16 @@ OS << "Empty_SuperRegsSet },\n"; } OS << " };\n"; // End of register descriptors... + + // Emit SubRegIndex names, skipping 0 + const std::vector SubRegIndices = Target.getSubRegIndices(); + OS << "\n const char *const SubRegIndexTable[] = { \""; + for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) { + OS << SubRegIndices[i]->getName(); + if (i+1 != e) + OS << "\", \""; + } + OS << "\" };\n\n"; OS << "}\n\n"; // End of anonymous namespace... std::string ClassName = Target.getName() + "GenRegisterInfo"; @@ -876,7 +886,8 @@ OS << ClassName << "::" << ClassName << "(int CallFrameSetupOpcode, int CallFrameDestroyOpcode)\n" << " : TargetRegisterInfo(RegisterDescriptors, " << Registers.size()+1 - << ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n " + << ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n" + << " SubRegIndexTable,\n" << " CallFrameSetupOpcode, CallFrameDestroyOpcode,\n" << " SubregHashTable, SubregHashTableSize,\n" << " SuperregHashTable, SuperregHashTableSize,\n" From stoklund at 2pi.dk Tue May 25 14:49:40 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 25 May 2010 19:49:40 -0000 Subject: [llvm-commits] [llvm] r104629 - /llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Message-ID: <20100525194940.C69D2312800A@llvm.org> Author: stoklund Date: Tue May 25 14:49:40 2010 New Revision: 104629 URL: http://llvm.org/viewvc/llvm-project?rev=104629&view=rev Log: Separate unrelated cases that once shared a numeric value Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp?rev=104629&r1=104628&r2=104629&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Tue May 25 14:49:40 2010 @@ -158,7 +158,6 @@ switch (SubIdx) { default: return 0; case X86::sub_8bit: - case X86::sub_ss: if (B == &X86::GR8RegClass) { if (A->getSize() == 2 || A->getSize() == 4 || A->getSize() == 8) return A; @@ -190,12 +189,9 @@ return &X86::GR16_NOREXRegClass; else if (A == &X86::GR16_ABCDRegClass) return &X86::GR16_ABCDRegClass; - } else if (B == &X86::FR32RegClass) { - return A; } break; case X86::sub_8bit_hi: - case X86::sub_sd: if (B == &X86::GR8_ABCD_HRegClass) { if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass || A == &X86::GR64_NOREXRegClass || @@ -208,12 +204,9 @@ else if (A == &X86::GR16RegClass || A == &X86::GR16_ABCDRegClass || A == &X86::GR16_NOREXRegClass) return &X86::GR16_ABCDRegClass; - } else if (B == &X86::FR64RegClass) { - return A; } break; case X86::sub_16bit: - case X86::sub_xmm: if (B == &X86::GR16RegClass) { if (A->getSize() == 4 || A->getSize() == 8) return A; @@ -237,8 +230,6 @@ return &X86::GR32_NOREXRegClass; else if (A == &X86::GR32_ABCDRegClass) return &X86::GR64_ABCDRegClass; - } else if (B == &X86::VR128RegClass) { - return A; } break; case X86::sub_32bit: @@ -259,6 +250,18 @@ return &X86::GR64_ABCDRegClass; } break; + case X86::sub_ss: + if (B == &X86::FR32RegClass) + return A; + break; + case X86::sub_sd: + if (B == &X86::FR64RegClass) + return A; + break; + case X86::sub_xmm: + if (B == &X86::VR128RegClass) + return A; + break; } return 0; } From stoklund at 2pi.dk Tue May 25 14:49:33 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 25 May 2010 19:49:33 -0000 Subject: [llvm-commits] [llvm] r104627 - in /llvm/trunk: include/llvm/Target/Target.td lib/Target/ARM/ARMRegisterInfo.td lib/Target/Blackfin/BlackfinRegisterInfo.td lib/Target/MSP430/MSP430RegisterInfo.td lib/Target/Mips/MipsRegisterInfo.td lib/Target/PowerPC/PPCRegisterInfo.td lib/Target/SystemZ/SystemZRegisterInfo.td lib/Target/X86/X86RegisterInfo.td Message-ID: <20100525194933.4E40D3128018@llvm.org> Author: stoklund Date: Tue May 25 14:49:33 2010 New Revision: 104627 URL: http://llvm.org/viewvc/llvm-project?rev=104627&view=rev Log: Remove NumberHack entirely. SubRegIndex instances are now numbered uniquely the same way Register instances are - in lexicographical order by name. Modified: llvm/trunk/include/llvm/Target/Target.td llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td llvm/trunk/lib/Target/X86/X86RegisterInfo.td Modified: llvm/trunk/include/llvm/Target/Target.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=104627&r1=104626&r2=104627&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/Target.td (original) +++ llvm/trunk/include/llvm/Target/Target.td Tue May 25 14:49:33 2010 @@ -21,13 +21,9 @@ class RegisterClass; // Forward def -// SubRegIndex - Use instances on SubRegIndex to identify subregisters. +// SubRegIndex - Use instances of SubRegIndex to identify subregisters. class SubRegIndex { string Namespace = ""; - - // This explicit numbering is going away after RegisterClass::SubRegClassList - // is replaced. - int NumberHack; } // Register - You should define one instance of this class for each register Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td?rev=104627&r1=104626&r2=104627&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td Tue May 25 14:49:33 2010 @@ -26,27 +26,27 @@ // Subregister indices. let Namespace = "ARM" in { // Note: Code depends on these having consecutive numbers. -def ssub_0 : SubRegIndex { let NumberHack = 1; } -def ssub_1 : SubRegIndex { let NumberHack = 2; } -def ssub_2 : SubRegIndex { let NumberHack = 3; } -def ssub_3 : SubRegIndex { let NumberHack = 4; } - -def dsub_0 : SubRegIndex { let NumberHack = 5; } -def dsub_1 : SubRegIndex { let NumberHack = 6; } -def dsub_2 : SubRegIndex { let NumberHack = 7; } -def dsub_3 : SubRegIndex { let NumberHack = 8; } -def dsub_4 : SubRegIndex { let NumberHack = 9; } -def dsub_5 : SubRegIndex { let NumberHack = 10; } -def dsub_6 : SubRegIndex { let NumberHack = 11; } -def dsub_7 : SubRegIndex { let NumberHack = 12; } - -def qsub_0 : SubRegIndex { let NumberHack = 13; } -def qsub_1 : SubRegIndex { let NumberHack = 14; } -def qsub_2 : SubRegIndex { let NumberHack = 15; } -def qsub_3 : SubRegIndex { let NumberHack = 16; } +def ssub_0 : SubRegIndex; +def ssub_1 : SubRegIndex; +def ssub_2 : SubRegIndex; +def ssub_3 : SubRegIndex; + +def dsub_0 : SubRegIndex; +def dsub_1 : SubRegIndex; +def dsub_2 : SubRegIndex; +def dsub_3 : SubRegIndex; +def dsub_4 : SubRegIndex; +def dsub_5 : SubRegIndex; +def dsub_6 : SubRegIndex; +def dsub_7 : SubRegIndex; + +def qsub_0 : SubRegIndex; +def qsub_1 : SubRegIndex; +def qsub_2 : SubRegIndex; +def qsub_3 : SubRegIndex; -def qqsub_0 : SubRegIndex { let NumberHack = 17; } -def qqsub_1 : SubRegIndex { let NumberHack = 18; } +def qqsub_0 : SubRegIndex; +def qqsub_1 : SubRegIndex; } // Integer registers Modified: llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td?rev=104627&r1=104626&r2=104627&view=diff ============================================================================== --- llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td (original) +++ llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td Tue May 25 14:49:33 2010 @@ -16,9 +16,9 @@ // 2: .H // 3: .W (32 low bits of 40-bit accu) let Namespace = "BF" in { -def lo16 : SubRegIndex { let NumberHack = 1; } -def hi16 : SubRegIndex { let NumberHack = 2; } -def lo32 : SubRegIndex { let NumberHack = 3; } +def lo16 : SubRegIndex; +def hi16 : SubRegIndex; +def lo32 : SubRegIndex; } // Registers are identified with 3-bit group and 3-bit ID numbers. Modified: llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td?rev=104627&r1=104626&r2=104627&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td (original) +++ llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td Tue May 25 14:49:33 2010 @@ -60,10 +60,7 @@ def R14W : MSP430RegWithSubregs<14, "r14", [R14B]>; def R15W : MSP430RegWithSubregs<15, "r15", [R15B]>; -def subreg_8bit : SubRegIndex { - let NumberHack = 1; - let Namespace = "MSP430"; -} +def subreg_8bit : SubRegIndex { let Namespace = "MSP430"; } def : SubRegSet, DwarfRegNum<[75]>; let Namespace = "PPC" in { -def sub_lt : SubRegIndex { let NumberHack = 1; } -def sub_gt : SubRegIndex { let NumberHack = 2; } -def sub_eq : SubRegIndex { let NumberHack = 3; } -def sub_un : SubRegIndex { let NumberHack = 4; } +def sub_lt : SubRegIndex; +def sub_gt : SubRegIndex; +def sub_eq : SubRegIndex; +def sub_un : SubRegIndex; } def : SubRegSet; let Namespace = "SystemZ" in { -def subreg_32bit : SubRegIndex { let NumberHack = 1; } -def subreg_even32 : SubRegIndex { let NumberHack = 1; } -def subreg_odd32 : SubRegIndex { let NumberHack = 2; } -def subreg_even : SubRegIndex { let NumberHack = 3; } -def subreg_odd : SubRegIndex { let NumberHack = 4; } +def subreg_32bit : SubRegIndex; +def subreg_even32 : SubRegIndex; +def subreg_odd32 : SubRegIndex; +def subreg_even : SubRegIndex; +def subreg_odd : SubRegIndex; } def : SubRegSet References: <20100525184723.847DE312800A@llvm.org> Message-ID: On May 25, 2010, at 11:47 AM, Dale Johannesen wrote: > Author: johannes > Date: Tue May 25 13:47:23 2010 > New Revision: 104624 > > URL: http://llvm.org/viewvc/llvm-project?rev=104624&view=rev > Log: > Fix another variant of PR 7191. Also add a testcase > Mon Ping provided; unfortunately bugpoint failed to > reduce it, but I think it's important to have a test for > this in the suite. 8023512. I agree that a testcase is useful, but that is too big. If you can't reduce it, please remove it. -Chris > > > Added: > llvm/trunk/test/CodeGen/X86/2010-05-25-FP_TO_INT-crash.ll > Modified: > llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=104624&r1=104623&r2=104624&view=diff > ============================================================================== > --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue May 25 13:47:23 2010 > @@ -3832,8 +3832,12 @@ > if (N0.getOpcode() == ISD::TRUNCATE) { > SDValue NarrowLoad = ReduceLoadWidth(N0.getNode()); > if (NarrowLoad.getNode()) { > - if (NarrowLoad.getNode() != N0.getNode()) > + SDNode* oye = N0.getNode()->getOperand(0).getNode(); > + if (NarrowLoad.getNode() != N0.getNode()) { > CombineTo(N0.getNode(), NarrowLoad); > + // CombineTo deleted the truncate, if needed, but not what's under it. > + AddToWorkList(oye); > + } > return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), VT, NarrowLoad); > } > } > > Added: llvm/trunk/test/CodeGen/X86/2010-05-25-FP_TO_INT-crash.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2010-05-25-FP_TO_INT-crash.ll?rev=104624&view=auto From dalej at apple.com Tue May 25 15:40:11 2010 From: dalej at apple.com (Dale Johannesen) Date: Tue, 25 May 2010 20:40:11 -0000 Subject: [llvm-commits] [llvm] r104632 - /llvm/trunk/test/CodeGen/X86/2010-05-25-FP_TO_INT-crash.ll Message-ID: <20100525204011.36BF63128026@llvm.org> Author: johannes Date: Tue May 25 15:40:10 2010 New Revision: 104632 URL: http://llvm.org/viewvc/llvm-project?rev=104632&view=rev Log: Removing test; Chris thinks it's better to have the bug go untested than have a testcase this large. So be it. Removed: llvm/trunk/test/CodeGen/X86/2010-05-25-FP_TO_INT-crash.ll Removed: llvm/trunk/test/CodeGen/X86/2010-05-25-FP_TO_INT-crash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2010-05-25-FP_TO_INT-crash.ll?rev=104631&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2010-05-25-FP_TO_INT-crash.ll (original) +++ llvm/trunk/test/CodeGen/X86/2010-05-25-FP_TO_INT-crash.ll (removed) @@ -1,2718 +0,0 @@ -; RUN: llc -O0 -march=x86 -mattr=+sse3 %s -; Formerly crashed - PR 7191 / 8023512 -; ModuleID = '' -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32" -target triple = "i386-apple-darwin11.0" - -%0 = type { i16, i16, i32 } -%1 = type { i32, i32, i16, i16, i16, i16 } -%2 = type { i16, i16, %struct.GLTColor4, %struct.GLTColor4 } -%3 = type { void (i8*, i8*, i32, i8*)*, i32 (i8*, ...)*, i8* (%struct.GLDContextRec*, %struct.GLDFramebufferRec*, i8, i32, i32)* } -%struct.GLDActiveTextureTargets = type { i64, i64, i64, i64, i64, i64 } -%struct.GLDAlphaTest = type { float, i16, i8, i8 } -%struct.GLDArrayRange = type { i8, i8, i8, i8 } -%struct.GLDBlendMode = type { i16, i16, i16, i16, %struct.GLTColor4, i16, i16, i8, i8, i8, i8 } -%struct.GLDBufferData = type { i8*, i32, i32, i16, i16, i8, i8, i8, i8 } -%struct.GLDBufferRec = type { %struct.GLDBufferData*, %struct.GLDPluginBufferData* } -%struct.GLDBufferstate = type { %struct.GLTDimensions, %struct.GLTDimensions, %struct.GLTFixedColor4, %struct.GLTFixedColor4, i8, i8, i8, i8, [0 x i32], %union.GLSBuffer, %union.GLSBuffer, %union.GLSBuffer, [8 x %union.GLSBuffer], %union.GLSBuffer } -%struct.GLDClearColor = type { double, %struct.GLTColor4, %struct.GLTColor4, float, i32 } -%struct.GLDClipPlane = type { i32, [6 x %struct.GLTColor4] } -%struct.GLDColorBuffer = type { i16, i8, i8, [8 x i16], i8, i8, i8, i8 } -%struct.GLDColorMatrix = type { [16 x float]*, %struct.GLDImagingColorScale } -%struct.GLDConfig = type { i32, float, %struct.GLTDimensions, %struct.GLTDimensions, i8, i8, i8, i8, i8, i8, i16, i32, i32, i32, %struct.GLDPixelFormatInfo, %struct.GLDPointLineLimits, %struct.GLDPointLineLimits, %struct.GLDRenderFeatures, i32, i32, i32, i32, i32, i32, i32, i32, %struct.GLDMultisamplePositions, %struct.GLDTextureLimits, [3 x %struct.GLDPipelineProgramLimits], %struct.GLDFragmentProgramLimits, %struct.GLDVertexProgramLimits, %struct.GLDGeometryShaderLimits, %struct.GLDGeometryShaderLimits, %struct.GLDTransformFeedbackLimits, i16, i8, i8, %struct.GLDVertexDescriptor*, %struct.GLDVertexDescriptor*, [4 x i32], [8 x i32], %struct.GLDMultisamplePositions* } -%struct.GLDContextRec = type { float, float, float, float, float, float, float, float, %struct.GLTColor4, %struct.GLTColor4, %struct.GLVMFPContext, [16 x [2 x %union.PPStreamToken]], %struct.GLGProcessor, %struct._GLVMConstants*, void (%struct.GLDContextRec*, i32, i32, %struct.GLVMFragmentAttribRec*, %struct.GLVMFragmentAttribRec*, i32)*, %struct._GLVMFunction*, %union.PPStreamToken*, void (%struct.GLDContextRec*, %struct.GLDVertex*)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, %struct.GLDVertex*)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, %struct.GLDVertex*, %struct.GLDVertex*)*, %struct._GLVMFunction*, %struct._GLVMFunction*, %struct._GLVMFunction*, [4 x i32], [3 x i32], [3 x i32], %union.PPStreamToken, %struct.GLDConfig*, %struct.GLDFramebufferRec*, %struct.GLDFramebufferRec*, %struct.GLDBufferstate, %struct.GLDReadBufferstate, %struct.GLDLayeredBufferstate, [64 x %struct.GLTColor4*], %struct.GLDSharedRec*, %struct.GLDState*, %struct.GLDPluginState*, %stru ct.GLDVertex*, %struct.GLVMFragmentAttribRec*, %struct.GLVMFragmentAttribRec*, %struct.GLVMFragmentAttribRec*, %struct.GLDProgramRec*, %struct.GLDPipelineProgramRec*, %struct.GLVMTextures, %struct.GLDQueryRec*, %struct.GLDQueryRec*, %struct.GLDQueryRec*, %struct.GLTDimensions, i64 ()*, %struct.GLDFallback, %3, %union.GLSDrawable, i32, float, float, %struct.GLDRect, %struct.GLDFormat, %struct.GLDFormat, %struct.GLDFormat, %struct.GLDStippleData, i32, i32, i32, i32, i16, i8, i8, i8, i8, [2 x i8], [0 x i32] } -%struct.GLDConvolution = type { %struct.GLTColor4, %struct.GLDImagingColorScale, i16, i16, [0 x i32], float*, i32, i32 } -%struct.GLDCurrent = type { [8 x %struct.GLTColor4], [16 x %struct.GLTColor4], %struct.GLTColor4, %struct.GLDPointLineLimits, float, %struct.GLDPointLineLimits, float, [4 x float], float, float, float, i8, i8, i8, i8, i32, i32, i32, i32 } -%struct.GLDDepthTest = type { i16, i16, i8, i8, i8, i8, double, double } -%struct.GLDDitherMode = type { i8, i8, i8, i8 } -%struct.GLDDrawableOffscreen = type { i32, i32, i32, [0 x i32], i8* } -%struct.GLDDrawableWindow = type { i32, i32, i32 } -%struct.GLDFallback = type { float*, %struct.GLDRenderDispatch*, %struct.GLDConfig*, i8*, i8*, i32, i32 } -%struct.GLDFixedFunction = type { %union.PPStreamToken* } -%struct.GLDFogMode = type { %struct.GLTColor4, float, float, float, float, float, i16, i16, i16, i8, i8 } -%struct.GLDFormat = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i8, i8, i8, i8, i32, i32, i32 } -%struct.GLDFragmentProgramLimits = type { i32, i32, i32, i16, i16, i32, i16, i16, i16, i16 } -%struct.GLDFramebufferAttachment = type { i16, i16, i32, i32, i32 } -%struct.GLDFramebufferData = type { [10 x %struct.GLDFramebufferAttachment], [8 x i16], i16, i16, i16, i8, i8, i32, i32, i32 } -%struct.GLDFramebufferRec = type { %struct.GLDFramebufferData*, %struct.GLDPluginFramebufferData*, [10 x %struct.GLDFormat], i8, i8, i16, [0 x i32] } -%struct.GLDGeometryShaderLimits = type { i32, i32, i32, i32, i32, i16, i16 } -%struct.GLDHintMode = type { i16, i16, i16, i16, i16, i16, i16, i16, i16, i16 } -%struct.GLDHistogram = type { %struct.GLTFixedColor4*, i32, i16, i8, i8 } -%struct.GLDImagingColorScale = type { %struct.GLDMultisamplePositions, %struct.GLDMultisamplePositions, %struct.GLDMultisamplePositions, %struct.GLDMultisamplePositions } -%struct.GLDImagingSubset = type { %struct.GLDConvolution, %struct.GLDConvolution, %struct.GLDConvolution, %struct.GLDColorMatrix, %struct.GLDMinmax, %struct.GLDHistogram, %struct.GLDImagingColorScale, %struct.GLDImagingColorScale, %struct.GLDImagingColorScale, %struct.GLDImagingColorScale, i32, [0 x i32] } -%struct.GLDLayeredBufferstate = type { %union.GLSBuffer, %union.GLSBuffer, [8 x %union.GLSBuffer] } -%struct.GLDLight = type { %struct.GLTColor4, %struct.GLTColor4, %struct.GLTColor4, %struct.GLTColor4, %struct.GLDPointLineLimits, float, float, float, float, float, %struct.GLDPointLineLimits, float, %struct.GLDPointLineLimits, float, %struct.GLDPointLineLimits, float, float, float, float, float } -%struct.GLDLightModel = type { %struct.GLTColor4, [8 x %struct.GLDLight], [2 x %struct.GLDMaterial], i32, i16, i16, i16, i8, i8, i8, i8, i8, i8 } -%struct.GLDLightProduct = type { %struct.GLTColor4, %struct.GLTColor4, %struct.GLTColor4 } -%struct.GLDLineMode = type { float, i32, i16, i16, i8, i8, i8, i8 } -%struct.GLDLogicOp = type { i16, i8, i8 } -%struct.GLDMaskMode = type { i32, [3 x i32], i8, i8, i8, i8, i8, i8, i8, i8 } -%struct.GLDMaterial = type { %struct.GLTColor4, %struct.GLTColor4, %struct.GLTColor4, %struct.GLTColor4, float, float, float, float, [8 x %struct.GLDLightProduct], %struct.GLTColor4, [8 x i32] } -%struct.GLDMinmax = type { %struct.GLDMinmaxTable*, i16, i8, i8, [0 x i32] } -%struct.GLDMinmaxTable = type { %struct.GLTColor4, %struct.GLTColor4 } -%struct.GLDMipmaplevel = type { [4 x i32], [4 x i32], [4 x float], [4 x i32], i32, i32, float*, i8*, i16, i16, i16, i16, [2 x float] } -%struct.GLDMultisample = type { float, [1 x i32], [0 x i32], i8, i8, i8, i8, i8, i8, i8, i8 } -%struct.GLDMultisamplePositions = type { float, float } -%struct.GLDPipelineProgramData = type { i16, i8, i8, i32, %union.PPStreamToken*, i64, %struct.GLTColor4*, i32, [0 x i32] } -%struct.GLDPipelineProgramLimits = type { i32, i16, i16, i32, i16, i16, i32, i32 } -%struct.GLDPipelineProgramRec = type { %struct.GLDPipelineProgramData*, %union.PPStreamToken*, %struct.GLDContextRec*, %struct.GLVMProgramData*, i32, i32 } -%struct.GLDPipelineProgramState = type { i8, i8, i8, i8, [0 x i32], %struct.GLTColor4* } -%struct.GLDPixelFormatInfo = type { i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8 } -%struct.GLDPixelMap = type { i32*, float*, float*, float*, float*, float*, float*, float*, float*, i32*, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } -%struct.GLDPixelMode = type { float, float, %struct.GLDPixelStore, %struct.GLDPixelTransfer, %struct.GLDPixelMap, %struct.GLDImagingSubset, i32, [0 x i32] } -%struct.GLDPixelPack = type { i32, i32, i32, i32, i32, i32, i32, i32, i8, i8, i8, i8 } -%struct.GLDPixelStore = type { %struct.GLDPixelPack, %struct.GLDPixelPack } -%struct.GLDPixelTransfer = type { float, float, float, float, float, float, float, float, float, float, i32, i32 } -%struct.GLDPluginBufferData = type { i32 } -%struct.GLDPluginFramebufferData = type { [10 x %struct.GLDTextureRec*], i8, i8, i8, i8 } -%struct.GLDPluginProgramData = type { [3 x %struct.GLDPipelineProgramRec*], %struct.GLDBufferRec**, i32, [0 x i32] } -%struct.GLDPluginState = type { [16 x [11 x %struct.GLDTextureRec*]], [3 x %struct.GLDTextureRec*], [3 x %struct.GLDPipelineProgramRec*], [3 x %struct.GLDPipelineProgramRec*], %struct.GLDProgramRec*, %struct.GLDVertexArrayRec*, [16 x %struct.GLDBufferRec*], %struct.GLDFramebufferRec*, %struct.GLDFramebufferRec*, [6 x %struct.GLDQueryRec*], [64 x %struct.GLDBufferRec*] } -%struct.GLDPluginTextureState = type { %struct.GLDBufferRec*, [6 x i16], i8, i8, i16 } -%struct.GLDPointLineLimits = type { float, float, float } -%struct.GLDPointMode = type { float, float, float, float, %struct.GLDPointLineLimits, float, i8, i8, i8, i8, i16, i16, i32, i16, i16 } -%struct.GLDPolygonMode = type { [128 x i8], float, float, i16, i16, i16, i16, i8, i8, i8, i8, i8, i8, i8, i8 } -%struct.GLDPolygonOffset = type { float, float } -%struct.GLDPrimitiveRestart = type { i8, i8, i8, i8, i32 } -%struct.GLDProgramData = type { i32, i32, i32, i32, %union.PPStreamToken*, i32*, i32, i32, i32, i32, i8, i8, i8, i8, i32, [64 x i32] } -%struct.GLDProgramLimits = type { i32, i32, i32, i32, i32, i16, i16 } -%struct.GLDProgramRec = type { %struct.GLDProgramData*, %struct.GLDPluginProgramData*, i32, [0 x i32] } -%struct.GLDProgramState = type { i8, i8, i8, i8 } -%struct.GLDQueryRec = type { i64, i64, i64 } -%struct.GLDQueryState = type { i16, i16 } -%struct.GLDReadBufferstate = type { %struct.GLTDimensions, %struct.GLTDimensions, %union.GLSBuffer, %union.GLSBuffer, %union.GLSBuffer, %union.GLSBuffer } -%struct.GLDRect = type { i32, i32, i32, i32, i32, i32 } -%struct.GLDRenderDispatch = type { void (%struct.GLDContextRec*, i32, float)*, void (%struct.GLDContextRec*, i32)*, i32 (%struct.GLDContextRec*, %struct.GLDMultisamplePositions*, i32, i32, i32, i32, i8*, i32, %struct.GLDBufferRec*)*, void (%struct.GLDContextRec*, %struct.GLDMultisamplePositions*, i32, i32, i32, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, %struct.GLDVertex*, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, i32, i32)*, void (%struct.GLDContext Rec*, %struct.GLDVertex*, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex*, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex**, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex**, i32, i32)*, void (%struct.GLDContextRec*, %struct.GLDVertex**, i32, i32)*, i8* (%struct.GLDContextRec*, i32, i32*)*, void (%struct.GLDContextRec*, i32, i32, i32)*, i8* (%struct.GLDContextRec*, i32, i32, i32, i32, i32)*, void (%struct.GLDContextRec*, i32, i32, i32, i32, i32, i8*)*, void (%struct.GLDContextRec*)*, void (%struct.GLDContextRec*)*, void (%struct.GLDContextRec*)*, i32 (%struct.GLDContextRec*, i32, i32, i32, i32, i32, i8*, %struct.GLTColor4*, i32)*, i32 (%struct.GLDContextRec*, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32)* } -%struct.GLDRenderFeatures = type { i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8 } -%struct.GLDScissorTest = type { %struct.GLTFixedColor4, i8, i8, i8, i8 } -%struct.GLDSeamlessCubemap = type { i8, i8, i16 } -%struct.GLDSharedData = type {} -%struct.GLDSharedRec = type { %struct.pthread_mutex_t, %struct.GLDSharedData*, %struct.GLGProcessor, i32, i16, i16, i8, i8, i8, i8, [0 x i32] } -%struct.GLDState = type <{ i16, i16, i16, i16, i32, i32, [256 x %struct.GLTColor4], [128 x %struct.GLTColor4], %struct.GLDCurrent, %struct.GLDViewport, %struct.GLDTransform, %struct.GLDLightModel, %struct.GLDActiveTextureTargets, %struct.GLDAlphaTest, %struct.GLDBlendMode, %struct.GLDClearColor, %struct.GLDColorBuffer, %struct.GLDDepthTest, %struct.GLDArrayRange, %struct.GLDFogMode, %struct.GLDHintMode, %struct.GLDLineMode, %struct.GLDLogicOp, %struct.GLDMaskMode, %struct.GLDPixelMode, %struct.GLDPointMode, %struct.GLDPolygonMode, %struct.GLDScissorTest, i32, %struct.GLDStencilTest, [8 x %struct.GLDTextureMode], [16 x %struct.GLDTextureImageMode], [8 x %struct.GLDTextureCoordGen], %struct.GLDClipPlane, %struct.GLDMultisample, %struct.GLDArrayRange, %struct.GLDArrayRange, [3 x %struct.GLDPipelineProgramState], %struct.GLDArrayRange, %struct.GLDTransformFeedback, %struct.GLDUniformBuffer, i32*, %struct.GLDFixedFunction, i32, %struct.GLDQueryState, %struct.GLDSeamlessCubemap, % struct.GLDPrimitiveRestart, [2 x i32] }> -%struct.GLDStencilTest = type { [3 x %1], i32, [4 x i8] } -%struct.GLDStippleData = type { i32, i16, i16, [32 x [32 x i8]] } -%struct.GLDTextureCoordGen = type { %2, %2, %2, %2, i8, i8, i8, i8 } -%struct.GLDTextureGeomState = type { i16, i16, i16, i16, i16, i8, i8, i8, i8, i16, i16, i16, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i16, [6 x i16], [6 x i16] } -%struct.GLDTextureImageMode = type { float } -%struct.GLDTextureLevel = type { i32, i32, i16, i16, i16, i8, i8, i16, i16, i16, i16, i8* } -%struct.GLDTextureLimits = type { float, float, i16, i16, i16, i16, i16, i16, i16, i16, i16, i8, i8, i8, i8, i8, i8, i32, i32 } -%struct.GLDTextureMode = type { %struct.GLTColor4, i32, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, float, float } -%struct.GLDTextureParamState = type { i16, i16, i16, i16, i16, i16, %struct.GLTColor4, float, float, float, float, i16, i16, i16, i16, float, i16, i16, i32, i8* } -%struct.GLDTextureRec = type { [4 x float], %struct.GLDTextureState*, %struct.GLDPluginTextureState*, %struct.GLDMipmaplevel*, %struct.GLDMipmaplevel*, float, float, float, float, i8, i8, i8, i8, i16, i16, i16, i16, i32, float, [0 x i32], [2 x %union.PPStreamToken] } -%struct.GLDTextureState = type { i16, i8, i8, i16, i16, float, i32, %struct.GLISWRSurface*, %struct.GLDTextureParamState, %struct.GLDTextureGeomState, i16, i16, i8*, %struct.GLDTextureLevel, [1 x [15 x %struct.GLDTextureLevel]] } -%struct.GLDTransform = type <{ [24 x [16 x float]], [24 x [16 x float]], [16 x float], float, float, float, float, float, i8, i8, i8, i8, i32, i32, i32, i16, i16, i8, i8, i8, i8, i32 }> -%struct.GLDTransformFeedback = type { i8, i8, i16, [0 x i32], [16 x i32], [16 x i32] } -%struct.GLDTransformFeedbackLimits = type { i32, i32, i32, i32, i32 } -%struct.GLDUniformBuffer = type { [64 x %struct.GLTDimensions] } -%struct.GLDVertex = type { %struct.GLTColor4, %struct.GLTColor4, %struct.GLTColor4, %struct.GLTColor4, %struct.GLTColor4, %struct.GLDPointLineLimits, float, %struct.GLTColor4, float, i8, i8, i8, i8, float, float, i32, i32, i32, [4 x i8], [4 x float], [2 x %struct.GLDMaterial*], [2 x i32], [16 x %struct.GLTColor4] } -%struct.GLDVertexArrayRec = type opaque -%struct.GLDVertexBlend = type { i8, i8, i8, i8 } -%struct.GLDVertexDescriptor = type { i8, i8, i8, i8, [0 x i32] } -%struct.GLDVertexProgramLimits = type { i16, i16, i32, i32, i16, i16 } -%struct.GLDViewport = type { float, float, float, float, float, float, float, float, float, float, float, float, float, float, float, float, double, double, i32, i32, i32, i32, float, float, float, float } -%struct.GLGColorTable = type { i32, i32, i32, i8* } -%struct.GLGOperation = type { i8*, i8*, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, float, float, %struct.GLGColorTable, %struct.GLGColorTable, %struct.GLGColorTable } -%struct.GLGProcessor = type { void (%struct.GLDPixelMode*, %struct.GLGOperation*, %struct._GLGProcessorData*, %union._GLGFunctionKey*)*, %struct._GLVMFunction*, %union._GLGFunctionKey*, %struct._GLGProcessorData* } -%struct.GLISWRSurface = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i8*, i8*, i8*, [4 x i8*], i32 } -%struct.GLSGenericRec = type { %struct.GLTDimensions, %struct.GLTDimensions, i32, i32, %union.GLSDrawable, i8*, i8*, i8*, i8*, i8*, [4 x i8*], i32, i16, i16, i16, i16, i8, i8, i8, i8, i8, i8, i8, i8 } -%struct.GLSOffScreenRec = type { %struct.GLTDimensions, %struct.GLTDimensions, i32, i32, %union.GLSDrawable, i8*, i8*, i8*, i8*, i8*, [4 x i8*], i32, i16, i16, i16, i16, i8, i8, i8, i8, i8, i8, i8, i8, %struct.GLDDrawableOffscreen } -%struct.GLSSWRSurfaceRec = type { %struct.GLTDimensions, %struct.GLTDimensions, i32, i32, %union.GLSDrawable, i8*, i8*, i8*, i8*, i8*, [4 x i8*], i32, i16, i16, i16, i16, i8, i8, i8, i8, i8, i8, i8, i8, %struct.GLISWRSurface*, i32, i32 } -%struct.GLSWindowRec = type { %struct.GLTDimensions, %struct.GLTDimensions, i32, i32, %union.GLSDrawable, i8*, i8*, i8*, i8*, i8*, [4 x i8*], i32, i16, i16, i16, i16, i8, i8, i8, i8, i8, i8, i8, i8, %struct.GLDDrawableWindow, i32, i32, [0 x i32], i8*, i8* } -%struct.GLTColor3 = type { float, float, float } -%struct.GLTColor4 = type { float, float, float, float } -%struct.GLTCoord2 = type { float, float } -%struct.GLTCoord3 = type { float, float, float } -%struct.GLTCoord4 = type { float, float, float, float } -%struct.GLTDimensions = type { i32, i32 } -%struct.GLTFixedColor4 = type { i32, i32, i32, i32 } -%struct.GLTPlane = type { float, float, float, float } -%struct.GLTRectangle = type { i32, i32, i32, i32 } -%struct.GLTTexCoord4 = type { float, float, float, float } -%struct.GLVMFPContext = type { float, i32, i32, i32, i32, [3 x i32] } -%struct.GLVMFragmentAttribRec = type opaque -%struct.GLVMProgramData = type { %struct._GLVMFunction*, %struct.GLVMProgramData*, %struct.GLVMProgramData*, [42 x i32], [64 x i32], i32, i32, i32, [0 x i32] } -%struct.GLVMTextures = type { [16 x %struct.GLDTextureRec*] } -%struct._GLGProcessorData = type opaque -%struct._GLVMConstants = type opaque -%struct._GLVMFunction = type opaque -%struct.anon = type { float, float, float, float } -%struct.mach_timebase_info_data_t = type { i32, i32 } -%struct.pthread_mutex_t = type { i32, [40 x i8] } -%union.GLSBuffer = type { i8* } -%union.GLSDrawable = type { %struct.GLSWindowRec* } -%union.PPStreamToken = type { %0 } -%union._GLGFunctionKey = type opaque -%union.anon = type { %struct.GLTDimensions } - -declare i16 @_OSSwapInt16(i16 zeroext %_data) nounwind inlinehint ssp - -declare i32 @_OSSwapInt32(i32 %_data) nounwind inlinehint ssp - -declare i32 @llvm.bswap.i32(i32) nounwind readnone - -define void @gldAccumReturn(%struct.GLDContextRec* %ctx, %struct.GLDState* %state, float %value) nounwind ssp { -entry: - %ctx_addr = alloca %struct.GLDContextRec* ; <%struct.GLDContextRec**> [#uses=99] - %state_addr = alloca %struct.GLDState* ; <%struct.GLDState**> [#uses=21] - %value_addr = alloca float ; [#uses=33] - %iftmp.210 = alloca float ; [#uses=3] - %iftmp.209 = alloca float ; [#uses=3] - %iftmp.208 = alloca float ; [#uses=3] - %iftmp.207 = alloca float ; [#uses=3] - %iftmp.206 = alloca float ; [#uses=3] - %iftmp.205 = alloca float ; [#uses=3] - %iftmp.204 = alloca float ; [#uses=3] - %iftmp.203 = alloca float ; [#uses=3] - %iftmp.202 = alloca float ; [#uses=3] - %iftmp.201 = alloca float ; [#uses=3] - %iftmp.200 = alloca float ; [#uses=3] - %iftmp.199 = alloca float ; [#uses=3] - %iftmp.198 = alloca float ; [#uses=3] - %iftmp.197 = alloca float ; [#uses=3] - %iftmp.196 = alloca float ; [#uses=3] - %iftmp.195 = alloca float ; [#uses=3] - %iftmp.192 = alloca i8 ; [#uses=3] - %iftmp.190 = alloca i32 ; [#uses=3] - %iftmp.189 = alloca i32 ; [#uses=3] - %iftmp.188 = alloca i32 ; [#uses=3] - %iftmp.187 = alloca i32 ; [#uses=3] - %iftmp.186 = alloca i32 ; [#uses=3] - %iftmp.185 = alloca i32 ; [#uses=3] - %iftmp.184 = alloca i32 ; [#uses=3] - %iftmp.183 = alloca i32 ; [#uses=3] - %iftmp.182 = alloca i8 ; [#uses=3] - %iftmp.181 = alloca i8 ; [#uses=3] - %iftmp.180 = alloca i8 ; [#uses=3] - %iftmp.179 = alloca i8 ; [#uses=3] - %iftmp.178 = alloca i8 ; [#uses=3] - %iftmp.177 = alloca i8 ; [#uses=3] - %iftmp.176 = alloca i8 ; [#uses=3] - %iftmp.175 = alloca i8 ; [#uses=3] - %iftmp.174 = alloca i8 ; [#uses=3] - %iftmp.173 = alloca i8 ; [#uses=3] - %iftmp.172 = alloca i8 ; [#uses=3] - %iftmp.171 = alloca i8 ; [#uses=3] - %iftmp.170 = alloca i8 ; [#uses=3] - %iftmp.169 = alloca i8 ; [#uses=3] - %iftmp.168 = alloca i8 ; [#uses=3] - %iftmp.167 = alloca i8 ; [#uses=3] - %iftmp.164 = alloca i8 ; [#uses=3] - %iftmp.163 = alloca float ; [#uses=3] - %iftmp.162 = alloca float ; [#uses=3] - %iftmp.161 = alloca float ; [#uses=3] - %iftmp.160 = alloca float ; [#uses=3] - %iftmp.159 = alloca float ; [#uses=3] - %iftmp.158 = alloca float ; [#uses=3] - %iftmp.157 = alloca float ; [#uses=3] - %iftmp.156 = alloca float ; [#uses=3] - %iftmp.155 = alloca float ; [#uses=3] - %iftmp.154 = alloca float ; [#uses=3] - %iftmp.153 = alloca float ; [#uses=3] - %iftmp.152 = alloca float ; [#uses=3] - %iftmp.151 = alloca float ; [#uses=3] - %iftmp.150 = alloca float ; [#uses=3] - %iftmp.149 = alloca float ; [#uses=3] - %iftmp.148 = alloca float ; [#uses=3] - %iftmp.145 = alloca i8 ; [#uses=3] - %iftmp.144 = alloca i8 ; [#uses=3] - %iftmp.141 = alloca i8 ; [#uses=3] - %iftmp.140 = alloca i32 ; [#uses=3] - %accum = alloca double* ; [#uses=56] - %accum_end = alloca double* ; [#uses=9] - %y = alloca i32 ; [#uses=12] - %yl = alloca i32 ; [#uses=4] - %cw4 = alloca i32 ; [#uses=4] - %cx = alloca i32 ; [#uses=2] - %cy = alloca i32 ; [#uses=7] - %ch = alloca i32 ; [#uses=3] - %cw = alloca i32 ; [#uses=3] - %offset = alloca i32 ; [#uses=19] - %y_inc = alloca i32 ; [#uses=6] - %swap = alloca i8 ; [#uses=6] - %draw_buffer = alloca i32 ; [#uses=21] - %all_bits_mask = alloca i32 ; [#uses=9] - %color_mask_enabled = alloca i8 ; [#uses=4] - %color_ptr = alloca i16* ; [#uses=8] - %thirtyOne = alloca float ; [#uses=23] - %start_offset = alloca i32 ; [#uses=2] - %cur_draw_buffer_mask_bit = alloca i32 ; [#uses=5] - %r = alloca float ; [#uses=12] - %g = alloca float ; [#uses=12] - %b = alloca float ; [#uses=12] - %a = alloca float ; [#uses=12] - %pixl = alloca i16 ; [#uses=24] - %color_ptr111 = alloca i8* ; [#uses=14] - %twoFiftyFive = alloca float ; [#uses=17] - %start_offset112 = alloca i32 ; [#uses=2] - %cur_draw_buffer_mask_bit115 = alloca i32 ; [#uses=9] - %r119 = alloca float ; [#uses=7] - %g120 = alloca float ; [#uses=7] - %b121 = alloca float ; [#uses=7] - %a122 = alloca float ; [#uses=7] - %r193 = alloca i32 ; [#uses=2] - %g194 = alloca i32 ; [#uses=2] - %b195 = alloca i32 ; [#uses=2] - %a196 = alloca i32 ; [#uses=2] - %color = alloca i32 ; [#uses=4] - %color_ptr235 = alloca float* ; [#uses=13] - %start_offset236 = alloca i32 ; [#uses=2] - %cur_draw_buffer_mask_bit239 = alloca i32 ; [#uses=5] - %r243 = alloca float ; [#uses=4] - %g244 = alloca float ; [#uses=4] - %b245 = alloca float ; [#uses=4] - %a246 = alloca float ; [#uses=4] - %r283 = alloca float ; [#uses=4] - %g284 = alloca float ; [#uses=4] - %b285 = alloca float ; [#uses=4] - %a286 = alloca float ; [#uses=4] - %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] - store %struct.GLDContextRec* %ctx, %struct.GLDContextRec** %ctx_addr - store %struct.GLDState* %state, %struct.GLDState** %state_addr - store float %value, float* %value_addr - %0 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %1 = getelementptr inbounds %struct.GLDContextRec* %0, i32 0, i32 51 ; <%union.GLSDrawable*> [#uses=1] - %2 = getelementptr inbounds %union.GLSDrawable* %1, i32 0, i32 0 ; <%struct.GLSWindowRec**> [#uses=1] - %3 = bitcast %struct.GLSWindowRec** %2 to %struct.GLSGenericRec** ; <%struct.GLSGenericRec**> [#uses=1] - %4 = load %struct.GLSGenericRec** %3, align 4 ; <%struct.GLSGenericRec*> [#uses=1] - %5 = getelementptr inbounds %struct.GLSGenericRec* %4, i32 0, i32 16 ; [#uses=1] - %6 = load i8* %5, align 4 ; [#uses=1] - store i8 %6, i8* %swap, align 1 - store i32 255, i32* %all_bits_mask, align 4 - %7 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] - %8 = getelementptr inbounds %struct.GLDState* %7, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] - %9 = getelementptr inbounds %struct.GLDMaskMode* %8, i32 0, i32 5 ; [#uses=1] - %10 = load i8* %9, align 1 ; [#uses=1] - %11 = zext i8 %10 to i32 ; [#uses=1] - %12 = load i32* %all_bits_mask, align 4 ; [#uses=1] - %13 = and i32 %11, %12 ; [#uses=1] - %14 = load i32* %all_bits_mask, align 4 ; [#uses=1] - %15 = icmp ne i32 %13, %14 ; [#uses=1] - %16 = zext i1 %15 to i8 ; [#uses=1] - %17 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] - %18 = getelementptr inbounds %struct.GLDState* %17, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] - %19 = getelementptr inbounds %struct.GLDMaskMode* %18, i32 0, i32 2 ; [#uses=1] - %20 = load i8* %19, align 16 ; [#uses=1] - %21 = zext i8 %20 to i32 ; [#uses=1] - %22 = load i32* %all_bits_mask, align 4 ; [#uses=1] - %23 = and i32 %21, %22 ; [#uses=1] - %24 = load i32* %all_bits_mask, align 4 ; [#uses=1] - %25 = icmp ne i32 %23, %24 ; [#uses=1] - %26 = zext i1 %25 to i8 ; [#uses=1] - %toBool = icmp ne i8 %16, 0 ; [#uses=1] - %toBool1 = icmp ne i8 %26, 0 ; [#uses=1] - %27 = or i1 %toBool, %toBool1 ; [#uses=1] - %28 = zext i1 %27 to i8 ; [#uses=1] - %29 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] - %30 = getelementptr inbounds %struct.GLDState* %29, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] - %31 = getelementptr inbounds %struct.GLDMaskMode* %30, i32 0, i32 4 ; [#uses=1] - %32 = load i8* %31, align 2 ; [#uses=1] - %33 = zext i8 %32 to i32 ; [#uses=1] - %34 = load i32* %all_bits_mask, align 4 ; [#uses=1] - %35 = and i32 %33, %34 ; [#uses=1] - %36 = load i32* %all_bits_mask, align 4 ; [#uses=1] - %37 = icmp ne i32 %35, %36 ; [#uses=1] - %38 = zext i1 %37 to i8 ; [#uses=1] - %toBool2 = icmp ne i8 %28, 0 ; [#uses=1] - %toBool3 = icmp ne i8 %38, 0 ; [#uses=1] - %39 = or i1 %toBool2, %toBool3 ; [#uses=1] - %40 = zext i1 %39 to i8 ; [#uses=1] - %41 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] - %42 = getelementptr inbounds %struct.GLDState* %41, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] - %43 = getelementptr inbounds %struct.GLDMaskMode* %42, i32 0, i32 3 ; [#uses=1] - %44 = load i8* %43, align 1 ; [#uses=1] - %45 = zext i8 %44 to i32 ; [#uses=1] - %46 = load i32* %all_bits_mask, align 4 ; [#uses=1] - %47 = and i32 %45, %46 ; [#uses=1] - %48 = load i32* %all_bits_mask, align 4 ; [#uses=1] - %49 = icmp ne i32 %47, %48 ; [#uses=1] - %50 = zext i1 %49 to i8 ; [#uses=1] - %toBool4 = icmp ne i8 %40, 0 ; [#uses=1] - %toBool5 = icmp ne i8 %50, 0 ; [#uses=1] - %51 = or i1 %toBool4, %toBool5 ; [#uses=1] - %52 = zext i1 %51 to i8 ; [#uses=1] - store i8 %52, i8* %color_mask_enabled, align 1 - %53 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %54 = getelementptr inbounds %struct.GLDContextRec* %53, i32 0, i32 55 ; <%struct.GLDRect*> [#uses=1] - %55 = getelementptr inbounds %struct.GLDRect* %54, i32 0, i32 0 ; [#uses=1] - %56 = load i32* %55, align 4 ; [#uses=1] - store i32 %56, i32* %cx, align 4 - %57 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %58 = getelementptr inbounds %struct.GLDContextRec* %57, i32 0, i32 55 ; <%struct.GLDRect*> [#uses=1] - %59 = getelementptr inbounds %struct.GLDRect* %58, i32 0, i32 1 ; [#uses=1] - %60 = load i32* %59, align 4 ; [#uses=1] - store i32 %60, i32* %cy, align 4 - %61 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %62 = getelementptr inbounds %struct.GLDContextRec* %61, i32 0, i32 55 ; <%struct.GLDRect*> [#uses=1] - %63 = getelementptr inbounds %struct.GLDRect* %62, i32 0, i32 4 ; [#uses=1] - %64 = load i32* %63, align 4 ; [#uses=1] - store i32 %64, i32* %cw, align 4 - %65 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %66 = getelementptr inbounds %struct.GLDContextRec* %65, i32 0, i32 55 ; <%struct.GLDRect*> [#uses=1] - %67 = getelementptr inbounds %struct.GLDRect* %66, i32 0, i32 5 ; [#uses=1] - %68 = load i32* %67, align 4 ; [#uses=1] - store i32 %68, i32* %ch, align 4 - %69 = load i32* %cw, align 4 ; [#uses=1] - %70 = icmp eq i32 %69, 0 ; [#uses=1] - br i1 %70, label %bb6, label %bb - -bb: ; preds = %entry - %71 = load i32* %ch, align 4 ; [#uses=1] - %72 = icmp eq i32 %71, 0 ; [#uses=1] - br i1 %72, label %bb6, label %bb7 - -bb6: ; preds = %bb, %entry - br label %bb316 - -bb7: ; preds = %bb - %73 = load i32* %cw, align 4 ; [#uses=1] - %74 = mul i32 %73, 4 ; [#uses=1] - store i32 %74, i32* %cw4, align 4 - %75 = load i32* %cy, align 4 ; [#uses=1] - %76 = load i32* %ch, align 4 ; [#uses=1] - %77 = add i32 %75, %76 ; [#uses=1] - store i32 %77, i32* %yl, align 4 - %78 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %79 = getelementptr inbounds %struct.GLDContextRec* %78, i32 0, i32 30 ; <%struct.GLDBufferstate*> [#uses=1] - %80 = getelementptr inbounds %struct.GLDBufferstate* %79, i32 0, i32 1 ; <%struct.GLTDimensions*> [#uses=1] - %81 = getelementptr inbounds %struct.GLTDimensions* %80, i32 0, i32 0 ; [#uses=1] - %82 = load i32* %81, align 4 ; [#uses=1] - %83 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %84 = getelementptr inbounds %struct.GLDContextRec* %83, i32 0, i32 28 ; <%struct.GLDFramebufferRec**> [#uses=1] - %85 = load %struct.GLDFramebufferRec** %84, align 4 ; <%struct.GLDFramebufferRec*> [#uses=1] - %86 = icmp ne %struct.GLDFramebufferRec* %85, null ; [#uses=1] - br i1 %86, label %bb8, label %bb9 - -bb8: ; preds = %bb7 - %87 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %88 = getelementptr inbounds %struct.GLDContextRec* %87, i32 0, i32 57 ; <%struct.GLDFormat*> [#uses=1] - %89 = getelementptr inbounds %struct.GLDFormat* %88, i32 0, i32 12 ; [#uses=1] - %90 = load i8* %89, align 2 ; [#uses=1] - %91 = icmp ne i8 %90, 0 ; [#uses=1] - %92 = zext i1 %91 to i8 ; [#uses=1] - store i8 %92, i8* %iftmp.141, align 1 - br label %bb10 - -bb9: ; preds = %bb7 - %93 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %94 = getelementptr inbounds %struct.GLDContextRec* %93, i32 0, i32 56 ; <%struct.GLDFormat*> [#uses=1] - %95 = getelementptr inbounds %struct.GLDFormat* %94, i32 0, i32 12 ; [#uses=1] - %96 = load i8* %95, align 2 ; [#uses=1] - %97 = icmp ne i8 %96, 0 ; [#uses=1] - %98 = zext i1 %97 to i8 ; [#uses=1] - store i8 %98, i8* %iftmp.141, align 1 - br label %bb10 - -bb10: ; preds = %bb9, %bb8 - %99 = load i8* %iftmp.141, align 1 ; [#uses=1] - %toBool11 = icmp ne i8 %99, 0 ; [#uses=1] - br i1 %toBool11, label %bb12, label %bb13 - -bb12: ; preds = %bb10 - %100 = load i32* %cy, align 4 ; [#uses=1] - store i32 %100, i32* %iftmp.140, align 4 - br label %bb14 - -bb13: ; preds = %bb10 - %101 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %102 = getelementptr inbounds %struct.GLDContextRec* %101, i32 0, i32 30 ; <%struct.GLDBufferstate*> [#uses=1] - %103 = getelementptr inbounds %struct.GLDBufferstate* %102, i32 0, i32 1 ; <%struct.GLTDimensions*> [#uses=1] - %104 = getelementptr inbounds %struct.GLTDimensions* %103, i32 0, i32 1 ; [#uses=1] - %105 = load i32* %104, align 4 ; [#uses=1] - %106 = sub nsw i32 %105, 1 ; [#uses=1] - %107 = load i32* %cy, align 4 ; [#uses=1] - %108 = sub nsw i32 %106, %107 ; [#uses=1] - store i32 %108, i32* %iftmp.140, align 4 - br label %bb14 - -bb14: ; preds = %bb13, %bb12 - %109 = load i32* %iftmp.140, align 4 ; [#uses=1] - %110 = mul nsw i32 %82, %109 ; [#uses=1] - %111 = load i32* %cx, align 4 ; [#uses=1] - %112 = add nsw i32 %110, %111 ; [#uses=1] - store i32 %112, i32* %offset, align 4 - %113 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %114 = getelementptr inbounds %struct.GLDContextRec* %113, i32 0, i32 30 ; <%struct.GLDBufferstate*> [#uses=1] - %115 = getelementptr inbounds %struct.GLDBufferstate* %114, i32 0, i32 1 ; <%struct.GLTDimensions*> [#uses=1] - %116 = getelementptr inbounds %struct.GLTDimensions* %115, i32 0, i32 0 ; [#uses=1] - %117 = load i32* %116, align 4 ; [#uses=1] - store i32 %117, i32* %y_inc, align 4 - %118 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %119 = getelementptr inbounds %struct.GLDContextRec* %118, i32 0, i32 28 ; <%struct.GLDFramebufferRec**> [#uses=1] - %120 = load %struct.GLDFramebufferRec** %119, align 4 ; <%struct.GLDFramebufferRec*> [#uses=1] - %121 = icmp ne %struct.GLDFramebufferRec* %120, null ; [#uses=1] - br i1 %121, label %bb15, label %bb16 - -bb15: ; preds = %bb14 - %122 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %123 = getelementptr inbounds %struct.GLDContextRec* %122, i32 0, i32 57 ; <%struct.GLDFormat*> [#uses=1] - %124 = getelementptr inbounds %struct.GLDFormat* %123, i32 0, i32 12 ; [#uses=1] - %125 = load i8* %124, align 2 ; [#uses=1] - %126 = icmp eq i8 %125, 0 ; [#uses=1] - %127 = zext i1 %126 to i8 ; [#uses=1] - store i8 %127, i8* %iftmp.144, align 1 - br label %bb17 - -bb16: ; preds = %bb14 - %128 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %129 = getelementptr inbounds %struct.GLDContextRec* %128, i32 0, i32 56 ; <%struct.GLDFormat*> [#uses=1] - %130 = getelementptr inbounds %struct.GLDFormat* %129, i32 0, i32 12 ; [#uses=1] - %131 = load i8* %130, align 2 ; [#uses=1] - %132 = icmp eq i8 %131, 0 ; [#uses=1] - %133 = zext i1 %132 to i8 ; [#uses=1] - store i8 %133, i8* %iftmp.144, align 1 - br label %bb17 - -bb17: ; preds = %bb16, %bb15 - %134 = load i8* %iftmp.144, align 1 ; [#uses=1] - %toBool18 = icmp ne i8 %134, 0 ; [#uses=1] - br i1 %toBool18, label %bb19, label %bb20 - -bb19: ; preds = %bb17 - %135 = load i32* %y_inc, align 4 ; [#uses=1] - %136 = sub i32 0, %135 ; [#uses=1] - store i32 %136, i32* %y_inc, align 4 - br label %bb20 - -bb20: ; preds = %bb19, %bb17 - %137 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %138 = getelementptr inbounds %struct.GLDContextRec* %137, i32 0, i32 28 ; <%struct.GLDFramebufferRec**> [#uses=1] - %139 = load %struct.GLDFramebufferRec** %138, align 4 ; <%struct.GLDFramebufferRec*> [#uses=1] - %140 = icmp ne %struct.GLDFramebufferRec* %139, null ; [#uses=1] - br i1 %140, label %bb21, label %bb22 - -bb21: ; preds = %bb20 - %141 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %142 = getelementptr inbounds %struct.GLDContextRec* %141, i32 0, i32 28 ; <%struct.GLDFramebufferRec**> [#uses=1] - %143 = load %struct.GLDFramebufferRec** %142, align 4 ; <%struct.GLDFramebufferRec*> [#uses=1] - %144 = getelementptr inbounds %struct.GLDFramebufferRec* %143, i32 0, i32 2 ; <[10 x %struct.GLDFormat]*> [#uses=1] - %145 = getelementptr inbounds [10 x %struct.GLDFormat]* %144, i32 0, i32 0 ; <%struct.GLDFormat*> [#uses=1] - %146 = getelementptr inbounds %struct.GLDFormat* %145, i32 0, i32 7 ; [#uses=1] - %147 = load i32* %146, align 4 ; [#uses=1] - %148 = icmp eq i32 %147, 33638 ; [#uses=1] - %149 = zext i1 %148 to i8 ; [#uses=1] - store i8 %149, i8* %iftmp.145, align 1 - br label %bb23 - -bb22: ; preds = %bb20 - %150 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %151 = getelementptr inbounds %struct.GLDContextRec* %150, i32 0, i32 56 ; <%struct.GLDFormat*> [#uses=1] - %152 = getelementptr inbounds %struct.GLDFormat* %151, i32 0, i32 7 ; [#uses=1] - %153 = load i32* %152, align 4 ; [#uses=1] - %154 = icmp eq i32 %153, 33638 ; [#uses=1] - %155 = zext i1 %154 to i8 ; [#uses=1] - store i8 %155, i8* %iftmp.145, align 1 - br label %bb23 - -bb23: ; preds = %bb22, %bb21 - %156 = load i8* %iftmp.145, align 1 ; [#uses=1] - %toBool24 = icmp ne i8 %156, 0 ; [#uses=1] - br i1 %toBool24, label %bb25, label %bb105 - -bb25: ; preds = %bb23 - %157 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %158 = getelementptr inbounds %struct.GLDContextRec* %157, i32 0, i32 6 ; [#uses=1] - %159 = load float* %158, align 4 ; [#uses=1] - store float %159, float* %thirtyOne, align 4 - %160 = load i32* %offset, align 4 ; [#uses=1] - store i32 %160, i32* %start_offset, align 4 - store i32 0, i32* %draw_buffer, align 4 - br label %bb104 - -bb26: ; preds = %bb104 - %161 = load i32* %start_offset, align 4 ; [#uses=1] - store i32 %161, i32* %offset, align 4 - %162 = load i32* %draw_buffer, align 4 ; [#uses=1] - %163 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %164 = getelementptr inbounds %struct.GLDContextRec* %163, i32 0, i32 30 ; <%struct.GLDBufferstate*> [#uses=1] - %165 = getelementptr inbounds %struct.GLDBufferstate* %164, i32 0, i32 12 ; <[8 x %union.GLSBuffer]*> [#uses=1] - %166 = getelementptr inbounds [8 x %union.GLSBuffer]* %165, i32 0, i32 %162 ; <%union.GLSBuffer*> [#uses=1] - %167 = getelementptr inbounds %union.GLSBuffer* %166, i32 0, i32 0 ; [#uses=1] - %168 = load i8** %167, align 4 ; [#uses=1] - %169 = icmp ne i8* %168, null ; [#uses=1] - br i1 %169, label %bb27, label %bb103 - -bb27: ; preds = %bb26 - %170 = load i32* %draw_buffer, align 4 ; [#uses=1] - %171 = shl i32 1, %170 ; [#uses=1] - store i32 %171, i32* %cur_draw_buffer_mask_bit, align 4 - %172 = load i32* %cy, align 4 ; [#uses=1] - store i32 %172, i32* %y, align 4 - br label %bb102 - -bb28: ; preds = %bb102 - %173 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %174 = getelementptr inbounds %struct.GLDContextRec* %173, i32 0, i32 30 ; <%struct.GLDBufferstate*> [#uses=1] - %175 = getelementptr inbounds %struct.GLDBufferstate* %174, i32 0, i32 11 ; <%union.GLSBuffer*> [#uses=1] - %176 = getelementptr inbounds %union.GLSBuffer* %175, i32 0, i32 0 ; [#uses=1] - %177 = bitcast i8** %176 to double** ; [#uses=1] - %178 = load double** %177, align 4 ; [#uses=1] - %179 = load i32* %offset, align 4 ; [#uses=1] - %180 = mul i32 %179, 4 ; [#uses=1] - %181 = getelementptr inbounds double* %178, i32 %180 ; [#uses=1] - store double* %181, double** %accum, align 4 - %182 = load double** %accum, align 4 ; [#uses=1] - %183 = load i32* %cw4, align 4 ; [#uses=1] - %184 = getelementptr inbounds double* %182, i32 %183 ; [#uses=1] - store double* %184, double** %accum_end, align 4 - %185 = load i32* %draw_buffer, align 4 ; [#uses=1] - %186 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %187 = getelementptr inbounds %struct.GLDContextRec* %186, i32 0, i32 30 ; <%struct.GLDBufferstate*> [#uses=1] - %188 = getelementptr inbounds %struct.GLDBufferstate* %187, i32 0, i32 12 ; <[8 x %union.GLSBuffer]*> [#uses=1] - %189 = getelementptr inbounds [8 x %union.GLSBuffer]* %188, i32 0, i32 %185 ; <%union.GLSBuffer*> [#uses=1] - %190 = getelementptr inbounds %union.GLSBuffer* %189, i32 0, i32 0 ; [#uses=1] - %191 = bitcast i8** %190 to i16** ; [#uses=1] - %192 = load i16** %191, align 4 ; [#uses=1] - %193 = load i32* %offset, align 4 ; [#uses=1] - %194 = getelementptr inbounds i16* %192, i32 %193 ; [#uses=1] - store i16* %194, i16** %color_ptr, align 4 - %195 = load i8* %color_mask_enabled, align 1 ; [#uses=1] - %196 = icmp ne i8 %195, 0 ; [#uses=1] - br i1 %196, label %bb29, label %bb70 - -bb29: ; preds = %bb28 - br label %bb68 - -bb30: ; preds = %bb68 - %197 = load double** %accum, align 4 ; [#uses=1] - %198 = getelementptr inbounds double* %197, i32 3 ; [#uses=1] - %199 = load double* %198, align 1 ; [#uses=1] - %200 = fptrunc double %199 to float ; [#uses=1] - %201 = load float* %value_addr, align 4 ; [#uses=1] - %202 = fmul float %200, %201 ; [#uses=1] - store float %202, float* %a, align 4 - %203 = load double** %accum, align 4 ; [#uses=1] - %204 = getelementptr inbounds double* %203, i32 0 ; [#uses=1] - %205 = load double* %204, align 1 ; [#uses=1] - %206 = fptrunc double %205 to float ; [#uses=1] - %207 = load float* %thirtyOne, align 4 ; [#uses=1] - %208 = fmul float %206, %207 ; [#uses=1] - %209 = load float* %value_addr, align 4 ; [#uses=1] - %210 = fmul float %208, %209 ; [#uses=1] - %211 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %212 = getelementptr inbounds %struct.GLDContextRec* %211, i32 0, i32 1 ; [#uses=1] - %213 = load float* %212, align 4 ; [#uses=1] - %214 = fadd float %210, %213 ; [#uses=1] - store float %214, float* %r, align 4 - %215 = load double** %accum, align 4 ; [#uses=1] - %216 = getelementptr inbounds double* %215, i32 1 ; [#uses=1] - %217 = load double* %216, align 1 ; [#uses=1] - %218 = fptrunc double %217 to float ; [#uses=1] - %219 = load float* %thirtyOne, align 4 ; [#uses=1] - %220 = fmul float %218, %219 ; [#uses=1] - %221 = load float* %value_addr, align 4 ; [#uses=1] - %222 = fmul float %220, %221 ; [#uses=1] - %223 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %224 = getelementptr inbounds %struct.GLDContextRec* %223, i32 0, i32 1 ; [#uses=1] - %225 = load float* %224, align 4 ; [#uses=1] - %226 = fadd float %222, %225 ; [#uses=1] - store float %226, float* %g, align 4 - %227 = load double** %accum, align 4 ; [#uses=1] - %228 = getelementptr inbounds double* %227, i32 2 ; [#uses=1] - %229 = load double* %228, align 1 ; [#uses=1] - %230 = fptrunc double %229 to float ; [#uses=1] - %231 = load float* %thirtyOne, align 4 ; [#uses=1] - %232 = fmul float %230, %231 ; [#uses=1] - %233 = load float* %value_addr, align 4 ; [#uses=1] - %234 = fmul float %232, %233 ; [#uses=1] - %235 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %236 = getelementptr inbounds %struct.GLDContextRec* %235, i32 0, i32 1 ; [#uses=1] - %237 = load float* %236, align 4 ; [#uses=1] - %238 = fadd float %234, %237 ; [#uses=1] - store float %238, float* %b, align 4 - %239 = load float* %r, align 4 ; [#uses=1] - %240 = fcmp uge float %239, 0.000000e+00 ; [#uses=1] - br i1 %240, label %bb31, label %bb35 - -bb31: ; preds = %bb30 - %241 = load float* %r, align 4 ; [#uses=1] - %242 = load float* %thirtyOne, align 4 ; [#uses=1] - %243 = fcmp ogt float %241, %242 ; [#uses=1] - br i1 %243, label %bb32, label %bb33 - -bb32: ; preds = %bb31 - %244 = load float* %thirtyOne, align 4 ; [#uses=1] - store float %244, float* %iftmp.149, align 4 - br label %bb34 - -bb33: ; preds = %bb31 - %245 = load float* %r, align 4 ; [#uses=1] - store float %245, float* %iftmp.149, align 4 - br label %bb34 - -bb34: ; preds = %bb33, %bb32 - %246 = load float* %iftmp.149, align 4 ; [#uses=1] - store float %246, float* %iftmp.148, align 4 - br label %bb36 - -bb35: ; preds = %bb30 - store float 0.000000e+00, float* %iftmp.148, align 4 - br label %bb36 - -bb36: ; preds = %bb35, %bb34 - %247 = load float* %iftmp.148, align 4 ; [#uses=1] - store float %247, float* %r, align 4 - %248 = load float* %g, align 4 ; [#uses=1] - %249 = fcmp uge float %248, 0.000000e+00 ; [#uses=1] - br i1 %249, label %bb37, label %bb41 - -bb37: ; preds = %bb36 - %250 = load float* %g, align 4 ; [#uses=1] - %251 = load float* %thirtyOne, align 4 ; [#uses=1] - %252 = fcmp ogt float %250, %251 ; [#uses=1] - br i1 %252, label %bb38, label %bb39 - -bb38: ; preds = %bb37 - %253 = load float* %thirtyOne, align 4 ; [#uses=1] - store float %253, float* %iftmp.151, align 4 - br label %bb40 - -bb39: ; preds = %bb37 - %254 = load float* %g, align 4 ; [#uses=1] - store float %254, float* %iftmp.151, align 4 - br label %bb40 - -bb40: ; preds = %bb39, %bb38 - %255 = load float* %iftmp.151, align 4 ; [#uses=1] - store float %255, float* %iftmp.150, align 4 - br label %bb42 - -bb41: ; preds = %bb36 - store float 0.000000e+00, float* %iftmp.150, align 4 - br label %bb42 - -bb42: ; preds = %bb41, %bb40 - %256 = load float* %iftmp.150, align 4 ; [#uses=1] - store float %256, float* %g, align 4 - %257 = load float* %b, align 4 ; [#uses=1] - %258 = fcmp uge float %257, 0.000000e+00 ; [#uses=1] - br i1 %258, label %bb43, label %bb47 - -bb43: ; preds = %bb42 - %259 = load float* %b, align 4 ; [#uses=1] - %260 = load float* %thirtyOne, align 4 ; [#uses=1] - %261 = fcmp ogt float %259, %260 ; [#uses=1] - br i1 %261, label %bb44, label %bb45 - -bb44: ; preds = %bb43 - %262 = load float* %thirtyOne, align 4 ; [#uses=1] - store float %262, float* %iftmp.153, align 4 - br label %bb46 - -bb45: ; preds = %bb43 - %263 = load float* %b, align 4 ; [#uses=1] - store float %263, float* %iftmp.153, align 4 - br label %bb46 - -bb46: ; preds = %bb45, %bb44 - %264 = load float* %iftmp.153, align 4 ; [#uses=1] - store float %264, float* %iftmp.152, align 4 - br label %bb48 - -bb47: ; preds = %bb42 - store float 0.000000e+00, float* %iftmp.152, align 4 - br label %bb48 - -bb48: ; preds = %bb47, %bb46 - %265 = load float* %iftmp.152, align 4 ; [#uses=1] - store float %265, float* %b, align 4 - %266 = load float* %a, align 4 ; [#uses=1] - %267 = fcmp uge float %266, 0.000000e+00 ; [#uses=1] - br i1 %267, label %bb49, label %bb53 - -bb49: ; preds = %bb48 - %268 = load float* %a, align 4 ; [#uses=1] - %269 = load float* %thirtyOne, align 4 ; [#uses=1] - %270 = fcmp ogt float %268, %269 ; [#uses=1] - br i1 %270, label %bb50, label %bb51 - -bb50: ; preds = %bb49 - %271 = load float* %thirtyOne, align 4 ; [#uses=1] - store float %271, float* %iftmp.155, align 4 - br label %bb52 - -bb51: ; preds = %bb49 - %272 = load float* %a, align 4 ; [#uses=1] - store float %272, float* %iftmp.155, align 4 - br label %bb52 - -bb52: ; preds = %bb51, %bb50 - %273 = load float* %iftmp.155, align 4 ; [#uses=1] - store float %273, float* %iftmp.154, align 4 - br label %bb54 - -bb53: ; preds = %bb48 - store float 0.000000e+00, float* %iftmp.154, align 4 - br label %bb54 - -bb54: ; preds = %bb53, %bb52 - %274 = load float* %iftmp.154, align 4 ; [#uses=1] - store float %274, float* %a, align 4 - %275 = load i16** %color_ptr, align 4 ; [#uses=1] - %276 = load i16* %275, align 2 ; [#uses=1] - store i16 %276, i16* %pixl, align 2 - %277 = load i8* %swap, align 1 ; [#uses=1] - %278 = icmp ne i8 %277, 0 ; [#uses=1] - br i1 %278, label %bb55, label %bb56 - -bb55: ; preds = %bb54 - %279 = load i16* %pixl, align 2 ; [#uses=1] - %280 = zext i16 %279 to i32 ; [#uses=1] - %281 = trunc i32 %280 to i16 ; [#uses=1] - %282 = call zeroext i16 @_OSSwapInt16(i16 zeroext %281) nounwind ; [#uses=1] - store i16 %282, i16* %pixl, align 2 - br label %bb56 - -bb56: ; preds = %bb55, %bb54 - %283 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] - %284 = getelementptr inbounds %struct.GLDState* %283, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] - %285 = getelementptr inbounds %struct.GLDMaskMode* %284, i32 0, i32 2 ; [#uses=1] - %286 = load i8* %285, align 16 ; [#uses=1] - %287 = zext i8 %286 to i32 ; [#uses=1] - %288 = load i32* %cur_draw_buffer_mask_bit, align 4 ; [#uses=1] - %289 = and i32 %287, %288 ; [#uses=1] - %290 = icmp ne i32 %289, 0 ; [#uses=1] - br i1 %290, label %bb57, label %bb58 - -bb57: ; preds = %bb56 - %291 = load i16* %pixl, align 2 ; [#uses=1] - %292 = and i16 %291, -32257 ; [#uses=1] - %293 = load float* %r, align 4 ; [#uses=1] - %294 = fptoui float %293 to i32 ; [#uses=1] - %295 = trunc i32 %294 to i16 ; [#uses=1] - %296 = shl i16 %295, 10 ; [#uses=1] - %297 = and i16 %296, 31744 ; [#uses=1] - %298 = or i16 %292, %297 ; [#uses=1] - store i16 %298, i16* %pixl, align 2 - br label %bb58 - -bb58: ; preds = %bb57, %bb56 - %299 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] - %300 = getelementptr inbounds %struct.GLDState* %299, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] - %301 = getelementptr inbounds %struct.GLDMaskMode* %300, i32 0, i32 3 ; [#uses=1] - %302 = load i8* %301, align 1 ; [#uses=1] - %303 = zext i8 %302 to i32 ; [#uses=1] - %304 = load i32* %cur_draw_buffer_mask_bit, align 4 ; [#uses=1] - %305 = and i32 %303, %304 ; [#uses=1] - %306 = icmp ne i32 %305, 0 ; [#uses=1] - br i1 %306, label %bb59, label %bb60 - -bb59: ; preds = %bb58 - %307 = load i16* %pixl, align 2 ; [#uses=1] - %308 = and i16 %307, -993 ; [#uses=1] - %309 = load float* %g, align 4 ; [#uses=1] - %310 = fptoui float %309 to i32 ; [#uses=1] - %311 = trunc i32 %310 to i16 ; [#uses=1] - %312 = shl i16 %311, 5 ; [#uses=1] - %313 = and i16 %312, 992 ; [#uses=1] - %314 = or i16 %308, %313 ; [#uses=1] - store i16 %314, i16* %pixl, align 2 - br label %bb60 - -bb60: ; preds = %bb59, %bb58 - %315 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] - %316 = getelementptr inbounds %struct.GLDState* %315, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] - %317 = getelementptr inbounds %struct.GLDMaskMode* %316, i32 0, i32 4 ; [#uses=1] - %318 = load i8* %317, align 2 ; [#uses=1] - %319 = zext i8 %318 to i32 ; [#uses=1] - %320 = load i32* %cur_draw_buffer_mask_bit, align 4 ; [#uses=1] - %321 = and i32 %319, %320 ; [#uses=1] - %322 = icmp ne i32 %321, 0 ; [#uses=1] - br i1 %322, label %bb61, label %bb62 - -bb61: ; preds = %bb60 - %323 = load i16* %pixl, align 2 ; [#uses=1] - %324 = and i16 %323, -32 ; [#uses=1] - %325 = load float* %b, align 4 ; [#uses=1] - %326 = fptoui float %325 to i32 ; [#uses=1] - %327 = trunc i32 %326 to i16 ; [#uses=1] - %328 = and i16 %327, 31 ; [#uses=1] - %329 = or i16 %324, %328 ; [#uses=1] - store i16 %329, i16* %pixl, align 2 - br label %bb62 - -bb62: ; preds = %bb61, %bb60 - %330 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] - %331 = getelementptr inbounds %struct.GLDState* %330, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] - %332 = getelementptr inbounds %struct.GLDMaskMode* %331, i32 0, i32 5 ; [#uses=1] - %333 = load i8* %332, align 1 ; [#uses=1] - %334 = zext i8 %333 to i32 ; [#uses=1] - %335 = load i32* %cur_draw_buffer_mask_bit, align 4 ; [#uses=1] - %336 = and i32 %334, %335 ; [#uses=1] - %337 = icmp ne i32 %336, 0 ; [#uses=1] - br i1 %337, label %bb63, label %bb65 - -bb63: ; preds = %bb62 - %338 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %339 = getelementptr inbounds %struct.GLDContextRec* %338, i32 0, i32 1 ; [#uses=1] - %340 = load float* %339, align 4 ; [#uses=1] - %341 = load float* %a, align 4 ; [#uses=1] - %342 = fcmp olt float %340, %341 ; [#uses=1] - br i1 %342, label %bb64, label %bb65 - -bb64: ; preds = %bb63 - %343 = load i16* %pixl, align 2 ; [#uses=1] - %344 = or i16 %343, -32768 ; [#uses=1] - store i16 %344, i16* %pixl, align 2 - br label %bb65 - -bb65: ; preds = %bb64, %bb63, %bb62 - %345 = load i8* %swap, align 1 ; [#uses=1] - %346 = icmp ne i8 %345, 0 ; [#uses=1] - br i1 %346, label %bb66, label %bb67 - -bb66: ; preds = %bb65 - %347 = load i16* %pixl, align 2 ; [#uses=1] - %348 = zext i16 %347 to i32 ; [#uses=1] - %349 = trunc i32 %348 to i16 ; [#uses=1] - %350 = call zeroext i16 @_OSSwapInt16(i16 zeroext %349) nounwind ; [#uses=1] - store i16 %350, i16* %pixl, align 2 - br label %bb67 - -bb67: ; preds = %bb66, %bb65 - %351 = load i16** %color_ptr, align 4 ; [#uses=1] - %352 = load i16* %pixl, align 2 ; [#uses=1] - store i16 %352, i16* %351, align 2 - %353 = load double** %accum, align 4 ; [#uses=1] - %354 = getelementptr inbounds double* %353, i32 4 ; [#uses=1] - store double* %354, double** %accum, align 4 - %355 = load i16** %color_ptr, align 4 ; [#uses=1] - %356 = getelementptr inbounds i16* %355, i32 1 ; [#uses=1] - store i16* %356, i16** %color_ptr, align 4 - br label %bb68 - -bb68: ; preds = %bb67, %bb29 - %357 = load double** %accum, align 4 ; [#uses=1] - %358 = load double** %accum_end, align 4 ; [#uses=1] - %359 = icmp ult double* %357, %358 ; [#uses=1] - br i1 %359, label %bb30, label %bb69 - -bb69: ; preds = %bb68 - br label %bb101 - -bb70: ; preds = %bb28 - br label %bb100 - -bb71: ; preds = %bb100 - %360 = load double** %accum, align 4 ; [#uses=1] - %361 = getelementptr inbounds double* %360, i32 3 ; [#uses=1] - %362 = load double* %361, align 1 ; [#uses=1] - %363 = fptrunc double %362 to float ; [#uses=1] - %364 = load float* %value_addr, align 4 ; [#uses=1] - %365 = fmul float %363, %364 ; [#uses=1] - store float %365, float* %a, align 4 - %366 = load double** %accum, align 4 ; [#uses=1] - %367 = getelementptr inbounds double* %366, i32 0 ; [#uses=1] - %368 = load double* %367, align 1 ; [#uses=1] - %369 = fptrunc double %368 to float ; [#uses=1] - %370 = load float* %thirtyOne, align 4 ; [#uses=1] - %371 = fmul float %369, %370 ; [#uses=1] - %372 = load float* %value_addr, align 4 ; [#uses=1] - %373 = fmul float %371, %372 ; [#uses=1] - %374 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %375 = getelementptr inbounds %struct.GLDContextRec* %374, i32 0, i32 1 ; [#uses=1] - %376 = load float* %375, align 4 ; [#uses=1] - %377 = fadd float %373, %376 ; [#uses=1] - store float %377, float* %r, align 4 - %378 = load double** %accum, align 4 ; [#uses=1] - %379 = getelementptr inbounds double* %378, i32 1 ; [#uses=1] - %380 = load double* %379, align 1 ; [#uses=1] - %381 = fptrunc double %380 to float ; [#uses=1] - %382 = load float* %thirtyOne, align 4 ; [#uses=1] - %383 = fmul float %381, %382 ; [#uses=1] - %384 = load float* %value_addr, align 4 ; [#uses=1] - %385 = fmul float %383, %384 ; [#uses=1] - %386 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %387 = getelementptr inbounds %struct.GLDContextRec* %386, i32 0, i32 1 ; [#uses=1] - %388 = load float* %387, align 4 ; [#uses=1] - %389 = fadd float %385, %388 ; [#uses=1] - store float %389, float* %g, align 4 - %390 = load double** %accum, align 4 ; [#uses=1] - %391 = getelementptr inbounds double* %390, i32 2 ; [#uses=1] - %392 = load double* %391, align 1 ; [#uses=1] - %393 = fptrunc double %392 to float ; [#uses=1] - %394 = load float* %thirtyOne, align 4 ; [#uses=1] - %395 = fmul float %393, %394 ; [#uses=1] - %396 = load float* %value_addr, align 4 ; [#uses=1] - %397 = fmul float %395, %396 ; [#uses=1] - %398 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %399 = getelementptr inbounds %struct.GLDContextRec* %398, i32 0, i32 1 ; [#uses=1] - %400 = load float* %399, align 4 ; [#uses=1] - %401 = fadd float %397, %400 ; [#uses=1] - store float %401, float* %b, align 4 - %402 = load float* %r, align 4 ; [#uses=1] - %403 = fcmp uge float %402, 0.000000e+00 ; [#uses=1] - br i1 %403, label %bb72, label %bb76 - -bb72: ; preds = %bb71 - %404 = load float* %r, align 4 ; [#uses=1] - %405 = load float* %thirtyOne, align 4 ; [#uses=1] - %406 = fcmp ogt float %404, %405 ; [#uses=1] - br i1 %406, label %bb73, label %bb74 - -bb73: ; preds = %bb72 - %407 = load float* %thirtyOne, align 4 ; [#uses=1] - store float %407, float* %iftmp.157, align 4 - br label %bb75 - -bb74: ; preds = %bb72 - %408 = load float* %r, align 4 ; [#uses=1] - store float %408, float* %iftmp.157, align 4 - br label %bb75 - -bb75: ; preds = %bb74, %bb73 - %409 = load float* %iftmp.157, align 4 ; [#uses=1] - store float %409, float* %iftmp.156, align 4 - br label %bb77 - -bb76: ; preds = %bb71 - store float 0.000000e+00, float* %iftmp.156, align 4 - br label %bb77 - -bb77: ; preds = %bb76, %bb75 - %410 = load float* %iftmp.156, align 4 ; [#uses=1] - store float %410, float* %r, align 4 - %411 = load float* %g, align 4 ; [#uses=1] - %412 = fcmp uge float %411, 0.000000e+00 ; [#uses=1] - br i1 %412, label %bb78, label %bb82 - -bb78: ; preds = %bb77 - %413 = load float* %g, align 4 ; [#uses=1] - %414 = load float* %thirtyOne, align 4 ; [#uses=1] - %415 = fcmp ogt float %413, %414 ; [#uses=1] - br i1 %415, label %bb79, label %bb80 - -bb79: ; preds = %bb78 - %416 = load float* %thirtyOne, align 4 ; [#uses=1] - store float %416, float* %iftmp.159, align 4 - br label %bb81 - -bb80: ; preds = %bb78 - %417 = load float* %g, align 4 ; [#uses=1] - store float %417, float* %iftmp.159, align 4 - br label %bb81 - -bb81: ; preds = %bb80, %bb79 - %418 = load float* %iftmp.159, align 4 ; [#uses=1] - store float %418, float* %iftmp.158, align 4 - br label %bb83 - -bb82: ; preds = %bb77 - store float 0.000000e+00, float* %iftmp.158, align 4 - br label %bb83 - -bb83: ; preds = %bb82, %bb81 - %419 = load float* %iftmp.158, align 4 ; [#uses=1] - store float %419, float* %g, align 4 - %420 = load float* %b, align 4 ; [#uses=1] - %421 = fcmp uge float %420, 0.000000e+00 ; [#uses=1] - br i1 %421, label %bb84, label %bb88 - -bb84: ; preds = %bb83 - %422 = load float* %b, align 4 ; [#uses=1] - %423 = load float* %thirtyOne, align 4 ; [#uses=1] - %424 = fcmp ogt float %422, %423 ; [#uses=1] - br i1 %424, label %bb85, label %bb86 - -bb85: ; preds = %bb84 - %425 = load float* %thirtyOne, align 4 ; [#uses=1] - store float %425, float* %iftmp.161, align 4 - br label %bb87 - -bb86: ; preds = %bb84 - %426 = load float* %b, align 4 ; [#uses=1] - store float %426, float* %iftmp.161, align 4 - br label %bb87 - -bb87: ; preds = %bb86, %bb85 - %427 = load float* %iftmp.161, align 4 ; [#uses=1] - store float %427, float* %iftmp.160, align 4 - br label %bb89 - -bb88: ; preds = %bb83 - store float 0.000000e+00, float* %iftmp.160, align 4 - br label %bb89 - -bb89: ; preds = %bb88, %bb87 - %428 = load float* %iftmp.160, align 4 ; [#uses=1] - store float %428, float* %b, align 4 - %429 = load float* %a, align 4 ; [#uses=1] - %430 = fcmp uge float %429, 0.000000e+00 ; [#uses=1] - br i1 %430, label %bb90, label %bb94 - -bb90: ; preds = %bb89 - %431 = load float* %a, align 4 ; [#uses=1] - %432 = load float* %thirtyOne, align 4 ; [#uses=1] - %433 = fcmp ogt float %431, %432 ; [#uses=1] - br i1 %433, label %bb91, label %bb92 - -bb91: ; preds = %bb90 - %434 = load float* %thirtyOne, align 4 ; [#uses=1] - store float %434, float* %iftmp.163, align 4 - br label %bb93 - -bb92: ; preds = %bb90 - %435 = load float* %a, align 4 ; [#uses=1] - store float %435, float* %iftmp.163, align 4 - br label %bb93 - -bb93: ; preds = %bb92, %bb91 - %436 = load float* %iftmp.163, align 4 ; [#uses=1] - store float %436, float* %iftmp.162, align 4 - br label %bb95 - -bb94: ; preds = %bb89 - store float 0.000000e+00, float* %iftmp.162, align 4 - br label %bb95 - -bb95: ; preds = %bb94, %bb93 - %437 = load float* %iftmp.162, align 4 ; [#uses=1] - store float %437, float* %a, align 4 - %438 = load float* %r, align 4 ; [#uses=1] - %439 = fptoui float %438 to i32 ; [#uses=1] - %440 = trunc i32 %439 to i16 ; [#uses=1] - %441 = shl i16 %440, 10 ; [#uses=1] - %442 = and i16 %441, 31744 ; [#uses=1] - store i16 %442, i16* %pixl, align 2 - %443 = load float* %g, align 4 ; [#uses=1] - %444 = fptoui float %443 to i32 ; [#uses=1] - %445 = trunc i32 %444 to i16 ; [#uses=1] - %446 = shl i16 %445, 5 ; [#uses=1] - %447 = and i16 %446, 992 ; [#uses=1] - %448 = load i16* %pixl, align 2 ; [#uses=1] - %449 = or i16 %447, %448 ; [#uses=1] - store i16 %449, i16* %pixl, align 2 - %450 = load float* %b, align 4 ; [#uses=1] - %451 = fptoui float %450 to i32 ; [#uses=1] - %452 = trunc i32 %451 to i16 ; [#uses=1] - %453 = and i16 %452, 31 ; [#uses=1] - %454 = load i16* %pixl, align 2 ; [#uses=1] - %455 = or i16 %453, %454 ; [#uses=1] - store i16 %455, i16* %pixl, align 2 - %456 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %457 = getelementptr inbounds %struct.GLDContextRec* %456, i32 0, i32 1 ; [#uses=1] - %458 = load float* %457, align 4 ; [#uses=1] - %459 = load float* %a, align 4 ; [#uses=1] - %460 = fcmp olt float %458, %459 ; [#uses=1] - br i1 %460, label %bb96, label %bb97 - -bb96: ; preds = %bb95 - %461 = load i16* %pixl, align 2 ; [#uses=1] - %462 = or i16 %461, -32768 ; [#uses=1] - store i16 %462, i16* %pixl, align 2 - br label %bb97 - -bb97: ; preds = %bb96, %bb95 - %463 = load i8* %swap, align 1 ; [#uses=1] - %464 = icmp ne i8 %463, 0 ; [#uses=1] - br i1 %464, label %bb98, label %bb99 - -bb98: ; preds = %bb97 - %465 = load i16* %pixl, align 2 ; [#uses=1] - %466 = zext i16 %465 to i32 ; [#uses=1] - %467 = trunc i32 %466 to i16 ; [#uses=1] - %468 = call zeroext i16 @_OSSwapInt16(i16 zeroext %467) nounwind ; [#uses=1] - store i16 %468, i16* %pixl, align 2 - br label %bb99 - -bb99: ; preds = %bb98, %bb97 - %469 = load i16** %color_ptr, align 4 ; [#uses=1] - %470 = load i16* %pixl, align 2 ; [#uses=1] - store i16 %470, i16* %469, align 2 - %471 = load double** %accum, align 4 ; [#uses=1] - %472 = getelementptr inbounds double* %471, i32 4 ; [#uses=1] - store double* %472, double** %accum, align 4 - %473 = load i16** %color_ptr, align 4 ; [#uses=1] - %474 = getelementptr inbounds i16* %473, i32 1 ; [#uses=1] - store i16* %474, i16** %color_ptr, align 4 - br label %bb100 - -bb100: ; preds = %bb99, %bb70 - %475 = load double** %accum, align 4 ; [#uses=1] - %476 = load double** %accum_end, align 4 ; [#uses=1] - %477 = icmp ult double* %475, %476 ; [#uses=1] - br i1 %477, label %bb71, label %bb101 - -bb101: ; preds = %bb100, %bb69 - %478 = load i32* %y, align 4 ; [#uses=1] - %479 = add i32 %478, 1 ; [#uses=1] - store i32 %479, i32* %y, align 4 - %480 = load i32* %offset, align 4 ; [#uses=1] - %481 = load i32* %y_inc, align 4 ; [#uses=1] - %482 = add i32 %480, %481 ; [#uses=1] - store i32 %482, i32* %offset, align 4 - br label %bb102 - -bb102: ; preds = %bb101, %bb27 - %483 = load i32* %y, align 4 ; [#uses=1] - %484 = load i32* %yl, align 4 ; [#uses=1] - %485 = icmp ult i32 %483, %484 ; [#uses=1] - br i1 %485, label %bb28, label %bb103 - -bb103: ; preds = %bb102, %bb26 - %486 = load i32* %draw_buffer, align 4 ; [#uses=1] - %487 = add nsw i32 %486, 1 ; [#uses=1] - store i32 %487, i32* %draw_buffer, align 4 - br label %bb104 - -bb104: ; preds = %bb103, %bb25 - %488 = load i32* %draw_buffer, align 4 ; [#uses=1] - %489 = icmp sle i32 %488, 7 ; [#uses=1] - br i1 %489, label %bb26, label %bb105 - -bb105: ; preds = %bb104, %bb23 - %490 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %491 = getelementptr inbounds %struct.GLDContextRec* %490, i32 0, i32 28 ; <%struct.GLDFramebufferRec**> [#uses=1] - %492 = load %struct.GLDFramebufferRec** %491, align 4 ; <%struct.GLDFramebufferRec*> [#uses=1] - %493 = icmp ne %struct.GLDFramebufferRec* %492, null ; [#uses=1] - br i1 %493, label %bb106, label %bb107 - -bb106: ; preds = %bb105 - %494 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %495 = getelementptr inbounds %struct.GLDContextRec* %494, i32 0, i32 28 ; <%struct.GLDFramebufferRec**> [#uses=1] - %496 = load %struct.GLDFramebufferRec** %495, align 4 ; <%struct.GLDFramebufferRec*> [#uses=1] - %497 = getelementptr inbounds %struct.GLDFramebufferRec* %496, i32 0, i32 2 ; <[10 x %struct.GLDFormat]*> [#uses=1] - %498 = getelementptr inbounds [10 x %struct.GLDFormat]* %497, i32 0, i32 0 ; <%struct.GLDFormat*> [#uses=1] - %499 = getelementptr inbounds %struct.GLDFormat* %498, i32 0, i32 7 ; [#uses=1] - %500 = load i32* %499, align 4 ; [#uses=1] - %501 = icmp eq i32 %500, 33639 ; [#uses=1] - %502 = zext i1 %501 to i8 ; [#uses=1] - store i8 %502, i8* %iftmp.164, align 1 - br label %bb108 - -bb107: ; preds = %bb105 - %503 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %504 = getelementptr inbounds %struct.GLDContextRec* %503, i32 0, i32 56 ; <%struct.GLDFormat*> [#uses=1] - %505 = getelementptr inbounds %struct.GLDFormat* %504, i32 0, i32 7 ; [#uses=1] - %506 = load i32* %505, align 4 ; [#uses=1] - %507 = icmp eq i32 %506, 33639 ; [#uses=1] - %508 = zext i1 %507 to i8 ; [#uses=1] - store i8 %508, i8* %iftmp.164, align 1 - br label %bb108 - -bb108: ; preds = %bb107, %bb106 - %509 = load i8* %iftmp.164, align 1 ; [#uses=1] - %toBool109 = icmp ne i8 %509, 0 ; [#uses=1] - br i1 %toBool109, label %bb110, label %bb229 - -bb110: ; preds = %bb108 - %510 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %511 = getelementptr inbounds %struct.GLDContextRec* %510, i32 0, i32 7 ; [#uses=1] - %512 = load float* %511, align 4 ; [#uses=1] - store float %512, float* %twoFiftyFive, align 4 - %513 = load i32* %offset, align 4 ; [#uses=1] - store i32 %513, i32* %start_offset112, align 4 - store i32 0, i32* %draw_buffer, align 4 - br label %bb227 - -bb113: ; preds = %bb227 - %514 = load i32* %start_offset112, align 4 ; [#uses=1] - store i32 %514, i32* %offset, align 4 - %515 = load i32* %draw_buffer, align 4 ; [#uses=1] - %516 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %517 = getelementptr inbounds %struct.GLDContextRec* %516, i32 0, i32 30 ; <%struct.GLDBufferstate*> [#uses=1] - %518 = getelementptr inbounds %struct.GLDBufferstate* %517, i32 0, i32 12 ; <[8 x %union.GLSBuffer]*> [#uses=1] - %519 = getelementptr inbounds [8 x %union.GLSBuffer]* %518, i32 0, i32 %515 ; <%union.GLSBuffer*> [#uses=1] - %520 = getelementptr inbounds %union.GLSBuffer* %519, i32 0, i32 0 ; [#uses=1] - %521 = load i8** %520, align 4 ; [#uses=1] - %522 = icmp ne i8* %521, null ; [#uses=1] - br i1 %522, label %bb114, label %bb226 - -bb114: ; preds = %bb113 - %523 = load i32* %draw_buffer, align 4 ; [#uses=1] - %524 = shl i32 1, %523 ; [#uses=1] - store i32 %524, i32* %cur_draw_buffer_mask_bit115, align 4 - %525 = load i32* %cy, align 4 ; [#uses=1] - store i32 %525, i32* %y, align 4 - br label %bb225 - -bb116: ; preds = %bb225 - %526 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %527 = getelementptr inbounds %struct.GLDContextRec* %526, i32 0, i32 30 ; <%struct.GLDBufferstate*> [#uses=1] - %528 = getelementptr inbounds %struct.GLDBufferstate* %527, i32 0, i32 11 ; <%union.GLSBuffer*> [#uses=1] - %529 = getelementptr inbounds %union.GLSBuffer* %528, i32 0, i32 0 ; [#uses=1] - %530 = bitcast i8** %529 to double** ; [#uses=1] - %531 = load double** %530, align 4 ; [#uses=1] - %532 = load i32* %offset, align 4 ; [#uses=1] - %533 = mul i32 %532, 4 ; [#uses=1] - %534 = getelementptr inbounds double* %531, i32 %533 ; [#uses=1] - store double* %534, double** %accum, align 4 - %535 = load double** %accum, align 4 ; [#uses=1] - %536 = load i32* %cw4, align 4 ; [#uses=1] - %537 = getelementptr inbounds double* %535, i32 %536 ; [#uses=1] - store double* %537, double** %accum_end, align 4 - %538 = load i32* %draw_buffer, align 4 ; [#uses=1] - %539 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %540 = getelementptr inbounds %struct.GLDContextRec* %539, i32 0, i32 30 ; <%struct.GLDBufferstate*> [#uses=1] - %541 = getelementptr inbounds %struct.GLDBufferstate* %540, i32 0, i32 12 ; <[8 x %union.GLSBuffer]*> [#uses=1] - %542 = getelementptr inbounds [8 x %union.GLSBuffer]* %541, i32 0, i32 %538 ; <%union.GLSBuffer*> [#uses=1] - %543 = getelementptr inbounds %union.GLSBuffer* %542, i32 0, i32 0 ; [#uses=1] - %544 = bitcast i8** %543 to i32** ; [#uses=1] - %545 = load i32** %544, align 4 ; [#uses=1] - %546 = load i32* %offset, align 4 ; [#uses=1] - %547 = getelementptr inbounds i32* %545, i32 %546 ; [#uses=1] - %548 = bitcast i32* %547 to i8* ; [#uses=1] - store i8* %548, i8** %color_ptr111, align 4 - %549 = load i8* %color_mask_enabled, align 1 ; [#uses=1] - %550 = icmp ne i8 %549, 0 ; [#uses=1] - br i1 %550, label %bb117, label %bb191 - -bb117: ; preds = %bb116 - br label %bb189 - -bb118: ; preds = %bb189 - %551 = load double** %accum, align 4 ; [#uses=1] - %552 = getelementptr inbounds double* %551, i32 0 ; [#uses=1] - %553 = load double* %552, align 1 ; [#uses=1] - %554 = fptrunc double %553 to float ; [#uses=1] - %555 = load float* %value_addr, align 4 ; [#uses=1] - %556 = fmul float %554, %555 ; [#uses=1] - %557 = load float* %twoFiftyFive, align 4 ; [#uses=1] - %558 = fmul float %556, %557 ; [#uses=1] - %559 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %560 = getelementptr inbounds %struct.GLDContextRec* %559, i32 0, i32 1 ; [#uses=1] - %561 = load float* %560, align 4 ; [#uses=1] - %562 = fadd float %558, %561 ; [#uses=1] - store float %562, float* %r119, align 4 - %563 = load double** %accum, align 4 ; [#uses=1] - %564 = getelementptr inbounds double* %563, i32 1 ; [#uses=1] - %565 = load double* %564, align 1 ; [#uses=1] - %566 = fptrunc double %565 to float ; [#uses=1] - %567 = load float* %value_addr, align 4 ; [#uses=1] - %568 = fmul float %566, %567 ; [#uses=1] - %569 = load float* %twoFiftyFive, align 4 ; [#uses=1] - %570 = fmul float %568, %569 ; [#uses=1] - %571 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %572 = getelementptr inbounds %struct.GLDContextRec* %571, i32 0, i32 1 ; [#uses=1] - %573 = load float* %572, align 4 ; [#uses=1] - %574 = fadd float %570, %573 ; [#uses=1] - store float %574, float* %g120, align 4 - %575 = load double** %accum, align 4 ; [#uses=1] - %576 = getelementptr inbounds double* %575, i32 2 ; [#uses=1] - %577 = load double* %576, align 1 ; [#uses=1] - %578 = fptrunc double %577 to float ; [#uses=1] - %579 = load float* %value_addr, align 4 ; [#uses=1] - %580 = fmul float %578, %579 ; [#uses=1] - %581 = load float* %twoFiftyFive, align 4 ; [#uses=1] - %582 = fmul float %580, %581 ; [#uses=1] - %583 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %584 = getelementptr inbounds %struct.GLDContextRec* %583, i32 0, i32 1 ; [#uses=1] - %585 = load float* %584, align 4 ; [#uses=1] - %586 = fadd float %582, %585 ; [#uses=1] - store float %586, float* %b121, align 4 - %587 = load double** %accum, align 4 ; [#uses=1] - %588 = getelementptr inbounds double* %587, i32 3 ; [#uses=1] - %589 = load double* %588, align 1 ; [#uses=1] - %590 = fptrunc double %589 to float ; [#uses=1] - %591 = load float* %value_addr, align 4 ; [#uses=1] - %592 = fmul float %590, %591 ; [#uses=1] - %593 = load float* %twoFiftyFive, align 4 ; [#uses=1] - %594 = fmul float %592, %593 ; [#uses=1] - %595 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %596 = getelementptr inbounds %struct.GLDContextRec* %595, i32 0, i32 1 ; [#uses=1] - %597 = load float* %596, align 4 ; [#uses=1] - %598 = fadd float %594, %597 ; [#uses=1] - store float %598, float* %a122, align 4 - %599 = load i8* %swap, align 1 ; [#uses=1] - %600 = icmp ne i8 %599, 0 ; [#uses=1] - br i1 %600, label %bb123, label %bb156 - -bb123: ; preds = %bb118 - %601 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] - %602 = getelementptr inbounds %struct.GLDState* %601, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] - %603 = getelementptr inbounds %struct.GLDMaskMode* %602, i32 0, i32 5 ; [#uses=1] - %604 = load i8* %603, align 1 ; [#uses=1] - %605 = zext i8 %604 to i32 ; [#uses=1] - %606 = load i32* %cur_draw_buffer_mask_bit115, align 4 ; [#uses=1] - %607 = and i32 %605, %606 ; [#uses=1] - %608 = icmp ne i32 %607, 0 ; [#uses=1] - br i1 %608, label %bb124, label %bb131 - -bb124: ; preds = %bb123 - %609 = load float* %a122, align 4 ; [#uses=1] - %610 = fcmp uge float %609, 0.000000e+00 ; [#uses=1] - br i1 %610, label %bb125, label %bb129 - -bb125: ; preds = %bb124 - %611 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %612 = getelementptr inbounds %struct.GLDContextRec* %611, i32 0, i32 7 ; [#uses=1] - %613 = load float* %612, align 4 ; [#uses=1] - %614 = load float* %a122, align 4 ; [#uses=1] - %615 = fcmp olt float %613, %614 ; [#uses=1] - br i1 %615, label %bb126, label %bb127 - -bb126: ; preds = %bb125 - %616 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %617 = getelementptr inbounds %struct.GLDContextRec* %616, i32 0, i32 7 ; [#uses=1] - %618 = load float* %617, align 4 ; [#uses=1] - %619 = fptoui float %618 to i8 ; [#uses=1] - store i8 %619, i8* %iftmp.168, align 1 - br label %bb128 - -bb127: ; preds = %bb125 - %620 = load float* %a122, align 4 ; [#uses=1] - %621 = fptoui float %620 to i8 ; [#uses=1] - store i8 %621, i8* %iftmp.168, align 1 - br label %bb128 - -bb128: ; preds = %bb127, %bb126 - %622 = load i8* %iftmp.168, align 1 ; [#uses=1] - store i8 %622, i8* %iftmp.167, align 1 - br label %bb130 - -bb129: ; preds = %bb124 - store i8 0, i8* %iftmp.167, align 1 - br label %bb130 - -bb130: ; preds = %bb129, %bb128 - %623 = load i8** %color_ptr111, align 4 ; [#uses=1] - %624 = getelementptr inbounds i8* %623, i32 0 ; [#uses=1] - %625 = load i8* %iftmp.167, align 1 ; [#uses=1] - store i8 %625, i8* %624, align 1 - br label %bb131 - -bb131: ; preds = %bb130, %bb123 - %626 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] - %627 = getelementptr inbounds %struct.GLDState* %626, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] - %628 = getelementptr inbounds %struct.GLDMaskMode* %627, i32 0, i32 2 ; [#uses=1] - %629 = load i8* %628, align 16 ; [#uses=1] - %630 = zext i8 %629 to i32 ; [#uses=1] - %631 = load i32* %cur_draw_buffer_mask_bit115, align 4 ; [#uses=1] - %632 = and i32 %630, %631 ; [#uses=1] - %633 = icmp ne i32 %632, 0 ; [#uses=1] - br i1 %633, label %bb132, label %bb139 - -bb132: ; preds = %bb131 - %634 = load float* %r119, align 4 ; [#uses=1] - %635 = fcmp uge float %634, 0.000000e+00 ; [#uses=1] - br i1 %635, label %bb133, label %bb137 - -bb133: ; preds = %bb132 - %636 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %637 = getelementptr inbounds %struct.GLDContextRec* %636, i32 0, i32 7 ; [#uses=1] - %638 = load float* %637, align 4 ; [#uses=1] - %639 = load float* %r119, align 4 ; [#uses=1] - %640 = fcmp olt float %638, %639 ; [#uses=1] - br i1 %640, label %bb134, label %bb135 - -bb134: ; preds = %bb133 - %641 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %642 = getelementptr inbounds %struct.GLDContextRec* %641, i32 0, i32 7 ; [#uses=1] - %643 = load float* %642, align 4 ; [#uses=1] - %644 = fptoui float %643 to i8 ; [#uses=1] - store i8 %644, i8* %iftmp.170, align 1 - br label %bb136 - -bb135: ; preds = %bb133 - %645 = load float* %r119, align 4 ; [#uses=1] - %646 = fptoui float %645 to i8 ; [#uses=1] - store i8 %646, i8* %iftmp.170, align 1 - br label %bb136 - -bb136: ; preds = %bb135, %bb134 - %647 = load i8* %iftmp.170, align 1 ; [#uses=1] - store i8 %647, i8* %iftmp.169, align 1 - br label %bb138 - -bb137: ; preds = %bb132 - store i8 0, i8* %iftmp.169, align 1 - br label %bb138 - -bb138: ; preds = %bb137, %bb136 - %648 = load i8** %color_ptr111, align 4 ; [#uses=1] - %649 = getelementptr inbounds i8* %648, i32 1 ; [#uses=1] - %650 = load i8* %iftmp.169, align 1 ; [#uses=1] - store i8 %650, i8* %649, align 1 - br label %bb139 - -bb139: ; preds = %bb138, %bb131 - %651 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] - %652 = getelementptr inbounds %struct.GLDState* %651, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] - %653 = getelementptr inbounds %struct.GLDMaskMode* %652, i32 0, i32 3 ; [#uses=1] - %654 = load i8* %653, align 1 ; [#uses=1] - %655 = zext i8 %654 to i32 ; [#uses=1] - %656 = load i32* %cur_draw_buffer_mask_bit115, align 4 ; [#uses=1] - %657 = and i32 %655, %656 ; [#uses=1] - %658 = icmp ne i32 %657, 0 ; [#uses=1] - br i1 %658, label %bb140, label %bb147 - -bb140: ; preds = %bb139 - %659 = load float* %g120, align 4 ; [#uses=1] - %660 = fcmp uge float %659, 0.000000e+00 ; [#uses=1] - br i1 %660, label %bb141, label %bb145 - -bb141: ; preds = %bb140 - %661 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %662 = getelementptr inbounds %struct.GLDContextRec* %661, i32 0, i32 7 ; [#uses=1] - %663 = load float* %662, align 4 ; [#uses=1] - %664 = load float* %g120, align 4 ; [#uses=1] - %665 = fcmp olt float %663, %664 ; [#uses=1] - br i1 %665, label %bb142, label %bb143 - -bb142: ; preds = %bb141 - %666 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %667 = getelementptr inbounds %struct.GLDContextRec* %666, i32 0, i32 7 ; [#uses=1] - %668 = load float* %667, align 4 ; [#uses=1] - %669 = fptoui float %668 to i8 ; [#uses=1] - store i8 %669, i8* %iftmp.172, align 1 - br label %bb144 - -bb143: ; preds = %bb141 - %670 = load float* %g120, align 4 ; [#uses=1] - %671 = fptoui float %670 to i8 ; [#uses=1] - store i8 %671, i8* %iftmp.172, align 1 - br label %bb144 - -bb144: ; preds = %bb143, %bb142 - %672 = load i8* %iftmp.172, align 1 ; [#uses=1] - store i8 %672, i8* %iftmp.171, align 1 - br label %bb146 - -bb145: ; preds = %bb140 - store i8 0, i8* %iftmp.171, align 1 - br label %bb146 - -bb146: ; preds = %bb145, %bb144 - %673 = load i8** %color_ptr111, align 4 ; [#uses=1] - %674 = getelementptr inbounds i8* %673, i32 2 ; [#uses=1] - %675 = load i8* %iftmp.171, align 1 ; [#uses=1] - store i8 %675, i8* %674, align 1 - br label %bb147 - -bb147: ; preds = %bb146, %bb139 - %676 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] - %677 = getelementptr inbounds %struct.GLDState* %676, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] - %678 = getelementptr inbounds %struct.GLDMaskMode* %677, i32 0, i32 4 ; [#uses=1] - %679 = load i8* %678, align 2 ; [#uses=1] - %680 = zext i8 %679 to i32 ; [#uses=1] - %681 = load i32* %cur_draw_buffer_mask_bit115, align 4 ; [#uses=1] - %682 = and i32 %680, %681 ; [#uses=1] - %683 = icmp ne i32 %682, 0 ; [#uses=1] - br i1 %683, label %bb148, label %bb155 - -bb148: ; preds = %bb147 - %684 = load float* %b121, align 4 ; [#uses=1] - %685 = fcmp uge float %684, 0.000000e+00 ; [#uses=1] - br i1 %685, label %bb149, label %bb153 - -bb149: ; preds = %bb148 - %686 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %687 = getelementptr inbounds %struct.GLDContextRec* %686, i32 0, i32 7 ; [#uses=1] - %688 = load float* %687, align 4 ; [#uses=1] - %689 = load float* %b121, align 4 ; [#uses=1] - %690 = fcmp olt float %688, %689 ; [#uses=1] - br i1 %690, label %bb150, label %bb151 - -bb150: ; preds = %bb149 - %691 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %692 = getelementptr inbounds %struct.GLDContextRec* %691, i32 0, i32 7 ; [#uses=1] - %693 = load float* %692, align 4 ; [#uses=1] - %694 = fptoui float %693 to i8 ; [#uses=1] - store i8 %694, i8* %iftmp.174, align 1 - br label %bb152 - -bb151: ; preds = %bb149 - %695 = load float* %b121, align 4 ; [#uses=1] - %696 = fptoui float %695 to i8 ; [#uses=1] - store i8 %696, i8* %iftmp.174, align 1 - br label %bb152 - -bb152: ; preds = %bb151, %bb150 - %697 = load i8* %iftmp.174, align 1 ; [#uses=1] - store i8 %697, i8* %iftmp.173, align 1 - br label %bb154 - -bb153: ; preds = %bb148 - store i8 0, i8* %iftmp.173, align 1 - br label %bb154 - -bb154: ; preds = %bb153, %bb152 - %698 = load i8** %color_ptr111, align 4 ; [#uses=1] - %699 = getelementptr inbounds i8* %698, i32 3 ; [#uses=1] - %700 = load i8* %iftmp.173, align 1 ; [#uses=1] - store i8 %700, i8* %699, align 1 - br label %bb155 - -bb155: ; preds = %bb154, %bb147 - br label %bb188 - -bb156: ; preds = %bb118 - %701 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] - %702 = getelementptr inbounds %struct.GLDState* %701, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] - %703 = getelementptr inbounds %struct.GLDMaskMode* %702, i32 0, i32 5 ; [#uses=1] - %704 = load i8* %703, align 1 ; [#uses=1] - %705 = zext i8 %704 to i32 ; [#uses=1] - %706 = load i32* %cur_draw_buffer_mask_bit115, align 4 ; [#uses=1] - %707 = and i32 %705, %706 ; [#uses=1] - %708 = icmp ne i32 %707, 0 ; [#uses=1] - br i1 %708, label %bb157, label %bb164 - -bb157: ; preds = %bb156 - %709 = load float* %a122, align 4 ; [#uses=1] - %710 = fcmp uge float %709, 0.000000e+00 ; [#uses=1] - br i1 %710, label %bb158, label %bb162 - -bb158: ; preds = %bb157 - %711 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %712 = getelementptr inbounds %struct.GLDContextRec* %711, i32 0, i32 7 ; [#uses=1] - %713 = load float* %712, align 4 ; [#uses=1] - %714 = load float* %a122, align 4 ; [#uses=1] - %715 = fcmp olt float %713, %714 ; [#uses=1] - br i1 %715, label %bb159, label %bb160 - -bb159: ; preds = %bb158 - %716 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %717 = getelementptr inbounds %struct.GLDContextRec* %716, i32 0, i32 7 ; [#uses=1] - %718 = load float* %717, align 4 ; [#uses=1] - %719 = fptoui float %718 to i8 ; [#uses=1] - store i8 %719, i8* %iftmp.176, align 1 - br label %bb161 - -bb160: ; preds = %bb158 - %720 = load float* %a122, align 4 ; [#uses=1] - %721 = fptoui float %720 to i8 ; [#uses=1] - store i8 %721, i8* %iftmp.176, align 1 - br label %bb161 - -bb161: ; preds = %bb160, %bb159 - %722 = load i8* %iftmp.176, align 1 ; [#uses=1] - store i8 %722, i8* %iftmp.175, align 1 - br label %bb163 - -bb162: ; preds = %bb157 - store i8 0, i8* %iftmp.175, align 1 - br label %bb163 - -bb163: ; preds = %bb162, %bb161 - %723 = load i8** %color_ptr111, align 4 ; [#uses=1] - %724 = getelementptr inbounds i8* %723, i32 3 ; [#uses=1] - %725 = load i8* %iftmp.175, align 1 ; [#uses=1] - store i8 %725, i8* %724, align 1 - br label %bb164 - -bb164: ; preds = %bb163, %bb156 - %726 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] - %727 = getelementptr inbounds %struct.GLDState* %726, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] - %728 = getelementptr inbounds %struct.GLDMaskMode* %727, i32 0, i32 2 ; [#uses=1] - %729 = load i8* %728, align 16 ; [#uses=1] - %730 = zext i8 %729 to i32 ; [#uses=1] - %731 = load i32* %cur_draw_buffer_mask_bit115, align 4 ; [#uses=1] - %732 = and i32 %730, %731 ; [#uses=1] - %733 = icmp ne i32 %732, 0 ; [#uses=1] - br i1 %733, label %bb165, label %bb172 - -bb165: ; preds = %bb164 - %734 = load float* %r119, align 4 ; [#uses=1] - %735 = fcmp uge float %734, 0.000000e+00 ; [#uses=1] - br i1 %735, label %bb166, label %bb170 - -bb166: ; preds = %bb165 - %736 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %737 = getelementptr inbounds %struct.GLDContextRec* %736, i32 0, i32 7 ; [#uses=1] - %738 = load float* %737, align 4 ; [#uses=1] - %739 = load float* %r119, align 4 ; [#uses=1] - %740 = fcmp olt float %738, %739 ; [#uses=1] - br i1 %740, label %bb167, label %bb168 - -bb167: ; preds = %bb166 - %741 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %742 = getelementptr inbounds %struct.GLDContextRec* %741, i32 0, i32 7 ; [#uses=1] - %743 = load float* %742, align 4 ; [#uses=1] - %744 = fptoui float %743 to i8 ; [#uses=1] - store i8 %744, i8* %iftmp.178, align 1 - br label %bb169 - -bb168: ; preds = %bb166 - %745 = load float* %r119, align 4 ; [#uses=1] - %746 = fptoui float %745 to i8 ; [#uses=1] - store i8 %746, i8* %iftmp.178, align 1 - br label %bb169 - -bb169: ; preds = %bb168, %bb167 - %747 = load i8* %iftmp.178, align 1 ; [#uses=1] - store i8 %747, i8* %iftmp.177, align 1 - br label %bb171 - -bb170: ; preds = %bb165 - store i8 0, i8* %iftmp.177, align 1 - br label %bb171 - -bb171: ; preds = %bb170, %bb169 - %748 = load i8** %color_ptr111, align 4 ; [#uses=1] - %749 = getelementptr inbounds i8* %748, i32 2 ; [#uses=1] - %750 = load i8* %iftmp.177, align 1 ; [#uses=1] - store i8 %750, i8* %749, align 1 - br label %bb172 - -bb172: ; preds = %bb171, %bb164 - %751 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] - %752 = getelementptr inbounds %struct.GLDState* %751, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] - %753 = getelementptr inbounds %struct.GLDMaskMode* %752, i32 0, i32 3 ; [#uses=1] - %754 = load i8* %753, align 1 ; [#uses=1] - %755 = zext i8 %754 to i32 ; [#uses=1] - %756 = load i32* %cur_draw_buffer_mask_bit115, align 4 ; [#uses=1] - %757 = and i32 %755, %756 ; [#uses=1] - %758 = icmp ne i32 %757, 0 ; [#uses=1] - br i1 %758, label %bb173, label %bb180 - -bb173: ; preds = %bb172 - %759 = load float* %g120, align 4 ; [#uses=1] - %760 = fcmp uge float %759, 0.000000e+00 ; [#uses=1] - br i1 %760, label %bb174, label %bb178 - -bb174: ; preds = %bb173 - %761 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %762 = getelementptr inbounds %struct.GLDContextRec* %761, i32 0, i32 7 ; [#uses=1] - %763 = load float* %762, align 4 ; [#uses=1] - %764 = load float* %g120, align 4 ; [#uses=1] - %765 = fcmp olt float %763, %764 ; [#uses=1] - br i1 %765, label %bb175, label %bb176 - -bb175: ; preds = %bb174 - %766 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %767 = getelementptr inbounds %struct.GLDContextRec* %766, i32 0, i32 7 ; [#uses=1] - %768 = load float* %767, align 4 ; [#uses=1] - %769 = fptoui float %768 to i8 ; [#uses=1] - store i8 %769, i8* %iftmp.180, align 1 - br label %bb177 - -bb176: ; preds = %bb174 - %770 = load float* %g120, align 4 ; [#uses=1] - %771 = fptoui float %770 to i8 ; [#uses=1] - store i8 %771, i8* %iftmp.180, align 1 - br label %bb177 - -bb177: ; preds = %bb176, %bb175 - %772 = load i8* %iftmp.180, align 1 ; [#uses=1] - store i8 %772, i8* %iftmp.179, align 1 - br label %bb179 - -bb178: ; preds = %bb173 - store i8 0, i8* %iftmp.179, align 1 - br label %bb179 - -bb179: ; preds = %bb178, %bb177 - %773 = load i8** %color_ptr111, align 4 ; [#uses=1] - %774 = getelementptr inbounds i8* %773, i32 1 ; [#uses=1] - %775 = load i8* %iftmp.179, align 1 ; [#uses=1] - store i8 %775, i8* %774, align 1 - br label %bb180 - -bb180: ; preds = %bb179, %bb172 - %776 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] - %777 = getelementptr inbounds %struct.GLDState* %776, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] - %778 = getelementptr inbounds %struct.GLDMaskMode* %777, i32 0, i32 4 ; [#uses=1] - %779 = load i8* %778, align 2 ; [#uses=1] - %780 = zext i8 %779 to i32 ; [#uses=1] - %781 = load i32* %cur_draw_buffer_mask_bit115, align 4 ; [#uses=1] - %782 = and i32 %780, %781 ; [#uses=1] - %783 = icmp ne i32 %782, 0 ; [#uses=1] - br i1 %783, label %bb181, label %bb188 - -bb181: ; preds = %bb180 - %784 = load float* %b121, align 4 ; [#uses=1] - %785 = fcmp uge float %784, 0.000000e+00 ; [#uses=1] - br i1 %785, label %bb182, label %bb186 - -bb182: ; preds = %bb181 - %786 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %787 = getelementptr inbounds %struct.GLDContextRec* %786, i32 0, i32 7 ; [#uses=1] - %788 = load float* %787, align 4 ; [#uses=1] - %789 = load float* %b121, align 4 ; [#uses=1] - %790 = fcmp olt float %788, %789 ; [#uses=1] - br i1 %790, label %bb183, label %bb184 - -bb183: ; preds = %bb182 - %791 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %792 = getelementptr inbounds %struct.GLDContextRec* %791, i32 0, i32 7 ; [#uses=1] - %793 = load float* %792, align 4 ; [#uses=1] - %794 = fptoui float %793 to i8 ; [#uses=1] - store i8 %794, i8* %iftmp.182, align 1 - br label %bb185 - -bb184: ; preds = %bb182 - %795 = load float* %b121, align 4 ; [#uses=1] - %796 = fptoui float %795 to i8 ; [#uses=1] - store i8 %796, i8* %iftmp.182, align 1 - br label %bb185 - -bb185: ; preds = %bb184, %bb183 - %797 = load i8* %iftmp.182, align 1 ; [#uses=1] - store i8 %797, i8* %iftmp.181, align 1 - br label %bb187 - -bb186: ; preds = %bb181 - store i8 0, i8* %iftmp.181, align 1 - br label %bb187 - -bb187: ; preds = %bb186, %bb185 - %798 = load i8** %color_ptr111, align 4 ; [#uses=1] - %799 = getelementptr inbounds i8* %798, i32 0 ; [#uses=1] - %800 = load i8* %iftmp.181, align 1 ; [#uses=1] - store i8 %800, i8* %799, align 1 - br label %bb188 - -bb188: ; preds = %bb187, %bb180, %bb155 - %801 = load double** %accum, align 4 ; [#uses=1] - %802 = getelementptr inbounds double* %801, i32 4 ; [#uses=1] - store double* %802, double** %accum, align 4 - %803 = load i8** %color_ptr111, align 4 ; [#uses=1] - %804 = getelementptr inbounds i8* %803, i32 4 ; [#uses=1] - store i8* %804, i8** %color_ptr111, align 4 - br label %bb189 - -bb189: ; preds = %bb188, %bb117 - %805 = load double** %accum, align 4 ; [#uses=1] - %806 = load double** %accum_end, align 4 ; [#uses=1] - %807 = icmp ult double* %805, %806 ; [#uses=1] - br i1 %807, label %bb118, label %bb190 - -bb190: ; preds = %bb189 - br label %bb224 - -bb191: ; preds = %bb116 - br label %bb223 - -bb192: ; preds = %bb223 - %808 = load double** %accum, align 4 ; [#uses=1] - %809 = getelementptr inbounds double* %808, i32 0 ; [#uses=1] - %810 = load double* %809, align 1 ; [#uses=1] - %811 = fptrunc double %810 to float ; [#uses=1] - %812 = load float* %value_addr, align 4 ; [#uses=1] - %813 = fmul float %811, %812 ; [#uses=1] - %814 = load float* %twoFiftyFive, align 4 ; [#uses=1] - %815 = fmul float %813, %814 ; [#uses=1] - %816 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %817 = getelementptr inbounds %struct.GLDContextRec* %816, i32 0, i32 1 ; [#uses=1] - %818 = load float* %817, align 4 ; [#uses=1] - %819 = fadd float %815, %818 ; [#uses=1] - %820 = fcmp uge float %819, 0.000000e+00 ; [#uses=1] - br i1 %820, label %bb197, label %bb201 - -bb197: ; preds = %bb192 - %821 = load double** %accum, align 4 ; [#uses=1] - %822 = getelementptr inbounds double* %821, i32 0 ; [#uses=1] - %823 = load double* %822, align 1 ; [#uses=1] - %824 = fptrunc double %823 to float ; [#uses=1] - %825 = load float* %value_addr, align 4 ; [#uses=1] - %826 = fmul float %824, %825 ; [#uses=1] - %827 = load float* %twoFiftyFive, align 4 ; [#uses=1] - %828 = fmul float %826, %827 ; [#uses=1] - %829 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %830 = getelementptr inbounds %struct.GLDContextRec* %829, i32 0, i32 1 ; [#uses=1] - %831 = load float* %830, align 4 ; [#uses=1] - %832 = fadd float %828, %831 ; [#uses=1] - %833 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %834 = getelementptr inbounds %struct.GLDContextRec* %833, i32 0, i32 7 ; [#uses=1] - %835 = load float* %834, align 4 ; [#uses=1] - %836 = fcmp ogt float %832, %835 ; [#uses=1] - br i1 %836, label %bb198, label %bb199 - -bb198: ; preds = %bb197 - %837 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %838 = getelementptr inbounds %struct.GLDContextRec* %837, i32 0, i32 7 ; [#uses=1] - %839 = load float* %838, align 4 ; [#uses=1] - %840 = fptoui float %839 to i8 ; [#uses=1] - %841 = zext i8 %840 to i32 ; [#uses=1] - store i32 %841, i32* %iftmp.184, align 4 - br label %bb200 - -bb199: ; preds = %bb197 - %842 = load double** %accum, align 4 ; [#uses=1] - %843 = getelementptr inbounds double* %842, i32 0 ; [#uses=1] - %844 = load double* %843, align 1 ; [#uses=1] - %845 = fptrunc double %844 to float ; [#uses=1] - %846 = load float* %value_addr, align 4 ; [#uses=1] - %847 = fmul float %845, %846 ; [#uses=1] - %848 = load float* %twoFiftyFive, align 4 ; [#uses=1] - %849 = fmul float %847, %848 ; [#uses=1] - %850 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %851 = getelementptr inbounds %struct.GLDContextRec* %850, i32 0, i32 1 ; [#uses=1] - %852 = load float* %851, align 4 ; [#uses=1] - %853 = fadd float %849, %852 ; [#uses=1] - %854 = fptoui float %853 to i8 ; [#uses=1] - %855 = zext i8 %854 to i32 ; [#uses=1] - store i32 %855, i32* %iftmp.184, align 4 - br label %bb200 - -bb200: ; preds = %bb199, %bb198 - %856 = load i32* %iftmp.184, align 4 ; [#uses=1] - store i32 %856, i32* %iftmp.183, align 4 - br label %bb202 - -bb201: ; preds = %bb192 - store i32 0, i32* %iftmp.183, align 4 - br label %bb202 - -bb202: ; preds = %bb201, %bb200 - %857 = load i32* %iftmp.183, align 4 ; [#uses=1] - store i32 %857, i32* %r193, align 4 - %858 = load double** %accum, align 4 ; [#uses=1] - %859 = getelementptr inbounds double* %858, i32 1 ; [#uses=1] - %860 = load double* %859, align 1 ; [#uses=1] - %861 = fptrunc double %860 to float ; [#uses=1] - %862 = load float* %value_addr, align 4 ; [#uses=1] - %863 = fmul float %861, %862 ; [#uses=1] - %864 = load float* %twoFiftyFive, align 4 ; [#uses=1] - %865 = fmul float %863, %864 ; [#uses=1] - %866 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %867 = getelementptr inbounds %struct.GLDContextRec* %866, i32 0, i32 1 ; [#uses=1] - %868 = load float* %867, align 4 ; [#uses=1] - %869 = fadd float %865, %868 ; [#uses=1] - %870 = fcmp uge float %869, 0.000000e+00 ; [#uses=1] - br i1 %870, label %bb203, label %bb207 - -bb203: ; preds = %bb202 - %871 = load double** %accum, align 4 ; [#uses=1] - %872 = getelementptr inbounds double* %871, i32 1 ; [#uses=1] - %873 = load double* %872, align 1 ; [#uses=1] - %874 = fptrunc double %873 to float ; [#uses=1] - %875 = load float* %value_addr, align 4 ; [#uses=1] - %876 = fmul float %874, %875 ; [#uses=1] - %877 = load float* %twoFiftyFive, align 4 ; [#uses=1] - %878 = fmul float %876, %877 ; [#uses=1] - %879 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %880 = getelementptr inbounds %struct.GLDContextRec* %879, i32 0, i32 1 ; [#uses=1] - %881 = load float* %880, align 4 ; [#uses=1] - %882 = fadd float %878, %881 ; [#uses=1] - %883 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %884 = getelementptr inbounds %struct.GLDContextRec* %883, i32 0, i32 7 ; [#uses=1] - %885 = load float* %884, align 4 ; [#uses=1] - %886 = fcmp ogt float %882, %885 ; [#uses=1] - br i1 %886, label %bb204, label %bb205 - -bb204: ; preds = %bb203 - %887 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %888 = getelementptr inbounds %struct.GLDContextRec* %887, i32 0, i32 7 ; [#uses=1] - %889 = load float* %888, align 4 ; [#uses=1] - %890 = fptoui float %889 to i8 ; [#uses=1] - %891 = zext i8 %890 to i32 ; [#uses=1] - store i32 %891, i32* %iftmp.186, align 4 - br label %bb206 - -bb205: ; preds = %bb203 - %892 = load double** %accum, align 4 ; [#uses=1] - %893 = getelementptr inbounds double* %892, i32 1 ; [#uses=1] - %894 = load double* %893, align 1 ; [#uses=1] - %895 = fptrunc double %894 to float ; [#uses=1] - %896 = load float* %value_addr, align 4 ; [#uses=1] - %897 = fmul float %895, %896 ; [#uses=1] - %898 = load float* %twoFiftyFive, align 4 ; [#uses=1] - %899 = fmul float %897, %898 ; [#uses=1] - %900 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %901 = getelementptr inbounds %struct.GLDContextRec* %900, i32 0, i32 1 ; [#uses=1] - %902 = load float* %901, align 4 ; [#uses=1] - %903 = fadd float %899, %902 ; [#uses=1] - %904 = fptoui float %903 to i8 ; [#uses=1] - %905 = zext i8 %904 to i32 ; [#uses=1] - store i32 %905, i32* %iftmp.186, align 4 - br label %bb206 - -bb206: ; preds = %bb205, %bb204 - %906 = load i32* %iftmp.186, align 4 ; [#uses=1] - store i32 %906, i32* %iftmp.185, align 4 - br label %bb208 - -bb207: ; preds = %bb202 - store i32 0, i32* %iftmp.185, align 4 - br label %bb208 - -bb208: ; preds = %bb207, %bb206 - %907 = load i32* %iftmp.185, align 4 ; [#uses=1] - store i32 %907, i32* %g194, align 4 - %908 = load double** %accum, align 4 ; [#uses=1] - %909 = getelementptr inbounds double* %908, i32 2 ; [#uses=1] - %910 = load double* %909, align 1 ; [#uses=1] - %911 = fptrunc double %910 to float ; [#uses=1] - %912 = load float* %value_addr, align 4 ; [#uses=1] - %913 = fmul float %911, %912 ; [#uses=1] - %914 = load float* %twoFiftyFive, align 4 ; [#uses=1] - %915 = fmul float %913, %914 ; [#uses=1] - %916 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %917 = getelementptr inbounds %struct.GLDContextRec* %916, i32 0, i32 1 ; [#uses=1] - %918 = load float* %917, align 4 ; [#uses=1] - %919 = fadd float %915, %918 ; [#uses=1] - %920 = fcmp uge float %919, 0.000000e+00 ; [#uses=1] - br i1 %920, label %bb209, label %bb213 - -bb209: ; preds = %bb208 - %921 = load double** %accum, align 4 ; [#uses=1] - %922 = getelementptr inbounds double* %921, i32 2 ; [#uses=1] - %923 = load double* %922, align 1 ; [#uses=1] - %924 = fptrunc double %923 to float ; [#uses=1] - %925 = load float* %value_addr, align 4 ; [#uses=1] - %926 = fmul float %924, %925 ; [#uses=1] - %927 = load float* %twoFiftyFive, align 4 ; [#uses=1] - %928 = fmul float %926, %927 ; [#uses=1] - %929 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %930 = getelementptr inbounds %struct.GLDContextRec* %929, i32 0, i32 1 ; [#uses=1] - %931 = load float* %930, align 4 ; [#uses=1] - %932 = fadd float %928, %931 ; [#uses=1] - %933 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %934 = getelementptr inbounds %struct.GLDContextRec* %933, i32 0, i32 7 ; [#uses=1] - %935 = load float* %934, align 4 ; [#uses=1] - %936 = fcmp ogt float %932, %935 ; [#uses=1] - br i1 %936, label %bb210, label %bb211 - -bb210: ; preds = %bb209 - %937 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %938 = getelementptr inbounds %struct.GLDContextRec* %937, i32 0, i32 7 ; [#uses=1] - %939 = load float* %938, align 4 ; [#uses=1] - %940 = fptoui float %939 to i8 ; [#uses=1] - %941 = zext i8 %940 to i32 ; [#uses=1] - store i32 %941, i32* %iftmp.188, align 4 - br label %bb212 - -bb211: ; preds = %bb209 - %942 = load double** %accum, align 4 ; [#uses=1] - %943 = getelementptr inbounds double* %942, i32 2 ; [#uses=1] - %944 = load double* %943, align 1 ; [#uses=1] - %945 = fptrunc double %944 to float ; [#uses=1] - %946 = load float* %value_addr, align 4 ; [#uses=1] - %947 = fmul float %945, %946 ; [#uses=1] - %948 = load float* %twoFiftyFive, align 4 ; [#uses=1] - %949 = fmul float %947, %948 ; [#uses=1] - %950 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %951 = getelementptr inbounds %struct.GLDContextRec* %950, i32 0, i32 1 ; [#uses=1] - %952 = load float* %951, align 4 ; [#uses=1] - %953 = fadd float %949, %952 ; [#uses=1] - %954 = fptoui float %953 to i8 ; [#uses=1] - %955 = zext i8 %954 to i32 ; [#uses=1] - store i32 %955, i32* %iftmp.188, align 4 - br label %bb212 - -bb212: ; preds = %bb211, %bb210 - %956 = load i32* %iftmp.188, align 4 ; [#uses=1] - store i32 %956, i32* %iftmp.187, align 4 - br label %bb214 - -bb213: ; preds = %bb208 - store i32 0, i32* %iftmp.187, align 4 - br label %bb214 - -bb214: ; preds = %bb213, %bb212 - %957 = load i32* %iftmp.187, align 4 ; [#uses=1] - store i32 %957, i32* %b195, align 4 - %958 = load double** %accum, align 4 ; [#uses=1] - %959 = getelementptr inbounds double* %958, i32 3 ; [#uses=1] - %960 = load double* %959, align 1 ; [#uses=1] - %961 = fptrunc double %960 to float ; [#uses=1] - %962 = load float* %value_addr, align 4 ; [#uses=1] - %963 = fmul float %961, %962 ; [#uses=1] - %964 = load float* %twoFiftyFive, align 4 ; [#uses=1] - %965 = fmul float %963, %964 ; [#uses=1] - %966 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %967 = getelementptr inbounds %struct.GLDContextRec* %966, i32 0, i32 1 ; [#uses=1] - %968 = load float* %967, align 4 ; [#uses=1] - %969 = fadd float %965, %968 ; [#uses=1] - %970 = fcmp uge float %969, 0.000000e+00 ; [#uses=1] - br i1 %970, label %bb215, label %bb219 - -bb215: ; preds = %bb214 - %971 = load double** %accum, align 4 ; [#uses=1] - %972 = getelementptr inbounds double* %971, i32 3 ; [#uses=1] - %973 = load double* %972, align 1 ; [#uses=1] - %974 = fptrunc double %973 to float ; [#uses=1] - %975 = load float* %value_addr, align 4 ; [#uses=1] - %976 = fmul float %974, %975 ; [#uses=1] - %977 = load float* %twoFiftyFive, align 4 ; [#uses=1] - %978 = fmul float %976, %977 ; [#uses=1] - %979 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %980 = getelementptr inbounds %struct.GLDContextRec* %979, i32 0, i32 1 ; [#uses=1] - %981 = load float* %980, align 4 ; [#uses=1] - %982 = fadd float %978, %981 ; [#uses=1] - %983 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %984 = getelementptr inbounds %struct.GLDContextRec* %983, i32 0, i32 7 ; [#uses=1] - %985 = load float* %984, align 4 ; [#uses=1] - %986 = fcmp ogt float %982, %985 ; [#uses=1] - br i1 %986, label %bb216, label %bb217 - -bb216: ; preds = %bb215 - %987 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %988 = getelementptr inbounds %struct.GLDContextRec* %987, i32 0, i32 7 ; [#uses=1] - %989 = load float* %988, align 4 ; [#uses=1] - %990 = fptoui float %989 to i8 ; [#uses=1] - %991 = zext i8 %990 to i32 ; [#uses=1] - store i32 %991, i32* %iftmp.190, align 4 - br label %bb218 - -bb217: ; preds = %bb215 - %992 = load double** %accum, align 4 ; [#uses=1] - %993 = getelementptr inbounds double* %992, i32 3 ; [#uses=1] - %994 = load double* %993, align 1 ; [#uses=1] - %995 = fptrunc double %994 to float ; [#uses=1] - %996 = load float* %value_addr, align 4 ; [#uses=1] - %997 = fmul float %995, %996 ; [#uses=1] - %998 = load float* %twoFiftyFive, align 4 ; [#uses=1] - %999 = fmul float %997, %998 ; [#uses=1] - %1000 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %1001 = getelementptr inbounds %struct.GLDContextRec* %1000, i32 0, i32 1 ; [#uses=1] - %1002 = load float* %1001, align 4 ; [#uses=1] - %1003 = fadd float %999, %1002 ; [#uses=1] - %1004 = fptoui float %1003 to i8 ; [#uses=1] - %1005 = zext i8 %1004 to i32 ; [#uses=1] - store i32 %1005, i32* %iftmp.190, align 4 - br label %bb218 - -bb218: ; preds = %bb217, %bb216 - %1006 = load i32* %iftmp.190, align 4 ; [#uses=1] - store i32 %1006, i32* %iftmp.189, align 4 - br label %bb220 - -bb219: ; preds = %bb214 - store i32 0, i32* %iftmp.189, align 4 - br label %bb220 - -bb220: ; preds = %bb219, %bb218 - %1007 = load i32* %iftmp.189, align 4 ; [#uses=1] - store i32 %1007, i32* %a196, align 4 - %1008 = load i32* %a196, align 4 ; [#uses=1] - %1009 = shl i32 %1008, 24 ; [#uses=1] - %1010 = load i32* %r193, align 4 ; [#uses=1] - %1011 = shl i32 %1010, 16 ; [#uses=1] - %1012 = or i32 %1009, %1011 ; [#uses=1] - %1013 = load i32* %g194, align 4 ; [#uses=1] - %1014 = shl i32 %1013, 8 ; [#uses=1] - %1015 = or i32 %1012, %1014 ; [#uses=1] - %1016 = load i32* %b195, align 4 ; [#uses=1] - %1017 = or i32 %1015, %1016 ; [#uses=1] - store i32 %1017, i32* %color, align 4 - %1018 = load i8* %swap, align 1 ; [#uses=1] - %1019 = icmp ne i8 %1018, 0 ; [#uses=1] - br i1 %1019, label %bb221, label %bb222 - -bb221: ; preds = %bb220 - %1020 = load i32* %color, align 4 ; [#uses=1] - %1021 = call i32 @_OSSwapInt32(i32 %1020) nounwind inlinehint ssp ; [#uses=1] - store i32 %1021, i32* %color, align 4 - br label %bb222 - -bb222: ; preds = %bb221, %bb220 - %1022 = load i8** %color_ptr111, align 4 ; [#uses=1] - %1023 = bitcast i8* %1022 to i32* ; [#uses=1] - %1024 = getelementptr inbounds i32* %1023, i32 0 ; [#uses=1] - %1025 = load i32* %color, align 4 ; [#uses=1] - store i32 %1025, i32* %1024, align 1 - %1026 = load double** %accum, align 4 ; [#uses=1] - %1027 = getelementptr inbounds double* %1026, i32 4 ; [#uses=1] - store double* %1027, double** %accum, align 4 - %1028 = load i8** %color_ptr111, align 4 ; [#uses=1] - %1029 = getelementptr inbounds i8* %1028, i32 4 ; [#uses=1] - store i8* %1029, i8** %color_ptr111, align 4 - br label %bb223 - -bb223: ; preds = %bb222, %bb191 - %1030 = load double** %accum, align 4 ; [#uses=1] - %1031 = load double** %accum_end, align 4 ; [#uses=1] - %1032 = icmp ult double* %1030, %1031 ; [#uses=1] - br i1 %1032, label %bb192, label %bb224 - -bb224: ; preds = %bb223, %bb190 - %1033 = load i32* %y, align 4 ; [#uses=1] - %1034 = add i32 %1033, 1 ; [#uses=1] - store i32 %1034, i32* %y, align 4 - %1035 = load i32* %offset, align 4 ; [#uses=1] - %1036 = load i32* %y_inc, align 4 ; [#uses=1] - %1037 = add i32 %1035, %1036 ; [#uses=1] - store i32 %1037, i32* %offset, align 4 - br label %bb225 - -bb225: ; preds = %bb224, %bb114 - %1038 = load i32* %y, align 4 ; [#uses=1] - %1039 = load i32* %yl, align 4 ; [#uses=1] - %1040 = icmp ult i32 %1038, %1039 ; [#uses=1] - br i1 %1040, label %bb116, label %bb226 - -bb226: ; preds = %bb225, %bb113 - %1041 = load i32* %draw_buffer, align 4 ; [#uses=1] - %1042 = add nsw i32 %1041, 1 ; [#uses=1] - store i32 %1042, i32* %draw_buffer, align 4 - br label %bb227 - -bb227: ; preds = %bb226, %bb110 - %1043 = load i32* %draw_buffer, align 4 ; [#uses=1] - %1044 = icmp sle i32 %1043, 7 ; [#uses=1] - br i1 %1044, label %bb113, label %bb228 - -bb228: ; preds = %bb227 - br label %bb316 - -bb229: ; preds = %bb108 - %1045 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %1046 = getelementptr inbounds %struct.GLDContextRec* %1045, i32 0, i32 28 ; <%struct.GLDFramebufferRec**> [#uses=1] - %1047 = load %struct.GLDFramebufferRec** %1046, align 4 ; <%struct.GLDFramebufferRec*> [#uses=1] - %1048 = icmp ne %struct.GLDFramebufferRec* %1047, null ; [#uses=1] - br i1 %1048, label %bb230, label %bb231 - -bb230: ; preds = %bb229 - %1049 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %1050 = getelementptr inbounds %struct.GLDContextRec* %1049, i32 0, i32 28 ; <%struct.GLDFramebufferRec**> [#uses=1] - %1051 = load %struct.GLDFramebufferRec** %1050, align 4 ; <%struct.GLDFramebufferRec*> [#uses=1] - %1052 = getelementptr inbounds %struct.GLDFramebufferRec* %1051, i32 0, i32 2 ; <[10 x %struct.GLDFormat]*> [#uses=1] - %1053 = getelementptr inbounds [10 x %struct.GLDFormat]* %1052, i32 0, i32 0 ; <%struct.GLDFormat*> [#uses=1] - %1054 = getelementptr inbounds %struct.GLDFormat* %1053, i32 0, i32 7 ; [#uses=1] - %1055 = load i32* %1054, align 4 ; [#uses=1] - %1056 = icmp eq i32 %1055, 5123 ; [#uses=1] - %1057 = zext i1 %1056 to i8 ; [#uses=1] - store i8 %1057, i8* %iftmp.192, align 1 - br label %bb232 - -bb231: ; preds = %bb229 - %1058 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %1059 = getelementptr inbounds %struct.GLDContextRec* %1058, i32 0, i32 56 ; <%struct.GLDFormat*> [#uses=1] - %1060 = getelementptr inbounds %struct.GLDFormat* %1059, i32 0, i32 7 ; [#uses=1] - %1061 = load i32* %1060, align 4 ; [#uses=1] - %1062 = icmp eq i32 %1061, 5123 ; [#uses=1] - %1063 = zext i1 %1062 to i8 ; [#uses=1] - store i8 %1063, i8* %iftmp.192, align 1 - br label %bb232 - -bb232: ; preds = %bb231, %bb230 - %1064 = load i8* %iftmp.192, align 1 ; [#uses=1] - %toBool233 = icmp ne i8 %1064, 0 ; [#uses=1] - br i1 %toBool233, label %bb316, label %bb234 - -bb234: ; preds = %bb232 - %1065 = load i32* %offset, align 4 ; [#uses=1] - store i32 %1065, i32* %start_offset236, align 4 - store i32 0, i32* %draw_buffer, align 4 - br label %bb315 - -bb237: ; preds = %bb315 - %1066 = load i32* %draw_buffer, align 4 ; [#uses=1] - %1067 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %1068 = getelementptr inbounds %struct.GLDContextRec* %1067, i32 0, i32 30 ; <%struct.GLDBufferstate*> [#uses=1] - %1069 = getelementptr inbounds %struct.GLDBufferstate* %1068, i32 0, i32 12 ; <[8 x %union.GLSBuffer]*> [#uses=1] - %1070 = getelementptr inbounds [8 x %union.GLSBuffer]* %1069, i32 0, i32 %1066 ; <%union.GLSBuffer*> [#uses=1] - %1071 = getelementptr inbounds %union.GLSBuffer* %1070, i32 0, i32 0 ; [#uses=1] - %1072 = load i8** %1071, align 4 ; [#uses=1] - %1073 = icmp ne i8* %1072, null ; [#uses=1] - br i1 %1073, label %bb238, label %bb314 - -bb238: ; preds = %bb237 - %1074 = load i32* %draw_buffer, align 4 ; [#uses=1] - %1075 = shl i32 1, %1074 ; [#uses=1] - store i32 %1075, i32* %cur_draw_buffer_mask_bit239, align 4 - %1076 = load i32* %start_offset236, align 4 ; [#uses=1] - store i32 %1076, i32* %offset, align 4 - %1077 = load i32* %cy, align 4 ; [#uses=1] - store i32 %1077, i32* %y, align 4 - br label %bb313 - -bb240: ; preds = %bb313 - %1078 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %1079 = getelementptr inbounds %struct.GLDContextRec* %1078, i32 0, i32 30 ; <%struct.GLDBufferstate*> [#uses=1] - %1080 = getelementptr inbounds %struct.GLDBufferstate* %1079, i32 0, i32 11 ; <%union.GLSBuffer*> [#uses=1] - %1081 = getelementptr inbounds %union.GLSBuffer* %1080, i32 0, i32 0 ; [#uses=1] - %1082 = bitcast i8** %1081 to double** ; [#uses=1] - %1083 = load double** %1082, align 4 ; [#uses=1] - %1084 = load i32* %offset, align 4 ; [#uses=1] - %1085 = mul i32 %1084, 4 ; [#uses=1] - %1086 = getelementptr inbounds double* %1083, i32 %1085 ; [#uses=1] - store double* %1086, double** %accum, align 4 - %1087 = load double** %accum, align 4 ; [#uses=1] - %1088 = load i32* %cw4, align 4 ; [#uses=1] - %1089 = getelementptr inbounds double* %1087, i32 %1088 ; [#uses=1] - store double* %1089, double** %accum_end, align 4 - %1090 = load i32* %draw_buffer, align 4 ; [#uses=1] - %1091 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %1092 = getelementptr inbounds %struct.GLDContextRec* %1091, i32 0, i32 30 ; <%struct.GLDBufferstate*> [#uses=1] - %1093 = getelementptr inbounds %struct.GLDBufferstate* %1092, i32 0, i32 12 ; <[8 x %union.GLSBuffer]*> [#uses=1] - %1094 = getelementptr inbounds [8 x %union.GLSBuffer]* %1093, i32 0, i32 %1090 ; <%union.GLSBuffer*> [#uses=1] - %1095 = getelementptr inbounds %union.GLSBuffer* %1094, i32 0, i32 0 ; [#uses=1] - %1096 = bitcast i8** %1095 to float** ; [#uses=1] - %1097 = load float** %1096, align 4 ; [#uses=1] - %1098 = load i32* %offset, align 4 ; [#uses=1] - %1099 = mul i32 %1098, 4 ; [#uses=1] - %1100 = getelementptr inbounds float* %1097, i32 %1099 ; [#uses=1] - store float* %1100, float** %color_ptr235, align 4 - %1101 = load i8* %color_mask_enabled, align 1 ; [#uses=1] - %1102 = icmp ne i8 %1101, 0 ; [#uses=1] - br i1 %1102, label %bb241, label %bb281 - -bb241: ; preds = %bb240 - br label %bb279 - -bb242: ; preds = %bb279 - %1103 = load double** %accum, align 4 ; [#uses=1] - %1104 = getelementptr inbounds double* %1103, i32 0 ; [#uses=1] - %1105 = load double* %1104, align 1 ; [#uses=1] - %1106 = fptrunc double %1105 to float ; [#uses=1] - %1107 = load float* %value_addr, align 4 ; [#uses=1] - %1108 = fmul float %1106, %1107 ; [#uses=1] - store float %1108, float* %r243, align 4 - %1109 = load double** %accum, align 4 ; [#uses=1] - %1110 = getelementptr inbounds double* %1109, i32 1 ; [#uses=1] - %1111 = load double* %1110, align 1 ; [#uses=1] - %1112 = fptrunc double %1111 to float ; [#uses=1] - %1113 = load float* %value_addr, align 4 ; [#uses=1] - %1114 = fmul float %1112, %1113 ; [#uses=1] - store float %1114, float* %g244, align 4 - %1115 = load double** %accum, align 4 ; [#uses=1] - %1116 = getelementptr inbounds double* %1115, i32 2 ; [#uses=1] - %1117 = load double* %1116, align 1 ; [#uses=1] - %1118 = fptrunc double %1117 to float ; [#uses=1] - %1119 = load float* %value_addr, align 4 ; [#uses=1] - %1120 = fmul float %1118, %1119 ; [#uses=1] - store float %1120, float* %b245, align 4 - %1121 = load double** %accum, align 4 ; [#uses=1] - %1122 = getelementptr inbounds double* %1121, i32 3 ; [#uses=1] - %1123 = load double* %1122, align 1 ; [#uses=1] - %1124 = fptrunc double %1123 to float ; [#uses=1] - %1125 = load float* %value_addr, align 4 ; [#uses=1] - %1126 = fmul float %1124, %1125 ; [#uses=1] - store float %1126, float* %a246, align 4 - %1127 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] - %1128 = getelementptr inbounds %struct.GLDState* %1127, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] - %1129 = getelementptr inbounds %struct.GLDMaskMode* %1128, i32 0, i32 2 ; [#uses=1] - %1130 = load i8* %1129, align 16 ; [#uses=1] - %1131 = zext i8 %1130 to i32 ; [#uses=1] - %1132 = load i32* %cur_draw_buffer_mask_bit239, align 4 ; [#uses=1] - %1133 = and i32 %1131, %1132 ; [#uses=1] - %1134 = icmp ne i32 %1133, 0 ; [#uses=1] - br i1 %1134, label %bb247, label %bb254 - -bb247: ; preds = %bb242 - %1135 = load float* %r243, align 4 ; [#uses=1] - %1136 = fcmp uge float %1135, 0.000000e+00 ; [#uses=1] - br i1 %1136, label %bb248, label %bb252 - -bb248: ; preds = %bb247 - %1137 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %1138 = getelementptr inbounds %struct.GLDContextRec* %1137, i32 0, i32 2 ; [#uses=1] - %1139 = load float* %1138, align 4 ; [#uses=1] - %1140 = load float* %r243, align 4 ; [#uses=1] - %1141 = fcmp olt float %1139, %1140 ; [#uses=1] - br i1 %1141, label %bb249, label %bb250 - -bb249: ; preds = %bb248 - %1142 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %1143 = getelementptr inbounds %struct.GLDContextRec* %1142, i32 0, i32 2 ; [#uses=1] - %1144 = load float* %1143, align 4 ; [#uses=1] - store float %1144, float* %iftmp.196, align 4 - br label %bb251 - -bb250: ; preds = %bb248 - %1145 = load float* %r243, align 4 ; [#uses=1] - store float %1145, float* %iftmp.196, align 4 - br label %bb251 - -bb251: ; preds = %bb250, %bb249 - %1146 = load float* %iftmp.196, align 4 ; [#uses=1] - store float %1146, float* %iftmp.195, align 4 - br label %bb253 - -bb252: ; preds = %bb247 - store float 0.000000e+00, float* %iftmp.195, align 4 - br label %bb253 - -bb253: ; preds = %bb252, %bb251 - %1147 = load float** %color_ptr235, align 4 ; [#uses=1] - %1148 = getelementptr inbounds float* %1147, i32 0 ; [#uses=1] - %1149 = load float* %iftmp.195, align 4 ; [#uses=1] - store float %1149, float* %1148, align 1 - br label %bb254 - -bb254: ; preds = %bb253, %bb242 - %1150 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] - %1151 = getelementptr inbounds %struct.GLDState* %1150, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] - %1152 = getelementptr inbounds %struct.GLDMaskMode* %1151, i32 0, i32 3 ; [#uses=1] - %1153 = load i8* %1152, align 1 ; [#uses=1] - %1154 = zext i8 %1153 to i32 ; [#uses=1] - %1155 = load i32* %cur_draw_buffer_mask_bit239, align 4 ; [#uses=1] - %1156 = and i32 %1154, %1155 ; [#uses=1] - %1157 = icmp ne i32 %1156, 0 ; [#uses=1] - br i1 %1157, label %bb255, label %bb262 - -bb255: ; preds = %bb254 - %1158 = load float* %g244, align 4 ; [#uses=1] - %1159 = fcmp uge float %1158, 0.000000e+00 ; [#uses=1] - br i1 %1159, label %bb256, label %bb260 - -bb256: ; preds = %bb255 - %1160 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %1161 = getelementptr inbounds %struct.GLDContextRec* %1160, i32 0, i32 2 ; [#uses=1] - %1162 = load float* %1161, align 4 ; [#uses=1] - %1163 = load float* %g244, align 4 ; [#uses=1] - %1164 = fcmp olt float %1162, %1163 ; [#uses=1] - br i1 %1164, label %bb257, label %bb258 - -bb257: ; preds = %bb256 - %1165 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %1166 = getelementptr inbounds %struct.GLDContextRec* %1165, i32 0, i32 2 ; [#uses=1] - %1167 = load float* %1166, align 4 ; [#uses=1] - store float %1167, float* %iftmp.198, align 4 - br label %bb259 - -bb258: ; preds = %bb256 - %1168 = load float* %g244, align 4 ; [#uses=1] - store float %1168, float* %iftmp.198, align 4 - br label %bb259 - -bb259: ; preds = %bb258, %bb257 - %1169 = load float* %iftmp.198, align 4 ; [#uses=1] - store float %1169, float* %iftmp.197, align 4 - br label %bb261 - -bb260: ; preds = %bb255 - store float 0.000000e+00, float* %iftmp.197, align 4 - br label %bb261 - -bb261: ; preds = %bb260, %bb259 - %1170 = load float** %color_ptr235, align 4 ; [#uses=1] - %1171 = getelementptr inbounds float* %1170, i32 1 ; [#uses=1] - %1172 = load float* %iftmp.197, align 4 ; [#uses=1] - store float %1172, float* %1171, align 1 - br label %bb262 - -bb262: ; preds = %bb261, %bb254 - %1173 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] - %1174 = getelementptr inbounds %struct.GLDState* %1173, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] - %1175 = getelementptr inbounds %struct.GLDMaskMode* %1174, i32 0, i32 4 ; [#uses=1] - %1176 = load i8* %1175, align 2 ; [#uses=1] - %1177 = zext i8 %1176 to i32 ; [#uses=1] - %1178 = load i32* %cur_draw_buffer_mask_bit239, align 4 ; [#uses=1] - %1179 = and i32 %1177, %1178 ; [#uses=1] - %1180 = icmp ne i32 %1179, 0 ; [#uses=1] - br i1 %1180, label %bb263, label %bb270 - -bb263: ; preds = %bb262 - %1181 = load float* %b245, align 4 ; [#uses=1] - %1182 = fcmp uge float %1181, 0.000000e+00 ; [#uses=1] - br i1 %1182, label %bb264, label %bb268 - -bb264: ; preds = %bb263 - %1183 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %1184 = getelementptr inbounds %struct.GLDContextRec* %1183, i32 0, i32 2 ; [#uses=1] - %1185 = load float* %1184, align 4 ; [#uses=1] - %1186 = load float* %b245, align 4 ; [#uses=1] - %1187 = fcmp olt float %1185, %1186 ; [#uses=1] - br i1 %1187, label %bb265, label %bb266 - -bb265: ; preds = %bb264 - %1188 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %1189 = getelementptr inbounds %struct.GLDContextRec* %1188, i32 0, i32 2 ; [#uses=1] - %1190 = load float* %1189, align 4 ; [#uses=1] - store float %1190, float* %iftmp.200, align 4 - br label %bb267 - -bb266: ; preds = %bb264 - %1191 = load float* %b245, align 4 ; [#uses=1] - store float %1191, float* %iftmp.200, align 4 - br label %bb267 - -bb267: ; preds = %bb266, %bb265 - %1192 = load float* %iftmp.200, align 4 ; [#uses=1] - store float %1192, float* %iftmp.199, align 4 - br label %bb269 - -bb268: ; preds = %bb263 - store float 0.000000e+00, float* %iftmp.199, align 4 - br label %bb269 - -bb269: ; preds = %bb268, %bb267 - %1193 = load float** %color_ptr235, align 4 ; [#uses=1] - %1194 = getelementptr inbounds float* %1193, i32 2 ; [#uses=1] - %1195 = load float* %iftmp.199, align 4 ; [#uses=1] - store float %1195, float* %1194, align 1 - br label %bb270 - -bb270: ; preds = %bb269, %bb262 - %1196 = load %struct.GLDState** %state_addr, align 4 ; <%struct.GLDState*> [#uses=1] - %1197 = getelementptr inbounds %struct.GLDState* %1196, i32 0, i32 23 ; <%struct.GLDMaskMode*> [#uses=1] - %1198 = getelementptr inbounds %struct.GLDMaskMode* %1197, i32 0, i32 5 ; [#uses=1] - %1199 = load i8* %1198, align 1 ; [#uses=1] - %1200 = zext i8 %1199 to i32 ; [#uses=1] - %1201 = load i32* %cur_draw_buffer_mask_bit239, align 4 ; [#uses=1] - %1202 = and i32 %1200, %1201 ; [#uses=1] - %1203 = icmp ne i32 %1202, 0 ; [#uses=1] - br i1 %1203, label %bb271, label %bb278 - -bb271: ; preds = %bb270 - %1204 = load float* %a246, align 4 ; [#uses=1] - %1205 = fcmp uge float %1204, 0.000000e+00 ; [#uses=1] - br i1 %1205, label %bb272, label %bb276 - -bb272: ; preds = %bb271 - %1206 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %1207 = getelementptr inbounds %struct.GLDContextRec* %1206, i32 0, i32 2 ; [#uses=1] - %1208 = load float* %1207, align 4 ; [#uses=1] - %1209 = load float* %a246, align 4 ; [#uses=1] - %1210 = fcmp olt float %1208, %1209 ; [#uses=1] - br i1 %1210, label %bb273, label %bb274 - -bb273: ; preds = %bb272 - %1211 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %1212 = getelementptr inbounds %struct.GLDContextRec* %1211, i32 0, i32 2 ; [#uses=1] - %1213 = load float* %1212, align 4 ; [#uses=1] - store float %1213, float* %iftmp.202, align 4 - br label %bb275 - -bb274: ; preds = %bb272 - %1214 = load float* %a246, align 4 ; [#uses=1] - store float %1214, float* %iftmp.202, align 4 - br label %bb275 - -bb275: ; preds = %bb274, %bb273 - %1215 = load float* %iftmp.202, align 4 ; [#uses=1] - store float %1215, float* %iftmp.201, align 4 - br label %bb277 - -bb276: ; preds = %bb271 - store float 0.000000e+00, float* %iftmp.201, align 4 - br label %bb277 - -bb277: ; preds = %bb276, %bb275 - %1216 = load float** %color_ptr235, align 4 ; [#uses=1] - %1217 = getelementptr inbounds float* %1216, i32 3 ; [#uses=1] - %1218 = load float* %iftmp.201, align 4 ; [#uses=1] - store float %1218, float* %1217, align 1 - br label %bb278 - -bb278: ; preds = %bb277, %bb270 - %1219 = load double** %accum, align 4 ; [#uses=1] - %1220 = getelementptr inbounds double* %1219, i32 4 ; [#uses=1] - store double* %1220, double** %accum, align 4 - %1221 = load float** %color_ptr235, align 4 ; [#uses=1] - %1222 = getelementptr inbounds float* %1221, i32 4 ; [#uses=1] - store float* %1222, float** %color_ptr235, align 4 - br label %bb279 - -bb279: ; preds = %bb278, %bb241 - %1223 = load double** %accum, align 4 ; [#uses=1] - %1224 = load double** %accum_end, align 4 ; [#uses=1] - %1225 = icmp ult double* %1223, %1224 ; [#uses=1] - br i1 %1225, label %bb242, label %bb280 - -bb280: ; preds = %bb279 - br label %bb312 - -bb281: ; preds = %bb240 - br label %bb311 - -bb282: ; preds = %bb311 - %1226 = load double** %accum, align 4 ; [#uses=1] - %1227 = getelementptr inbounds double* %1226, i32 0 ; [#uses=1] - %1228 = load double* %1227, align 1 ; [#uses=1] - %1229 = fptrunc double %1228 to float ; [#uses=1] - %1230 = load float* %value_addr, align 4 ; [#uses=1] - %1231 = fmul float %1229, %1230 ; [#uses=1] - store float %1231, float* %r283, align 4 - %1232 = load double** %accum, align 4 ; [#uses=1] - %1233 = getelementptr inbounds double* %1232, i32 1 ; [#uses=1] - %1234 = load double* %1233, align 1 ; [#uses=1] - %1235 = fptrunc double %1234 to float ; [#uses=1] - %1236 = load float* %value_addr, align 4 ; [#uses=1] - %1237 = fmul float %1235, %1236 ; [#uses=1] - store float %1237, float* %g284, align 4 - %1238 = load double** %accum, align 4 ; [#uses=1] - %1239 = getelementptr inbounds double* %1238, i32 2 ; [#uses=1] - %1240 = load double* %1239, align 1 ; [#uses=1] - %1241 = fptrunc double %1240 to float ; [#uses=1] - %1242 = load float* %value_addr, align 4 ; [#uses=1] - %1243 = fmul float %1241, %1242 ; [#uses=1] - store float %1243, float* %b285, align 4 - %1244 = load double** %accum, align 4 ; [#uses=1] - %1245 = getelementptr inbounds double* %1244, i32 3 ; [#uses=1] - %1246 = load double* %1245, align 1 ; [#uses=1] - %1247 = fptrunc double %1246 to float ; [#uses=1] - %1248 = load float* %value_addr, align 4 ; [#uses=1] - %1249 = fmul float %1247, %1248 ; [#uses=1] - store float %1249, float* %a286, align 4 - %1250 = load float* %r283, align 4 ; [#uses=1] - %1251 = fcmp uge float %1250, 0.000000e+00 ; [#uses=1] - br i1 %1251, label %bb287, label %bb291 - -bb287: ; preds = %bb282 - %1252 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %1253 = getelementptr inbounds %struct.GLDContextRec* %1252, i32 0, i32 2 ; [#uses=1] - %1254 = load float* %1253, align 4 ; [#uses=1] - %1255 = load float* %r283, align 4 ; [#uses=1] - %1256 = fcmp olt float %1254, %1255 ; [#uses=1] - br i1 %1256, label %bb288, label %bb289 - -bb288: ; preds = %bb287 - %1257 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %1258 = getelementptr inbounds %struct.GLDContextRec* %1257, i32 0, i32 2 ; [#uses=1] - %1259 = load float* %1258, align 4 ; [#uses=1] - store float %1259, float* %iftmp.204, align 4 - br label %bb290 - -bb289: ; preds = %bb287 - %1260 = load float* %r283, align 4 ; [#uses=1] - store float %1260, float* %iftmp.204, align 4 - br label %bb290 - -bb290: ; preds = %bb289, %bb288 - %1261 = load float* %iftmp.204, align 4 ; [#uses=1] - store float %1261, float* %iftmp.203, align 4 - br label %bb292 - -bb291: ; preds = %bb282 - store float 0.000000e+00, float* %iftmp.203, align 4 - br label %bb292 - -bb292: ; preds = %bb291, %bb290 - %1262 = load float** %color_ptr235, align 4 ; [#uses=1] - %1263 = getelementptr inbounds float* %1262, i32 0 ; [#uses=1] - %1264 = load float* %iftmp.203, align 4 ; [#uses=1] - store float %1264, float* %1263, align 1 - %1265 = load float* %g284, align 4 ; [#uses=1] - %1266 = fcmp uge float %1265, 0.000000e+00 ; [#uses=1] - br i1 %1266, label %bb293, label %bb297 - -bb293: ; preds = %bb292 - %1267 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %1268 = getelementptr inbounds %struct.GLDContextRec* %1267, i32 0, i32 2 ; [#uses=1] - %1269 = load float* %1268, align 4 ; [#uses=1] - %1270 = load float* %g284, align 4 ; [#uses=1] - %1271 = fcmp olt float %1269, %1270 ; [#uses=1] - br i1 %1271, label %bb294, label %bb295 - -bb294: ; preds = %bb293 - %1272 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %1273 = getelementptr inbounds %struct.GLDContextRec* %1272, i32 0, i32 2 ; [#uses=1] - %1274 = load float* %1273, align 4 ; [#uses=1] - store float %1274, float* %iftmp.206, align 4 - br label %bb296 - -bb295: ; preds = %bb293 - %1275 = load float* %g284, align 4 ; [#uses=1] - store float %1275, float* %iftmp.206, align 4 - br label %bb296 - -bb296: ; preds = %bb295, %bb294 - %1276 = load float* %iftmp.206, align 4 ; [#uses=1] - store float %1276, float* %iftmp.205, align 4 - br label %bb298 - -bb297: ; preds = %bb292 - store float 0.000000e+00, float* %iftmp.205, align 4 - br label %bb298 - -bb298: ; preds = %bb297, %bb296 - %1277 = load float** %color_ptr235, align 4 ; [#uses=1] - %1278 = getelementptr inbounds float* %1277, i32 1 ; [#uses=1] - %1279 = load float* %iftmp.205, align 4 ; [#uses=1] - store float %1279, float* %1278, align 1 - %1280 = load float* %b285, align 4 ; [#uses=1] - %1281 = fcmp uge float %1280, 0.000000e+00 ; [#uses=1] - br i1 %1281, label %bb299, label %bb303 - -bb299: ; preds = %bb298 - %1282 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %1283 = getelementptr inbounds %struct.GLDContextRec* %1282, i32 0, i32 2 ; [#uses=1] - %1284 = load float* %1283, align 4 ; [#uses=1] - %1285 = load float* %b285, align 4 ; [#uses=1] - %1286 = fcmp olt float %1284, %1285 ; [#uses=1] - br i1 %1286, label %bb300, label %bb301 - -bb300: ; preds = %bb299 - %1287 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %1288 = getelementptr inbounds %struct.GLDContextRec* %1287, i32 0, i32 2 ; [#uses=1] - %1289 = load float* %1288, align 4 ; [#uses=1] - store float %1289, float* %iftmp.208, align 4 - br label %bb302 - -bb301: ; preds = %bb299 - %1290 = load float* %b285, align 4 ; [#uses=1] - store float %1290, float* %iftmp.208, align 4 - br label %bb302 - -bb302: ; preds = %bb301, %bb300 - %1291 = load float* %iftmp.208, align 4 ; [#uses=1] - store float %1291, float* %iftmp.207, align 4 - br label %bb304 - -bb303: ; preds = %bb298 - store float 0.000000e+00, float* %iftmp.207, align 4 - br label %bb304 - -bb304: ; preds = %bb303, %bb302 - %1292 = load float** %color_ptr235, align 4 ; [#uses=1] - %1293 = getelementptr inbounds float* %1292, i32 2 ; [#uses=1] - %1294 = load float* %iftmp.207, align 4 ; [#uses=1] - store float %1294, float* %1293, align 1 - %1295 = load float* %a286, align 4 ; [#uses=1] - %1296 = fcmp uge float %1295, 0.000000e+00 ; [#uses=1] - br i1 %1296, label %bb305, label %bb309 - -bb305: ; preds = %bb304 - %1297 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %1298 = getelementptr inbounds %struct.GLDContextRec* %1297, i32 0, i32 2 ; [#uses=1] - %1299 = load float* %1298, align 4 ; [#uses=1] - %1300 = load float* %a286, align 4 ; [#uses=1] - %1301 = fcmp olt float %1299, %1300 ; [#uses=1] - br i1 %1301, label %bb306, label %bb307 - -bb306: ; preds = %bb305 - %1302 = load %struct.GLDContextRec** %ctx_addr, align 4 ; <%struct.GLDContextRec*> [#uses=1] - %1303 = getelementptr inbounds %struct.GLDContextRec* %1302, i32 0, i32 2 ; [#uses=1] - %1304 = load float* %1303, align 4 ; [#uses=1] - store float %1304, float* %iftmp.210, align 4 - br label %bb308 - -bb307: ; preds = %bb305 - %1305 = load float* %a286, align 4 ; [#uses=1] - store float %1305, float* %iftmp.210, align 4 - br label %bb308 - -bb308: ; preds = %bb307, %bb306 - %1306 = load float* %iftmp.210, align 4 ; [#uses=1] - store float %1306, float* %iftmp.209, align 4 - br label %bb310 - -bb309: ; preds = %bb304 - store float 0.000000e+00, float* %iftmp.209, align 4 - br label %bb310 - -bb310: ; preds = %bb309, %bb308 - %1307 = load float** %color_ptr235, align 4 ; [#uses=1] - %1308 = getelementptr inbounds float* %1307, i32 3 ; [#uses=1] - %1309 = load float* %iftmp.209, align 4 ; [#uses=1] - store float %1309, float* %1308, align 1 - %1310 = load double** %accum, align 4 ; [#uses=1] - %1311 = getelementptr inbounds double* %1310, i32 4 ; [#uses=1] - store double* %1311, double** %accum, align 4 - %1312 = load float** %color_ptr235, align 4 ; [#uses=1] - %1313 = getelementptr inbounds float* %1312, i32 4 ; [#uses=1] - store float* %1313, float** %color_ptr235, align 4 - br label %bb311 - -bb311: ; preds = %bb310, %bb281 - %1314 = load double** %accum, align 4 ; [#uses=1] - %1315 = load double** %accum_end, align 4 ; [#uses=1] - %1316 = icmp ult double* %1314, %1315 ; [#uses=1] - br i1 %1316, label %bb282, label %bb312 - -bb312: ; preds = %bb311, %bb280 - %1317 = load i32* %y, align 4 ; [#uses=1] - %1318 = add i32 %1317, 1 ; [#uses=1] - store i32 %1318, i32* %y, align 4 - %1319 = load i32* %offset, align 4 ; [#uses=1] - %1320 = load i32* %y_inc, align 4 ; [#uses=1] - %1321 = add i32 %1319, %1320 ; [#uses=1] - store i32 %1321, i32* %offset, align 4 - br label %bb313 - -bb313: ; preds = %bb312, %bb238 - %1322 = load i32* %y, align 4 ; [#uses=1] - %1323 = load i32* %yl, align 4 ; [#uses=1] - %1324 = icmp ult i32 %1322, %1323 ; [#uses=1] - br i1 %1324, label %bb240, label %bb314 - -bb314: ; preds = %bb313, %bb237 - %1325 = load i32* %draw_buffer, align 4 ; [#uses=1] - %1326 = add nsw i32 %1325, 1 ; [#uses=1] - store i32 %1326, i32* %draw_buffer, align 4 - br label %bb315 - -bb315: ; preds = %bb314, %bb234 - %1327 = load i32* %draw_buffer, align 4 ; [#uses=1] - %1328 = icmp sle i32 %1327, 7 ; [#uses=1] - br i1 %1328, label %bb237, label %bb316 - -bb316: ; preds = %bb315, %bb232, %bb228, %bb6 - br label %return - -return: ; preds = %bb316 - ret void -} From enderby at apple.com Tue May 25 15:52:35 2010 From: enderby at apple.com (Kevin Enderby) Date: Tue, 25 May 2010 20:52:35 -0000 Subject: [llvm-commits] [llvm] r104634 - in /llvm/trunk: lib/Target/X86/AsmParser/X86AsmParser.cpp test/MC/AsmParser/X86/x86_32-new-encoder.s Message-ID: <20100525205235.1F2633128026@llvm.org> Author: enderby Date: Tue May 25 15:52:34 2010 New Revision: 104634 URL: http://llvm.org/viewvc/llvm-project?rev=104634&view=rev Log: Changed the encoding of X86 floating point stack operations where both operands are st(0). These can be encoded using an opcode for storing in st(0) or using an opcode for storing in st(i), where i can also be 0. To allow testing with the darwin assembler and get a matching binary the opcode for storing in st(0) is now used. To do this the same logical trick is use from the darwin assembler in converting things like this: fmul %st(0), %st into this: fmul %st(0) by looking for the second operand being X86::ST0 for specific floating point mnemonics then removing the second X86::ST0 operand. This also has the add benefit to allow things like: fmul %st(1), %st that llvm-mc did not assemble. Modified: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s Modified: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp?rev=104634&r1=104633&r2=104634&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp (original) +++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp Tue May 25 15:52:34 2010 @@ -706,6 +706,17 @@ Operands.erase(Operands.begin() + 1); } + // FIXME: Hack to handle "f{mul*,add*,sub*,div*} $op, st(0)" the same as + // "f{mul*,add*,sub*,div*} $op" + if ((Name.startswith("fmul") || Name.startswith("fadd") || + Name.startswith("fsub") || Name.startswith("fdiv")) && + Operands.size() == 3 && + static_cast(Operands[2])->isReg() && + static_cast(Operands[2])->getReg() == X86::ST0) { + delete Operands[2]; + Operands.erase(Operands.begin() + 2); + } + return false; } Modified: llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s?rev=104634&r1=104633&r2=104634&view=diff ============================================================================== --- llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s (original) +++ llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s Tue May 25 15:52:34 2010 @@ -277,3 +277,28 @@ // CHECK: cmpsd $7, %xmm0, %xmm1 // CHECK: encoding: [0xf2,0x0f,0xc2,0xc8,0x07] cmpordsd %xmm0, %xmm1 + +// rdar://7995856 +// CHECK: fmul %st(0) +// CHECK: encoding: [0xd8,0xc8] + fmul %st(0), %st + +// CHECK: fadd %st(0) +// CHECK: encoding: [0xd8,0xc0] + fadd %st(0), %st + +// CHECK: fsub %st(0) +// CHECK: encoding: [0xd8,0xe0] + fsub %st(0), %st + +// CHECK: fsubr %st(0) +// CHECK: encoding: [0xd8,0xe8] + fsubr %st(0), %st + +// CHECK: fdivr %st(0) +// CHECK: encoding: [0xd8,0xf8] + fdivr %st(0), %st + +// CHECK: fdiv %st(0) +// CHECK: encoding: [0xd8,0xf0] + fdiv %st(0), %st From gkistanova at gmail.com Tue May 25 16:14:20 2010 From: gkistanova at gmail.com (Galina Kistanova) Date: Tue, 25 May 2010 14:14:20 -0700 Subject: [llvm-commits] [PATCH] Fix for DragonEgg build launcher scripts and switch to ScriptedBuilder In-Reply-To: <4BFBB6FE.8070503@free.fr> References: <4BFBB6FE.8070503@free.fr> Message-ID: Hello Duncan, > I don't understand what you mean by an infinite loop of links. > What might happen is that the link gets placed inside the > pre-existing directory. Right. And this is the exact problem. Here is what happens on Linux centos 2.6.18 if the script gets run twice without removing the links in between runs. Let's assume we have an empty "source code" directory. $ ls -l drwxr-xr-x 2 buildslave staff 4096 May 22 16:51 dragonegg.src First time you create a symbolic link, it works like this: $ ln -sf dragonegg.src ./dragonegg $ ls -l lrwxrwxrwx 1 buildslave staff 13 May 22 16:58 dragonegg -> dragonegg.src drwxr-xr-x 2 buildslave staff 4096 May 22 16:51 dragonegg.src $ ls -l ./dragonegg.src $ Which looks right. But the next time the same link commands get run, things go wrong: $ ln -sf dragonegg.src ./dragonegg $ ls -l lrwxrwxrwx 1 buildslave staff 13 May 22 16:58 dragonegg -> dragonegg.src drwxr-xr-x 2 buildslave staff 4096 May 22 17:04 dragonegg.src $ ls -l ./dragonegg.src lrwxrwxrwx 1 buildslave staff 13 May 22 17:04 dragonegg.src -> dragonegg.src As you can see, there is a symbolic link gets placed inside the pre-existing directory which reference itself or a parent directory. Because the build involves recurrent iteration through nested directories, it will eventually get an error by de-referencing dragonegg.src/dragonegg.src/dragonegg.src symbolic link. Am I missing something? > Moving the "cd" up seems pointless. This is not too important, really. It just explicitly specifies that all relative paths we may get as a parameter will be relative to the build directory and not the directory the script was run from. This small change makes things easier on the buildbot side. I'll skip it if you have a strong preference of having it that way. > exists -> exist Thanks for catching this! > Also, the comment is wrong, since if the target link exists you do > still create a new link. Not really. Except for -h and -L, all FILE-related tests de-reference symbolic links. Like this: $ ls -l lrwxrwxrwx 1 13 May 22 16:58 dragonegg -> dragonegg.src drwxr-xr-x 2 4096 May 22 17:04 dragonegg.src $ if [ ! -d ./dragonegg.src ] ; then echo 'Create link' ; fi $ if [ ! -d ./dragonegg ] ; then echo 'Create link' ; fi $ if [ ! -d ./dragonegg.new ] ; then echo 'Create link' ; fi Create link So, since the symbolic links actually get de-referenced by -d test, everything should work well. Am I missing something here? > If the source already exists as a directory, presumably something funny > is going on. ... > In fact wouldn't it be better to bail out if the target exists > and is not a symbol link? I have thought of it. But ended up with the idea that since the symbolic link is just a way to enforce some source code directory naming and place convention, we shouldn't punish a user if he/she has provided it already in the right place. We have to check this case anyway, and it is equally simple to handle it correctly or bail out with an error, so my choice was to handle. But I can easily make it to bail out, if you have a strong preference for that. What do you think? Thanks Galina On Tue, May 25, 2010 at 4:39 AM, Duncan Sands wrote: > Hi Galina, > >> patch07.diff fixes a possible infinite loop linked with ln commands, >> and changes directory before the ln command so it could dial well with >> the relative to the build root pathes. >> >> Both buildbot_self_strap and buildbot_self_strap-32 scripts could make >> infinite loop of links on Linux if the build directories remain >> between builds. This could happen because the second time "form 3 of >> ln command" will be used. > > thanks for working on this. ?I don't understand what you mean by an infinite > loop of links. ?What might happen is that the link gets placed inside the > pre-existing directory. > >> -ln -sf $LLVM_SOURCE $BUILD_DIR/llvm >> -ln -sf $DRAGONEGG_SOURCE $BUILD_DIR/dragonegg >> +# Change the current directory to the build root. >> +cd $BUILD_DIR > > Moving the "cd" up seems pointless. > >> +# Create links only if target directory or link does not exists. > > exists -> exist > Also, the comment is wrong, since if the target link exists you do > still create a new link. > >> +if [ ! -d $BUILD_DIR/llvm ] ; then >> + ? ln -sf $LLVM_SOURCE $BUILD_DIR/llvm >> +fi >> +if [ ! -d $BUILD_DIR/dragonegg ] ; then >> + ? ln -sf $DRAGONEGG_SOURCE $BUILD_DIR/dragonegg >> +fi > > If the source already exists as a directory, presumably something funny > is going on. ?Wouldn't it be better to bail out with an error in this > case? ?In fact wouldn't it be better to bail out if the target exists > and is not a symbol link? > > Ciao, > > Duncan. > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From echristo at apple.com Tue May 25 16:28:51 2010 From: echristo at apple.com (Eric Christopher) Date: Tue, 25 May 2010 21:28:51 -0000 Subject: [llvm-commits] [llvm] r104635 - in /llvm/trunk: lib/CodeGen/AsmPrinter/AsmPrinter.cpp lib/CodeGen/TargetLoweringObjectFileImpl.cpp test/MC/MachO/tls.s Message-ID: <20100525212851.3658D3128034@llvm.org> Author: echristo Date: Tue May 25 16:28:50 2010 New Revision: 104635 URL: http://llvm.org/viewvc/llvm-project?rev=104635&view=rev Log: Add support for initialized global data for darwin tls. Update comments and testcases accordingly. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp llvm/trunk/test/MC/MachO/tls.s Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=104635&r1=104634&r2=104635&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Tue May 25 16:28:50 2010 @@ -311,13 +311,26 @@ return; } - // Handle the tbss directive on darwin which is a thread local bss directive - // like zerofill. - if (GVKind.isThreadBSS() && MAI->hasMachoTBSSDirective()) { + // Handle thread local data for mach-o which requires us to output an + // additional structure of data and mangle the original symbol so that we + // can reference it later. + if (GVKind.isThreadLocal() && MAI->hasMachoTBSSDirective()) { // Emit the .tbss symbol MCSymbol *MangSym = OutContext.GetOrCreateSymbol(GVSym->getName() + Twine("$tlv$init")); - OutStreamer.EmitTBSSSymbol(TheSection, MangSym, Size, 1 << AlignLog); + + if (GVKind.isThreadBSS()) + OutStreamer.EmitTBSSSymbol(TheSection, MangSym, Size, 1 << AlignLog); + else if (GVKind.isThreadData()) { + OutStreamer.SwitchSection(TheSection); + + EmitLinkage(GV->getLinkage(), MangSym); + EmitAlignment(AlignLog, GV); + OutStreamer.EmitLabel(MangSym); + + EmitGlobalConstant(GV->getInitializer()); + } + OutStreamer.AddBlankLine(); // Emit the variable struct for the runtime. Modified: llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp?rev=104635&r1=104634&r2=104635&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp (original) +++ llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp Tue May 25 16:28:50 2010 @@ -670,11 +670,10 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, Mangler *Mang, const TargetMachine &TM) const { - // Handle one kind of thread local... + // Handle thread local data. if (Kind.isThreadBSS()) return TLSBSSSection; + if (Kind.isThreadData()) return TLSDataSection; - assert(!Kind.isThreadLocal() && "Darwin doesn't support TLS"); - if (Kind.isText()) return GV->isWeakForLinker() ? TextCoalSection : TextSection; Modified: llvm/trunk/test/MC/MachO/tls.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MachO/tls.s?rev=104635&r1=104634&r2=104635&view=diff ============================================================================== --- llvm/trunk/test/MC/MachO/tls.s (original) +++ llvm/trunk/test/MC/MachO/tls.s Tue May 25 16:28:50 2010 @@ -1,40 +1,56 @@ // RUN: llvm-mc -triple x86_64-apple-darwin %s -filetype=obj -o - | macho-dump --dump-section-data | FileCheck %s -.tbss _a$tlv$init, 4 + .section __TEXT,__text,regular,pure_instructions + .section __DATA,__thread_data,thread_local_regular + .globl _c$tlv$init + .align 2 +_c$tlv$init: + .long 4 + + .section __DATA,__thread_vars,thread_local_variables + .globl _c +_c: + .quad ___tlv_bootstrap + .quad 0 + .quad _c$tlv$init + + .section __DATA,__thread_data,thread_local_regular + .globl _d$tlv$init + .align 2 +_d$tlv$init: + .long 5 + + .section __DATA,__thread_vars,thread_local_variables + .globl _d +_d: + .quad ___tlv_bootstrap + .quad 0 + .quad _d$tlv$init -.tlv - .globl _a +.tbss _a$tlv$init, 4, 2 + + .globl _a _a: - .quad _tlv_bootstrap - .quad 0 - .quad _a$tlv$init + .quad ___tlv_bootstrap + .quad 0 + .quad _a$tlv$init -.tbss _b$tlv$init, 8, 4 +.tbss _b$tlv$init, 4, 2 -.tlv - .globl _b + .globl _b _b: - .quad _tlv_bootstrap - .quad 0 - .quad _b$tlv$init - -.tdata -_c$tlv$init: - .quad 8 + .quad ___tlv_bootstrap + .quad 0 + .quad _b$tlv$init -.tlv - .globl _c -_c: - .quad _tlv_bootstrap - .quad 0 - .quad _c$tlv$init +.subsections_via_symbols // CHECK: ('cputype', 16777223) // CHECK: ('cpusubtype', 3) // CHECK: ('filetype', 1) // CHECK: ('num_load_commands', 1) // CHECK: ('load_commands_size', 496) -// CHECK: ('flag', 0) +// CHECK: ('flag', 8192) // CHECK: ('reserved', 0) // CHECK: ('load_commands', [ // CHECK: # Load Command 0 @@ -42,9 +58,9 @@ // CHECK: ('size', 392) // CHECK: ('segment_name', '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') // CHECK: ('vm_addr', 0) -// CHECK: ('vm_size', 104) +// CHECK: ('vm_size', 112) // CHECK: ('file_offset', 528) -// CHECK: ('file_size', 80) +// CHECK: ('file_size', 104) // CHECK: ('maxprot', 7) // CHECK: ('initprot', 7) // CHECK: ('num_sections', 4) @@ -68,31 +84,31 @@ // CHECK: ]) // CHECK: ('_section_data', '') // CHECK: # Section 1 -// CHECK: (('section_name', '__thread_bss\x00\x00\x00\x00') +// CHECK: (('section_name', '__thread_data\x00\x00\x00') // CHECK: ('segment_name', '__DATA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') -// CHECK: ('address', 80) -// CHECK: ('size', 24) -// CHECK: ('offset', 0) -// CHECK: ('alignment', 4) +// CHECK: ('address', 0) +// CHECK: ('size', 8) +// CHECK: ('offset', 528) +// CHECK: ('alignment', 2) // CHECK: ('reloc_offset', 0) // CHECK: ('num_reloc', 0) -// CHECK: ('flags', 0x12) +// CHECK: ('flags', 0x11) // CHECK: ('reserved1', 0) // CHECK: ('reserved2', 0) // CHECK: ('reserved3', 0) // CHECK: ), // CHECK: ('_relocations', [ // CHECK: ]) -// CHECK: ('_section_data', '\xcf\xfa\xed\xfe\x07\x00\x00\x01\x03\x00\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00\xf0\x01\x00\x00') +// CHECK: ('_section_data', '\x04\x00\x00\x00\x05\x00\x00\x00') // CHECK: # Section 2 // CHECK: (('section_name', '__thread_vars\x00\x00\x00') // CHECK: ('segment_name', '__DATA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') -// CHECK: ('address', 0) -// CHECK: ('size', 72) -// CHECK: ('offset', 528) +// CHECK: ('address', 8) +// CHECK: ('size', 96) +// CHECK: ('offset', 536) // CHECK: ('alignment', 0) -// CHECK: ('reloc_offset', 608) -// CHECK: ('num_reloc', 6) +// CHECK: ('reloc_offset', 632) +// CHECK: ('num_reloc', 8) // CHECK: ('flags', 0x13) // CHECK: ('reserved1', 0) // CHECK: ('reserved2', 0) @@ -100,108 +116,130 @@ // CHECK: ), // CHECK: ('_relocations', [ // CHECK: # Relocation 0 -// CHECK: (('word-0', 0x40), -// CHECK: ('word-1', 0xe000002)), +// CHECK: (('word-0', 0x58), +// CHECK: ('word-1', 0xe000001)), // CHECK: # Relocation 1 -// CHECK: (('word-0', 0x30), -// CHECK: ('word-1', 0xe000006)), +// CHECK: (('word-0', 0x48), +// CHECK: ('word-1', 0xe000008)), // CHECK: # Relocation 2 -// CHECK: (('word-0', 0x28), -// CHECK: ('word-1', 0xe000001)), +// CHECK: (('word-0', 0x40), +// CHECK: ('word-1', 0xe000000)), // CHECK: # Relocation 3 -// CHECK: (('word-0', 0x18), -// CHECK: ('word-1', 0xe000006)), +// CHECK: (('word-0', 0x30), +// CHECK: ('word-1', 0xe000008)), // CHECK: # Relocation 4 -// CHECK: (('word-0', 0x10), -// CHECK: ('word-1', 0xe000000)), +// CHECK: (('word-0', 0x28), +// CHECK: ('word-1', 0xe000007)), // CHECK: # Relocation 5 +// CHECK: (('word-0', 0x18), +// CHECK: ('word-1', 0xe000008)), +// CHECK: # Relocation 6 +// CHECK: (('word-0', 0x10), +// CHECK: ('word-1', 0xe000005)), +// CHECK: # Relocation 7 // CHECK: (('word-0', 0x0), -// CHECK: ('word-1', 0xe000006)), +// CHECK: ('word-1', 0xe000008)), // CHECK: ]) -// CHECK: ('_section_data', '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +// CHECK: ('_section_data', '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') // CHECK: # Section 3 -// CHECK: (('section_name', '__thread_data\x00\x00\x00') +// CHECK: (('section_name', '__thread_bss\x00\x00\x00\x00') // CHECK: ('segment_name', '__DATA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') -// CHECK: ('address', 72) +// CHECK: ('address', 104) // CHECK: ('size', 8) -// CHECK: ('offset', 600) -// CHECK: ('alignment', 0) +// CHECK: ('offset', 0) +// CHECK: ('alignment', 2) // CHECK: ('reloc_offset', 0) // CHECK: ('num_reloc', 0) -// CHECK: ('flags', 0x11) +// CHECK: ('flags', 0x12) // CHECK: ('reserved1', 0) // CHECK: ('reserved2', 0) // CHECK: ('reserved3', 0) // CHECK: ), // CHECK: ('_relocations', [ // CHECK: ]) -// CHECK: ('_section_data', '\x08\x00\x00\x00\x00\x00\x00\x00') +// CHECK: ('_section_data', '\xcf\xfa\xed\xfe\x07\x00\x00\x01') // CHECK: ]) // CHECK: ), // CHECK: # Load Command 1 // CHECK: (('command', 2) // CHECK: ('size', 24) -// CHECK: ('symoff', 656) -// CHECK: ('nsyms', 7) -// CHECK: ('stroff', 768) -// CHECK: ('strsize', 64) -// CHECK: ('_string_data', '\x00_a\x00_tlv_bootstrap\x00_b\x00_c\x00_a$tlv$init\x00_b$tlv$init\x00_c$tlv$init\x00\x00\x00\x00') +// CHECK: ('symoff', 696) +// CHECK: ('nsyms', 9) +// CHECK: ('stroff', 840) +// CHECK: ('strsize', 80) +// CHECK: ('_string_data', '\x00_c$tlv$init\x00_c\x00___tlv_bootstrap\x00_d$tlv$init\x00_d\x00_a\x00_b\x00_a$tlv$init\x00_b$tlv$init\x00\x00\x00') // CHECK: ('_symbols', [ // CHECK: # Symbol 0 -// CHECK: (('n_strx', 25) +// CHECK: (('n_strx', 54) // CHECK: ('n_type', 0xe) -// CHECK: ('n_sect', 2) +// CHECK: ('n_sect', 4) // CHECK: ('n_desc', 0) -// CHECK: ('n_value', 80) +// CHECK: ('n_value', 104) // CHECK: ('_string', '_a$tlv$init') // CHECK: ), // CHECK: # Symbol 1 -// CHECK: (('n_strx', 37) +// CHECK: (('n_strx', 66) // CHECK: ('n_type', 0xe) -// CHECK: ('n_sect', 2) +// CHECK: ('n_sect', 4) // CHECK: ('n_desc', 0) -// CHECK: ('n_value', 96) +// CHECK: ('n_value', 108) // CHECK: ('_string', '_b$tlv$init') // CHECK: ), // CHECK: # Symbol 2 -// CHECK: (('n_strx', 49) -// CHECK: ('n_type', 0xe) -// CHECK: ('n_sect', 4) +// CHECK: (('n_strx', 48) +// CHECK: ('n_type', 0xf) +// CHECK: ('n_sect', 3) // CHECK: ('n_desc', 0) -// CHECK: ('n_value', 72) -// CHECK: ('_string', '_c$tlv$init') +// CHECK: ('n_value', 56) +// CHECK: ('_string', '_a') // CHECK: ), // CHECK: # Symbol 3 -// CHECK: (('n_strx', 1) +// CHECK: (('n_strx', 51) // CHECK: ('n_type', 0xf) // CHECK: ('n_sect', 3) // CHECK: ('n_desc', 0) -// CHECK: ('n_value', 0) -// CHECK: ('_string', '_a') +// CHECK: ('n_value', 80) +// CHECK: ('_string', '_b') // CHECK: ), // CHECK: # Symbol 4 -// CHECK: (('n_strx', 19) +// CHECK: (('n_strx', 13) // CHECK: ('n_type', 0xf) // CHECK: ('n_sect', 3) // CHECK: ('n_desc', 0) -// CHECK: ('n_value', 24) -// CHECK: ('_string', '_b') +// CHECK: ('n_value', 8) +// CHECK: ('_string', '_c') // CHECK: ), // CHECK: # Symbol 5 -// CHECK: (('n_strx', 22) +// CHECK: (('n_strx', 1) // CHECK: ('n_type', 0xf) -// CHECK: ('n_sect', 3) +// CHECK: ('n_sect', 2) // CHECK: ('n_desc', 0) -// CHECK: ('n_value', 48) -// CHECK: ('_string', '_c') +// CHECK: ('n_value', 0) +// CHECK: ('_string', '_c$tlv$init') // CHECK: ), // CHECK: # Symbol 6 -// CHECK: (('n_strx', 4) +// CHECK: (('n_strx', 45) +// CHECK: ('n_type', 0xf) +// CHECK: ('n_sect', 3) +// CHECK: ('n_desc', 0) +// CHECK: ('n_value', 32) +// CHECK: ('_string', '_d') +// CHECK: ), +// CHECK: # Symbol 7 +// CHECK: (('n_strx', 33) +// CHECK: ('n_type', 0xf) +// CHECK: ('n_sect', 2) +// CHECK: ('n_desc', 0) +// CHECK: ('n_value', 4) +// CHECK: ('_string', '_d$tlv$init') +// CHECK: ), +// CHECK: # Symbol 8 +// CHECK: (('n_strx', 16) // CHECK: ('n_type', 0x1) // CHECK: ('n_sect', 0) // CHECK: ('n_desc', 0) // CHECK: ('n_value', 0) -// CHECK: ('_string', '_tlv_bootstrap') +// CHECK: ('_string', '___tlv_bootstrap') // CHECK: ), // CHECK: ]) // CHECK: ), @@ -209,10 +247,10 @@ // CHECK: (('command', 11) // CHECK: ('size', 80) // CHECK: ('ilocalsym', 0) -// CHECK: ('nlocalsym', 3) -// CHECK: ('iextdefsym', 3) -// CHECK: ('nextdefsym', 3) -// CHECK: ('iundefsym', 6) +// CHECK: ('nlocalsym', 2) +// CHECK: ('iextdefsym', 2) +// CHECK: ('nextdefsym', 6) +// CHECK: ('iundefsym', 8) // CHECK: ('nundefsym', 1) // CHECK: ('tocoff', 0) // CHECK: ('ntoc', 0) From isanbard at gmail.com Tue May 25 16:44:27 2010 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 25 May 2010 21:44:27 -0000 Subject: [llvm-commits] [llvm] r104640 - /llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Message-ID: <20100525214427.0BB0A3128034@llvm.org> Author: void Date: Tue May 25 16:44:26 2010 New Revision: 104640 URL: http://llvm.org/viewvc/llvm-project?rev=104640&view=rev Log: Okay, bear with me here... If you have a setjmp/longjmp situation, it's possible for stack slot coloring to reuse a stack slot before it's really dead. For instance, if we have something like this: 1: y = g; x = sigsetjmp(env, 0); switch (x) { case 1: /* ... */ goto run; case 0: run: do_run(); /* marked as "no return" */ break; case 3: if (...) { /* ... */ goto run; } /* ... */ break; } 2: g = y; "y" may be put onto the stack, so the expression "g = y" is relying upon the fact that the stack slot containing "y" isn't modified between (1) and (2). But it can be, because of the "no return" calls in there. A longjmp might come back with 3, modify the stack slot, and then go to case 0. And it's perfectly acceptable to reuse the stack slot there because there's no CFG flow from case 3 to (2). The fix is to disable certain optimizations in these situations. Ideally, we'd disable them for all "returns twice" functions. But we don't support that attribute. Check for "setjmp" and "sigsetjmp" instead. Modified: llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Modified: llvm/trunk/lib/CodeGen/StackSlotColoring.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackSlotColoring.cpp?rev=104640&r1=104639&r2=104640&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StackSlotColoring.cpp (original) +++ llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Tue May 25 16:44:26 2010 @@ -13,6 +13,8 @@ #define DEBUG_TYPE "stackcoloring" #include "VirtRegMap.h" +#include "llvm/Function.h" +#include "llvm/Module.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" #include "llvm/CodeGen/LiveStackAnalysis.h" @@ -116,6 +118,7 @@ private: void InitializeSlots(); + bool CheckForSetJmpCall(const MachineFunction &MF); void ScanForSpillSlotRefs(MachineFunction &MF); bool OverlapWithAssignments(LiveInterval *li, int Color) const; int ColorSlot(LiveInterval *li); @@ -159,6 +162,34 @@ }; } +/// CheckForSetJmpCall - Return true if there's a call to setjmp/sigsetjmp in +/// this function. +bool StackSlotColoring::CheckForSetJmpCall(const MachineFunction &MF) { + const Function *F = MF.getFunction(); + const Module *M = F->getParent(); + const Function *SetJmp = M->getFunction("setjmp"); + const Function *SigSetJmp = M->getFunction("sigsetjmp"); + + if (!SetJmp && !SigSetJmp) + return false; + + if (SetJmp && !SetJmp->use_empty()) + for (Value::const_use_iterator + I = SetJmp->use_begin(), E = SetJmp->use_end(); I != E; ++I) + if (const CallInst *CI = dyn_cast(I)) + if (CI->getParent()->getParent() == F) + return true; + + if (SigSetJmp && !SigSetJmp->use_empty()) + for (Value::const_use_iterator + I = SigSetJmp->use_begin(), E = SigSetJmp->use_end(); I != E; ++I) + if (const CallInst *CI = dyn_cast(I)) + if (CI->getParent()->getParent() == F) + return true; + + return false; +} + /// ScanForSpillSlotRefs - Scan all the machine instructions for spill slot /// references and update spill slot weights. void StackSlotColoring::ScanForSpillSlotRefs(MachineFunction &MF) { @@ -722,6 +753,16 @@ return false; } + // If there are calls to setjmp or sigsetjmp, don't perform stack slot + // coloring. The stack could be modified before the longjmp is executed, + // resulting in the wrong value being used afterwards. (See + // .) + // + // FIXME: This goes beyond the setjmp/sigsetjmp functions. Ideally, we should + // check for the GCC "returns twice" attribute. + if (CheckForSetJmpCall(MF)) + return false; + // Gather spill slot references ScanForSpillSlotRefs(MF); InitializeSlots(); From wendling at apple.com Tue May 25 16:47:02 2010 From: wendling at apple.com (Bill Wendling) Date: Tue, 25 May 2010 14:47:02 -0700 Subject: [llvm-commits] [llvm] r104624 - in /llvm/trunk: lib/CodeGen/SelectionDAG/DAGCombiner.cpp test/CodeGen/X86/2010-05-25-FP_TO_INT-crash.ll In-Reply-To: References: <20100525184723.847DE312800A@llvm.org> Message-ID: <815CCDA3-240D-4812-B2A9-C834D8A4CA1F@apple.com> Would we be able to put the original .c code into the nightly tester? -bw On May 25, 2010, at 1:28 PM, Chris Lattner wrote: > > On May 25, 2010, at 11:47 AM, Dale Johannesen wrote: > >> Author: johannes >> Date: Tue May 25 13:47:23 2010 >> New Revision: 104624 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=104624&view=rev >> Log: >> Fix another variant of PR 7191. Also add a testcase >> Mon Ping provided; unfortunately bugpoint failed to >> reduce it, but I think it's important to have a test for >> this in the suite. 8023512. > > I agree that a testcase is useful, but that is too big. If you can't reduce it, please remove it. > > -Chris > >> >> >> Added: >> llvm/trunk/test/CodeGen/X86/2010-05-25-FP_TO_INT-crash.ll >> Modified: >> llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp >> >> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=104624&r1=104623&r2=104624&view=diff >> ============================================================================== >> --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) >> +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue May 25 13:47:23 2010 >> @@ -3832,8 +3832,12 @@ >> if (N0.getOpcode() == ISD::TRUNCATE) { >> SDValue NarrowLoad = ReduceLoadWidth(N0.getNode()); >> if (NarrowLoad.getNode()) { >> - if (NarrowLoad.getNode() != N0.getNode()) >> + SDNode* oye = N0.getNode()->getOperand(0).getNode(); >> + if (NarrowLoad.getNode() != N0.getNode()) { >> CombineTo(N0.getNode(), NarrowLoad); >> + // CombineTo deleted the truncate, if needed, but not what's under it. >> + AddToWorkList(oye); >> + } >> return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), VT, NarrowLoad); >> } >> } >> >> Added: llvm/trunk/test/CodeGen/X86/2010-05-25-FP_TO_INT-crash.ll >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2010-05-25-FP_TO_INT-crash.ll?rev=104624&view=auto > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From dalej at apple.com Tue May 25 16:49:15 2010 From: dalej at apple.com (Dale Johannesen) Date: Tue, 25 May 2010 14:49:15 -0700 Subject: [llvm-commits] [llvm] r104624 - in /llvm/trunk: lib/CodeGen/SelectionDAG/DAGCombiner.cpp test/CodeGen/X86/2010-05-25-FP_TO_INT-crash.ll In-Reply-To: <815CCDA3-240D-4812-B2A9-C834D8A4CA1F@apple.com> References: <20100525184723.847DE312800A@llvm.org> <815CCDA3-240D-4812-B2A9-C834D8A4CA1F@apple.com> Message-ID: <0DAA0F0B-BD2E-4CB6-BC95-AEF5FF062BED@apple.com> Maybe. I don't currently have it. The failure in PR 7191 only happens with clang AFAICT. On May 25, 2010, at 2:47 PMPDT, Bill Wendling wrote: > Would we be able to put the original .c code into the nightly tester? > > -bw > > On May 25, 2010, at 1:28 PM, Chris Lattner wrote: > >> >> On May 25, 2010, at 11:47 AM, Dale Johannesen wrote: >> >>> Author: johannes >>> Date: Tue May 25 13:47:23 2010 >>> New Revision: 104624 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=104624&view=rev >>> Log: >>> Fix another variant of PR 7191. Also add a testcase >>> Mon Ping provided; unfortunately bugpoint failed to >>> reduce it, but I think it's important to have a test for >>> this in the suite. 8023512. >> >> I agree that a testcase is useful, but that is too big. If you >> can't reduce it, please remove it. >> >> -Chris >> >>> >>> >>> Added: >>> llvm/trunk/test/CodeGen/X86/2010-05-25-FP_TO_INT-crash.ll >>> Modified: >>> llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp >>> >>> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=104624&r1=104623&r2=104624&view=diff >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> = >>> ==================================================================== >>> --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) >>> +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue May 25 >>> 13:47:23 2010 >>> @@ -3832,8 +3832,12 @@ >>> if (N0.getOpcode() == ISD::TRUNCATE) { >>> SDValue NarrowLoad = ReduceLoadWidth(N0.getNode()); >>> if (NarrowLoad.getNode()) { >>> - if (NarrowLoad.getNode() != N0.getNode()) >>> + SDNode* oye = N0.getNode()->getOperand(0).getNode(); >>> + if (NarrowLoad.getNode() != N0.getNode()) { >>> CombineTo(N0.getNode(), NarrowLoad); >>> + // CombineTo deleted the truncate, if needed, but not >>> what's under it. >>> + AddToWorkList(oye); >>> + } >>> return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), VT, >>> NarrowLoad); >>> } >>> } >>> >>> Added: llvm/trunk/test/CodeGen/X86/2010-05-25-FP_TO_INT-crash.ll >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2010-05-25-FP_TO_INT-crash.ll?rev=104624&view=auto >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From echristo at apple.com Tue May 25 16:49:43 2010 From: echristo at apple.com (Eric Christopher) Date: Tue, 25 May 2010 21:49:43 -0000 Subject: [llvm-commits] [llvm] r104642 - /llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Message-ID: <20100525214943.3D5143128034@llvm.org> Author: echristo Date: Tue May 25 16:49:43 2010 New Revision: 104642 URL: http://llvm.org/viewvc/llvm-project?rev=104642&view=rev Log: Move the verbose asm output up a bit so it can be used in the special cases as well. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=104642&r1=104641&r2=104642&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Tue May 25 16:49:43 2010 @@ -241,6 +241,12 @@ if (EmitSpecialLLVMGlobal(GV)) return; + if (isVerbose()) { + WriteAsOperand(OutStreamer.GetCommentOS(), GV, + /*PrintType=*/false, GV->getParent()); + OutStreamer.GetCommentOS() << '\n'; + } + MCSymbol *GVSym = Mang->getSymbol(GV); EmitVisibility(GVSym, GV->getVisibility()); @@ -361,11 +367,6 @@ EmitLinkage(GV->getLinkage(), GVSym); EmitAlignment(AlignLog, GV); - if (isVerbose()) { - WriteAsOperand(OutStreamer.GetCommentOS(), GV, - /*PrintType=*/false, GV->getParent()); - OutStreamer.GetCommentOS() << '\n'; - } OutStreamer.EmitLabel(GVSym); EmitGlobalConstant(GV->getInitializer()); From gohman at apple.com Tue May 25 16:50:35 2010 From: gohman at apple.com (Dan Gohman) Date: Tue, 25 May 2010 21:50:35 -0000 Subject: [llvm-commits] [llvm] r104644 - /llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Message-ID: <20100525215035.4B1593128034@llvm.org> Author: djg Date: Tue May 25 16:50:35 2010 New Revision: 104644 URL: http://llvm.org/viewvc/llvm-project?rev=104644&view=rev Log: Fix a missing newline in debug output. Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp?rev=104644&r1=104643&r2=104644&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Tue May 25 16:50:35 2010 @@ -442,7 +442,7 @@ // If this cast is a truncate, evaluting in a different type always // eliminates the cast, so it is always a win. DEBUG(dbgs() << "ICE: EvaluateInDifferentType converting expression type" - " to avoid cast: " << CI); + " to avoid cast: " << CI << '\n'); Value *Res = EvaluateInDifferentType(Src, DestTy, false); assert(Res->getType() == DestTy); return ReplaceInstUsesWith(CI, Res); From dalej at apple.com Tue May 25 16:56:14 2010 From: dalej at apple.com (Dale Johannesen) Date: Tue, 25 May 2010 14:56:14 -0700 Subject: [llvm-commits] [llvm] r104640 - /llvm/trunk/lib/CodeGen/StackSlotColoring.cpp In-Reply-To: <20100525214427.0BB0A3128034@llvm.org> References: <20100525214427.0BB0A3128034@llvm.org> Message-ID: On May 25, 2010, at 2:44 PMPDT, Bill Wendling wrote: > > +/// CheckForSetJmpCall - Return true if there's a call to setjmp/ > sigsetjmp in > +/// this function. > +bool StackSlotColoring::CheckForSetJmpCall(const MachineFunction > &MF) { > + const Function *F = MF.getFunction(); Should we figure this out once and set a bit in the function? There are other optimization phases that need to know this. From gohman at apple.com Tue May 25 16:59:42 2010 From: gohman at apple.com (Dan Gohman) Date: Tue, 25 May 2010 21:59:42 -0000 Subject: [llvm-commits] [llvm] r104645 - /llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Message-ID: <20100525215942.45B693128034@llvm.org> Author: djg Date: Tue May 25 16:59:42 2010 New Revision: 104645 URL: http://llvm.org/viewvc/llvm-project?rev=104645&view=rev Log: Do one map lookup instead of two. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=104645&r1=104644&r2=104645&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Tue May 25 16:59:42 2010 @@ -99,8 +99,9 @@ // cache values defined by Instructions across blocks, and other values // only locally. This is because Instructions already have the SSA // def-dominates-use requirement enforced. - if (ValueMap.count(V)) - return ValueMap[V]; + DenseMap::iterator I = ValueMap.find(V); + if (I != ValueMap.end()) + return I->second; unsigned Reg = LocalValueMap[V]; if (Reg != 0) return Reg; From isanbard at gmail.com Tue May 25 17:02:17 2010 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 25 May 2010 15:02:17 -0700 Subject: [llvm-commits] [llvm] r104640 - /llvm/trunk/lib/CodeGen/StackSlotColoring.cpp In-Reply-To: References: <20100525214427.0BB0A3128034@llvm.org> Message-ID: On May 25, 2010, at 2:56 PM, Dale Johannesen wrote: > On May 25, 2010, at 2:44 PMPDT, Bill Wendling wrote: >> >> +/// CheckForSetJmpCall - Return true if there's a call to setjmp/ >> sigsetjmp in >> +/// this function. >> +bool StackSlotColoring::CheckForSetJmpCall(const MachineFunction >> &MF) { >> + const Function *F = MF.getFunction(); > > Should we figure this out once and set a bit in the function? There > are other optimization phases that need to know this. > Maybe...though it could get messy to keep it up-to-date if a setjmp/sigsetjmp function is removed or added. -bw From isanbard at gmail.com Tue May 25 17:02:22 2010 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 25 May 2010 22:02:22 -0000 Subject: [llvm-commits] [llvm] r104646 - /llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Message-ID: <20100525220222.E12DB3128034@llvm.org> Author: void Date: Tue May 25 17:02:22 2010 New Revision: 104646 URL: http://llvm.org/viewvc/llvm-project?rev=104646&view=rev Log: Constify function. Modified: llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Modified: llvm/trunk/lib/CodeGen/StackSlotColoring.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackSlotColoring.cpp?rev=104646&r1=104645&r2=104646&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StackSlotColoring.cpp (original) +++ llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Tue May 25 17:02:22 2010 @@ -118,7 +118,7 @@ private: void InitializeSlots(); - bool CheckForSetJmpCall(const MachineFunction &MF); + bool CheckForSetJmpCall(const MachineFunction &MF) const; void ScanForSpillSlotRefs(MachineFunction &MF); bool OverlapWithAssignments(LiveInterval *li, int Color) const; int ColorSlot(LiveInterval *li); @@ -164,7 +164,7 @@ /// CheckForSetJmpCall - Return true if there's a call to setjmp/sigsetjmp in /// this function. -bool StackSlotColoring::CheckForSetJmpCall(const MachineFunction &MF) { +bool StackSlotColoring::CheckForSetJmpCall(const MachineFunction &MF) const { const Function *F = MF.getFunction(); const Module *M = F->getParent(); const Function *SetJmp = M->getFunction("setjmp"); From benny.kra at googlemail.com Tue May 25 17:53:43 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Tue, 25 May 2010 22:53:43 -0000 Subject: [llvm-commits] [llvm] r104648 - in /llvm/trunk: lib/Transforms/Scalar/SimplifyLibCalls.cpp test/Transforms/SimplifyLibCalls/memcmp.ll Message-ID: <20100525225343.9B79D3128034@llvm.org> Author: d0k Date: Tue May 25 17:53:43 2010 New Revision: 104648 URL: http://llvm.org/viewvc/llvm-project?rev=104648&view=rev Log: Properly promote operands when optimizing a single-character memcmp. Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp llvm/trunk/test/Transforms/SimplifyLibCalls/memcmp.ll Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp?rev=104648&r1=104647&r2=104648&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp Tue May 25 17:53:43 2010 @@ -558,9 +558,12 @@ if (Len == 0) // memcmp(s1,s2,0) -> 0 return Constant::getNullValue(CI->getType()); - if (Len == 1) { // memcmp(S1,S2,1) -> *LHS - *RHS - Value *LHSV = B.CreateLoad(CastToCStr(LHS, B), "lhsv"); - Value *RHSV = B.CreateLoad(CastToCStr(RHS, B), "rhsv"); + // memcmp(S1,S2,1) -> *(unsigned char*)LHS - *(unsigned char*)RHS + if (Len == 1) { + Value *LHSV = B.CreateZExt(B.CreateLoad(CastToCStr(LHS, B), "lhsc"), + CI->getType(), "lhsv"); + Value *RHSV = B.CreateZExt(B.CreateLoad(CastToCStr(RHS, B), "rhsc"), + CI->getType(), "rhsv"); return B.CreateSExt(B.CreateSub(LHSV, RHSV, "chardiff"), CI->getType()); } Modified: llvm/trunk/test/Transforms/SimplifyLibCalls/memcmp.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyLibCalls/memcmp.ll?rev=104648&r1=104647&r2=104648&view=diff ============================================================================== --- llvm/trunk/test/Transforms/SimplifyLibCalls/memcmp.ll (original) +++ llvm/trunk/test/Transforms/SimplifyLibCalls/memcmp.ll Tue May 25 17:53:43 2010 @@ -1,5 +1,5 @@ ; Test that the memcmpOptimizer works correctly -; RUN: opt < %s -simplify-libcalls -S | not grep {call.*memcmp} +; RUN: opt < %s -simplify-libcalls -S | FileCheck %s @h = constant [2 x i8] c"h\00" ; <[2 x i8]*> [#uses=0] @hel = constant [4 x i8] c"hel\00" ; <[4 x i8]*> [#uses=0] @@ -9,14 +9,26 @@ define void @test(i8* %P, i8* %Q, i32 %N, i32* %IP, i1* %BP) { %A = call i32 @memcmp( i8* %P, i8* %P, i32 %N ) ; [#uses=1] +; CHECK-NOT: call {{.*}} memcmp +; CHECK: volatile store volatile store i32 %A, i32* %IP %B = call i32 @memcmp( i8* %P, i8* %Q, i32 0 ) ; [#uses=1] +; CHECK-NOT: call {{.*}} memcmp +; CHECK: volatile store volatile store i32 %B, i32* %IP %C = call i32 @memcmp( i8* %P, i8* %Q, i32 1 ) ; [#uses=1] +; CHECK: load +; CHECK: zext +; CHECK: load +; CHECK: zext +; CHECK: sub +; CHECK: volatile store volatile store i32 %C, i32* %IP %F = call i32 @memcmp(i8* getelementptr ([4 x i8]* @hel, i32 0, i32 0), i8* getelementptr ([8 x i8]* @hello_u, i32 0, i32 0), i32 3) +; CHECK-NOT: call {{.*}} memcmp +; CHECK: volatile store volatile store i32 %F, i32* %IP ret void } From dpatel at apple.com Tue May 25 18:40:22 2010 From: dpatel at apple.com (Devang Patel) Date: Tue, 25 May 2010 23:40:22 -0000 Subject: [llvm-commits] [llvm] r104649 - in /llvm/trunk: lib/CodeGen/AsmPrinter/DIE.h lib/CodeGen/AsmPrinter/DwarfDebug.cpp lib/CodeGen/AsmPrinter/DwarfDebug.h test/DebugInfo/2010-05-25-DotDebugLoc.ll Message-ID: <20100525234022.A6A383128034@llvm.org> Author: dpatel Date: Tue May 25 18:40:22 2010 New Revision: 104649 URL: http://llvm.org/viewvc/llvm-project?rev=104649&view=rev Log: First cut at supporting .debug_loc section. This is used to track variable information. Added: llvm/trunk/test/DebugInfo/2010-05-25-DotDebugLoc.ll Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DIE.h llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DIE.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DIE.h?rev=104649&r1=104648&r2=104649&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DIE.h (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DIE.h Tue May 25 18:40:22 2010 @@ -315,6 +315,10 @@ /// virtual void EmitValue(AsmPrinter *AP, unsigned Form) const; + /// getValue - Get MCSymbol. + /// + const MCSymbol *getValue() const { return Label; } + /// SizeOf - Determine size of label value in bytes. /// virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const; Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=104649&r1=104648&r2=104649&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Tue May 25 18:40:22 2010 @@ -168,15 +168,18 @@ /// class DbgVariable { DIVariable Var; // Variable Descriptor. - DIE *TheDIE; + DIE *TheDIE; // Variable DIE. + unsigned DotDebugLocOffset; // Offset in DotDebugLocEntries. public: // AbsVar may be NULL. - DbgVariable(DIVariable V) : Var(V), TheDIE(0) {} + DbgVariable(DIVariable V) : Var(V), TheDIE(0), DotDebugLocOffset(~0U) {} // Accessors. DIVariable getVariable() const { return Var; } void setDIE(DIE *D) { TheDIE = D; } DIE *getDIE() const { return TheDIE; } + void setDotDebugLocOffset(unsigned O) { DotDebugLocOffset = O; } + unsigned getDotDebugLocOffset() const { return DotDebugLocOffset; } }; //===----------------------------------------------------------------------===// @@ -317,8 +320,8 @@ DwarfFrameSectionSym = DwarfInfoSectionSym = DwarfAbbrevSectionSym = 0; DwarfStrSectionSym = TextSectionSym = 0; - DwarfDebugRangeSectionSym = 0; - FunctionBeginSym = 0; + DwarfDebugRangeSectionSym = DwarfDebugLocSectionSym = 0; + FunctionBeginSym = FunctionEndSym = 0; if (TimePassesIsEnabled) { NamedRegionTimer T(DbgTimerName, DWARFGroupName); beginModule(M); @@ -1441,18 +1444,18 @@ DebugRangeSymbols.size() * Asm->getTargetData().getPointerSize()); for (SmallVector::const_iterator RI = Ranges.begin(), RE = Ranges.end(); RI != RE; ++RI) { - DebugRangeSymbols.push_back(LabelsBeforeInsn.lookup(RI->first)); - DebugRangeSymbols.push_back(LabelsAfterInsn.lookup(RI->second)); + DebugRangeSymbols.push_back(getLabelBeforeInsn(RI->first)); + DebugRangeSymbols.push_back(getLabelAfterInsn(RI->second)); } DebugRangeSymbols.push_back(NULL); DebugRangeSymbols.push_back(NULL); return ScopeDIE; } - MCSymbol *Start = LabelsBeforeInsn.lookup(RI->first); - MCSymbol *End = LabelsAfterInsn.lookup(RI->second); + const MCSymbol *Start = getLabelBeforeInsn(RI->first); + const MCSymbol *End = getLabelAfterInsn(RI->second); - if (Start == 0 || End == 0) return 0; + if (End == 0) return 0; assert(Start->isDefined() && "Invalid starting label for an inlined scope!"); assert(End->isDefined() && "Invalid end label for an inlined scope!"); @@ -1477,10 +1480,10 @@ // For now, use first instruction range and emit low_pc/high_pc pair and // corresponding .debug_inlined section entry for this pair. SmallVector::const_iterator RI = Ranges.begin(); - MCSymbol *StartLabel = LabelsBeforeInsn.lookup(RI->first); - MCSymbol *EndLabel = LabelsAfterInsn.lookup(RI->second); + const MCSymbol *StartLabel = getLabelBeforeInsn(RI->first); + const MCSymbol *EndLabel = getLabelAfterInsn(RI->second); - if (StartLabel == 0 || EndLabel == 0) { + if (StartLabel == FunctionBeginSym || EndLabel == 0) { assert (0 && "Unexpected Start and End labels for a inlined scope!"); return 0; } @@ -1573,61 +1576,76 @@ addType(VariableDie, VD.getType()); } + if (Tag == dwarf::DW_TAG_formal_parameter && VD.getType().isArtificial()) + addUInt(VariableDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1); + + if (Scope->isAbstractScope()) { + DV->setDIE(VariableDie); + return VariableDie; + } + // Add variable address. - if (!Scope->isAbstractScope()) { - // Check if variable is described by DBG_VALUE instruction. - DenseMap::iterator DVI = - DbgVariableToDbgInstMap.find(DV); - if (DVI != DbgVariableToDbgInstMap.end()) { - const MachineInstr *DVInsn = DVI->second; - const MCSymbol *DVLabel = findVariableLabel(DV); - bool updated = false; - // FIXME : Handle getNumOperands != 3 - if (DVInsn->getNumOperands() == 3) { - if (DVInsn->getOperand(0).isReg()) - updated = addRegisterAddress(VariableDie, DVLabel, DVInsn->getOperand(0)); - else if (DVInsn->getOperand(0).isImm()) - updated = addConstantValue(VariableDie, DVLabel, DVInsn->getOperand(0)); - else if (DVInsn->getOperand(0).isFPImm()) - updated = addConstantFPValue(VariableDie, DVLabel, DVInsn->getOperand(0)); - } else { - MachineLocation Location = Asm->getDebugValueLocation(DVInsn); - if (Location.getReg()) { - addAddress(VariableDie, dwarf::DW_AT_location, Location); - if (DVLabel) - addLabel(VariableDie, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr, - DVLabel); - updated = true; - } - } - if (!updated) { - // If variableDie is not updated then DBG_VALUE instruction does not - // have valid variable info. - delete VariableDie; - return NULL; - } - } - else { - MachineLocation Location; - unsigned FrameReg; - const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo(); - int FI = 0; - if (findVariableFrameIndex(DV, &FI)) { - int Offset = RI->getFrameIndexReference(*Asm->MF, FI, FrameReg); - Location.set(FrameReg, Offset); - - if (VD.hasComplexAddress()) - addComplexAddress(DV, VariableDie, dwarf::DW_AT_location, Location); - else if (VD.isBlockByrefVariable()) - addBlockByrefAddress(DV, VariableDie, dwarf::DW_AT_location, Location); - else - addAddress(VariableDie, dwarf::DW_AT_location, Location); + + unsigned Offset = DV->getDotDebugLocOffset(); + if (Offset != ~0U) { + addLabel(VariableDie, dwarf::DW_AT_location, dwarf::DW_FORM_data4, + Asm->GetTempSymbol("debug_loc", Offset)); + DV->setDIE(VariableDie); + UseDotDebugLocEntry.insert(VariableDie); + return VariableDie; + } + + // Check if variable is described by a DBG_VALUE instruction. + DenseMap::iterator DVI = + DbgVariableToDbgInstMap.find(DV); + if (DVI != DbgVariableToDbgInstMap.end()) { + const MachineInstr *DVInsn = DVI->second; + const MCSymbol *DVLabel = findVariableLabel(DV); + bool updated = false; + // FIXME : Handle getNumOperands != 3 + if (DVInsn->getNumOperands() == 3) { + if (DVInsn->getOperand(0).isReg()) + updated = addRegisterAddress(VariableDie, DVLabel, DVInsn->getOperand(0)); + else if (DVInsn->getOperand(0).isImm()) + updated = addConstantValue(VariableDie, DVLabel, DVInsn->getOperand(0)); + else if (DVInsn->getOperand(0).isFPImm()) + updated = addConstantFPValue(VariableDie, DVLabel, DVInsn->getOperand(0)); + } else { + MachineLocation Location = Asm->getDebugValueLocation(DVInsn); + if (Location.getReg()) { + addAddress(VariableDie, dwarf::DW_AT_location, Location); + if (DVLabel) + addLabel(VariableDie, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr, + DVLabel); + updated = true; } } - } + if (!updated) { + // If variableDie is not updated then DBG_VALUE instruction does not + // have valid variable info. + delete VariableDie; + return NULL; + } + DV->setDIE(VariableDie); + return VariableDie; + } - if (Tag == dwarf::DW_TAG_formal_parameter && VD.getType().isArtificial()) - addUInt(VariableDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1); + // .. else use frame index, if available. + MachineLocation Location; + unsigned FrameReg; + const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo(); + int FI = 0; + if (findVariableFrameIndex(DV, &FI)) { + int Offset = RI->getFrameIndexReference(*Asm->MF, FI, FrameReg); + Location.set(FrameReg, Offset); + + if (VD.hasComplexAddress()) + addComplexAddress(DV, VariableDie, dwarf::DW_AT_location, Location); + else if (VD.isBlockByrefVariable()) + addBlockByrefAddress(DV, VariableDie, dwarf::DW_AT_location, Location); + else + addAddress(VariableDie, dwarf::DW_AT_location, Location); + } DV->setDIE(VariableDie); return VariableDie; @@ -2113,6 +2131,24 @@ } } +/// isDbgValueInUndefinedReg - Return true if debug value, encoded by +/// DBG_VALUE instruction, is in undefined reg. +static bool isDbgValueInUndefinedReg(const MachineInstr *MI) { + assert (MI->isDebugValue() && "Invalid DBG_VALUE machine instruction!"); + if (MI->getOperand(0).isReg() && !MI->getOperand(0).getReg()) + return true; + return false; +} + +/// isDbgValueInDefinedReg - Return true if debug value, encoded by +/// DBG_VALUE instruction, is in a defined reg. +static bool isDbgValueInDefinedReg(const MachineInstr *MI) { + assert (MI->isDebugValue() && "Invalid DBG_VALUE machine instruction!"); + if (MI->getOperand(0).isReg() && MI->getOperand(0).getReg()) + return true; + return false; +} + /// collectVariableInfo - Populate DbgScope entries with variables' info. void DwarfDebug::collectVariableInfo(const MachineFunction *MF) { SmallPtrSet Processed; @@ -2127,24 +2163,31 @@ for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end(); II != IE; ++II) { const MachineInstr *MInsn = II; - if (!MInsn->isDebugValue()) + if (!MInsn->isDebugValue() || isDbgValueInUndefinedReg(MInsn)) continue; - - // Ignore Undef values. - if (MInsn->getOperand(0).isReg() && !MInsn->getOperand(0).getReg()) - continue; - DbgValues.push_back(MInsn); } + // This is a collection of DBV_VALUE instructions describing same variable. + SmallVector MultipleValues; for(SmallVector::iterator I = DbgValues.begin(), E = DbgValues.end(); I != E; ++I) { const MachineInstr *MInsn = *I; - + MultipleValues.clear(); + if (isDbgValueInDefinedReg(MInsn)) + MultipleValues.push_back(MInsn); DIVariable DV(MInsn->getOperand(MInsn->getNumOperands() - 1).getMetadata()); if (Processed.count(DV) != 0) continue; + for (SmallVector::iterator MI = I+1, + ME = DbgValues.end(); MI != ME; ++MI) { + const MDNode *Var = + (*MI)->getOperand((*MI)->getNumOperands()-1).getMetadata(); + if (Var == DV && isDbgValueInDefinedReg(*MI)) + MultipleValues.push_back(*MI); + } + DbgScope *Scope = findDbgScope(MInsn); if (!Scope && DV.getTag() == dwarf::DW_TAG_arg_variable) Scope = CurrentFnDbgScope; @@ -2154,16 +2197,45 @@ Processed.insert(DV); DbgVariable *RegVar = new DbgVariable(DV); - DbgVariableToDbgInstMap[RegVar] = MInsn; Scope->addVariable(RegVar); if (DV.getTag() != dwarf::DW_TAG_arg_variable) { DbgValueStartMap[MInsn] = RegVar; - DbgVariableLabelsMap[RegVar] = LabelsBeforeInsn.lookup(MInsn); + DbgVariableLabelsMap[RegVar] = getLabelBeforeInsn(MInsn); } if (DbgVariable *AbsVar = findAbstractVariable(DV, MInsn->getDebugLoc())) { DbgVariableToDbgInstMap[AbsVar] = MInsn; VarToAbstractVarMap[RegVar] = AbsVar; } + if (MultipleValues.size() <= 1) { + DbgVariableToDbgInstMap[RegVar] = MInsn; + continue; + } + + // handle multiple DBG_VALUE instructions describing one variable. + RegVar->setDotDebugLocOffset(DotDebugLocEntries.size()); + if (DotDebugLocEntries.empty()) + DotDebugLocEntries.push_back(DotDebugLocEntry()); + const MachineInstr *Current = MultipleValues.back(); + MultipleValues.pop_back(); + while (!MultipleValues.empty()) { + const MachineInstr *Next = MultipleValues.back(); + MultipleValues.pop_back(); + DbgValueStartMap[Next] = RegVar; + MachineLocation MLoc; + MLoc.set(Current->getOperand(0).getReg(), 0); + const MCSymbol *FLabel = getLabelBeforeInsn(Next); + const MCSymbol *SLabel = getLabelBeforeInsn(Current); + DotDebugLocEntries.push_back(DotDebugLocEntry(FLabel, SLabel, MLoc)); + Current = Next; + if (MultipleValues.empty()) { + // If Next is the last instruction then its value is valid + // until the end of the funtion. + MLoc.set(Next->getOperand(0).getReg(), 0); + DotDebugLocEntries. + push_back(DotDebugLocEntry(SLabel, FunctionEndSym, MLoc)); + } + } + DotDebugLocEntries.push_back(DotDebugLocEntry()); } // Collect info for variables that were optimized out. @@ -2178,26 +2250,45 @@ Scope->addVariable(new DbgVariable(DV)); } } +} +/// getLabelBeforeInsn - Return Label preceding the instruction. +const MCSymbol *DwarfDebug::getLabelBeforeInsn(const MachineInstr *MI) { + DenseMap::iterator I = + LabelsBeforeInsn.find(MI); + if (I == LabelsBeforeInsn.end()) + // FunctionBeginSym always preceeds all the instruction in current function. + return FunctionBeginSym; + return I->second; +} + +/// getLabelAfterInsn - Return Label immediately following the instruction. +const MCSymbol *DwarfDebug::getLabelAfterInsn(const MachineInstr *MI) { + DenseMap::iterator I = + LabelsAfterInsn.find(MI); + if (I == LabelsAfterInsn.end()) + return NULL; + return I->second; } /// beginScope - Process beginning of a scope. void DwarfDebug::beginScope(const MachineInstr *MI) { // Check location. DebugLoc DL = MI->getDebugLoc(); - if (DL.isUnknown() && !UnknownLocations) + if (DL.isUnknown() && !UnknownLocations) { + if (MI->isDebugValue() && PrevLabel) + LabelsBeforeInsn[MI] = PrevLabel; return; + } bool LocalVar = false; if (MI->isDebugValue()) { assert (MI->getNumOperands() > 1 && "Invalid machine instruction!"); DIVariable DV(MI->getOperand(MI->getNumOperands() - 1).getMetadata()); if (!DV.Verify()) return; - if (DV.getTag() != dwarf::DW_TAG_arg_variable) + if (DV.getTag() != dwarf::DW_TAG_arg_variable + && !isDbgValueInUndefinedReg(MI)) LocalVar = true; - // Ignore Undef values. - if (MI->getOperand(0).isReg() && !MI->getOperand(0).getReg()) - LocalVar = false; } MCSymbol *Label = NULL; @@ -2224,7 +2315,7 @@ // If this instruction begins a scope then note down corresponding label // even if previous label is reused. - if (InsnsBeginScopeSet.count(MI) != 0) + if (Label && (InsnsBeginScopeSet.count(MI) != 0 || MI->isDebugValue())) LabelsBeforeInsn[MI] = Label; } @@ -2544,12 +2635,14 @@ if (CurrentFnDbgScope) { - collectVariableInfo(MF); - // Define end label for subprogram. - Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("func_end", - Asm->getFunctionNumber())); + FunctionEndSym = Asm->GetTempSymbol("func_end", + Asm->getFunctionNumber()); + // Assumes in correct section after the entry point. + Asm->OutStreamer.EmitLabel(FunctionEndSym); + collectVariableInfo(MF); + // Get function line info. if (!Lines.empty()) { // Get section line info. @@ -2790,6 +2883,9 @@ DwarfDebugRangeSectionSym = EmitSectionSym(Asm, TLOF.getDwarfRangesSection(), "debug_range"); + DwarfDebugLocSectionSym = EmitSectionSym(Asm, TLOF.getDwarfLocSection(), + "section_debug_loc"); + TextSectionSym = EmitSectionSym(Asm, TLOF.getTextSection(), "text_begin"); EmitSectionSym(Asm, TLOF.getDataSection()); } @@ -2841,6 +2937,14 @@ 4); break; } + case dwarf::DW_AT_location: { + if (UseDotDebugLocEntry.count(Die) != 0) { + DIELabel *L = cast(Values[i]); + Asm->EmitLabelDifference(L->getValue(), DwarfDebugLocSectionSym, 4); + } else + Values[i]->EmitValue(Asm, Form); + break; + } default: // Emit an attribute using the defined form. Values[i]->EmitValue(Asm, Form); @@ -3356,7 +3460,38 @@ void DwarfDebug::emitDebugLoc() { // Start the dwarf loc section. Asm->OutStreamer.SwitchSection( - Asm->getObjFileLowering().getDwarfLocSection()); + Asm->getObjFileLowering().getDwarfLocSection()); + unsigned char Size = Asm->getTargetData().getPointerSize(); + unsigned index = 0; + bool needMarker = true; + for (SmallVector::iterator I = DotDebugLocEntries.begin(), + E = DotDebugLocEntries.end(); I != E; ++I, ++index) { + DotDebugLocEntry Entry = *I; + if (needMarker) { + Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_loc", index)); + needMarker = false; + } + if (Entry.isEmpty()) { + Asm->OutStreamer.EmitIntValue(0, Size, /*addrspace*/0); + Asm->OutStreamer.EmitIntValue(0, Size, /*addrspace*/0); + needMarker = true; + } else { + Asm->OutStreamer.EmitSymbolValue(Entry.Begin, Size, 0); + Asm->OutStreamer.EmitSymbolValue(Entry.End, Size, 0); + const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo(); + unsigned Reg = RI->getDwarfRegNum(Entry.Loc.getReg(), false); + if (Reg < 32) { + Asm->OutStreamer.AddComment("Loc expr size"); + Asm->EmitInt16(1); + Asm->EmitInt8(dwarf::DW_OP_reg0 + Reg); + } else { + Asm->OutStreamer.AddComment("Loc expr size"); + Asm->EmitInt16(1+MCAsmInfo::getULEB128Size(Reg)); + Asm->EmitInt8(dwarf::DW_OP_regx); + Asm->EmitULEB128(Reg); + } + } + } } /// EmitDebugARanges - Emit visible names into a debug aranges section. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=104649&r1=104648&r2=104649&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Tue May 25 18:40:22 2010 @@ -15,6 +15,7 @@ #define CODEGEN_ASMPRINTER_DWARFDEBUG_H__ #include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/CodeGen/MachineLocation.h" #include "DIE.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" @@ -30,7 +31,6 @@ class DbgScope; class DbgVariable; class MachineFrameInfo; -class MachineLocation; class MachineModuleInfo; class MachineOperand; class MCAsmInfo; @@ -181,6 +181,27 @@ /// DbgVariableLabelsMap - Maps DbgVariable to corresponding MCSymbol. DenseMap DbgVariableLabelsMap; + /// DotDebugLocEntry - This struct describes location entries emitted in + /// .debug_loc section. + typedef struct DotDebugLocEntry { + const MCSymbol *Begin; + const MCSymbol *End; + MachineLocation Loc; + DotDebugLocEntry() : Begin(0), End(0) {} + DotDebugLocEntry(const MCSymbol *B, const MCSymbol *E, + MachineLocation &L) : Begin(B), End(E), Loc(L) {} + /// Empty entries are also used as a trigger to emit temp label. Such + /// labels are referenced is used to find debug_loc offset for a given DIE. + bool isEmpty() { return Begin == 0 && End == 0; } + } DotDebugLocEntry; + + /// DotDebugLocEntries - Collection of DotDebugLocEntry. + SmallVector DotDebugLocEntries; + + /// UseDotDebugLocEntry - DW_AT_location attributes for the DIEs in this set + /// idetifies corresponding .debug_loc entry offset. + SmallPtrSet UseDotDebugLocEntry; + /// VarToAbstractVarMap - Maps DbgVariable with corresponding Abstract /// DbgVariable, if any. DenseMap VarToAbstractVarMap; @@ -200,7 +221,7 @@ /// InlineInfo - Keep track of inlined functions and their location. This /// information is used to populate debug_inlined section. - typedef std::pair InlineInfoLabels; + typedef std::pair InlineInfoLabels; DenseMap > InlineInfo; SmallVector InlinedSPNodes; @@ -234,8 +255,8 @@ // section offsets and are created by EmitSectionLabels. MCSymbol *DwarfFrameSectionSym, *DwarfInfoSectionSym, *DwarfAbbrevSectionSym; MCSymbol *DwarfStrSectionSym, *TextSectionSym, *DwarfDebugRangeSectionSym; - - MCSymbol *FunctionBeginSym; + MCSymbol *DwarfDebugLocSectionSym; + MCSymbol *FunctionBeginSym, *FunctionEndSym; private: /// getSourceDirectoryAndFileIds - Return the directory and file ids that @@ -600,6 +621,12 @@ /// void endFunction(const MachineFunction *MF); + /// getLabelBeforeInsn - Return Label preceding the instruction. + const MCSymbol *getLabelBeforeInsn(const MachineInstr *MI); + + /// getLabelAfterInsn - Return Label immediately following the instruction. + const MCSymbol *getLabelAfterInsn(const MachineInstr *MI); + /// beginScope - Process beginning of a scope. void beginScope(const MachineInstr *MI); Added: llvm/trunk/test/DebugInfo/2010-05-25-DotDebugLoc.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/2010-05-25-DotDebugLoc.ll?rev=104649&view=auto ============================================================================== --- llvm/trunk/test/DebugInfo/2010-05-25-DotDebugLoc.ll (added) +++ llvm/trunk/test/DebugInfo/2010-05-25-DotDebugLoc.ll Tue May 25 18:40:22 2010 @@ -0,0 +1,239 @@ +; RUN: llc -O2 < %s | grep debug_loc13 +; Test to check .debug_loc support. This test case emits 14 debug_loc entries. + +%0 = type { double } + +define hidden %0 @__divsc3(float %a, float %b, float %c, float %d) nounwind readnone { +entry: + tail call void @llvm.dbg.value(metadata !{float %a}, i64 0, metadata !0) + tail call void @llvm.dbg.value(metadata !{float %b}, i64 0, metadata !11) + tail call void @llvm.dbg.value(metadata !{float %c}, i64 0, metadata !12) + tail call void @llvm.dbg.value(metadata !{float %d}, i64 0, metadata !13) + %0 = tail call float @fabsf(float %c) nounwind readnone, !dbg !19 ; [#uses=1] + %1 = tail call float @fabsf(float %d) nounwind readnone, !dbg !19 ; [#uses=1] + %2 = fcmp olt float %0, %1, !dbg !19 ; [#uses=1] + br i1 %2, label %bb, label %bb1, !dbg !19 + +bb: ; preds = %entry + %3 = fdiv float %c, %d, !dbg !20 ; [#uses=3] + tail call void @llvm.dbg.value(metadata !{float %3}, i64 0, metadata !16), !dbg !20 + %4 = fmul float %3, %c, !dbg !21 ; [#uses=1] + %5 = fadd float %4, %d, !dbg !21 ; [#uses=2] + tail call void @llvm.dbg.value(metadata !{float %5}, i64 0, metadata !14), !dbg !21 + %6 = fmul float %3, %a, !dbg !22 ; [#uses=1] + %7 = fadd float %6, %b, !dbg !22 ; [#uses=1] + %8 = fdiv float %7, %5, !dbg !22 ; [#uses=1] + tail call void @llvm.dbg.value(metadata !{float %8}, i64 0, metadata !17), !dbg !22 + %9 = fmul float %3, %b, !dbg !23 ; [#uses=1] + %10 = fsub float %9, %a, !dbg !23 ; [#uses=1] + %11 = fdiv float %10, %5, !dbg !23 ; [#uses=1] + tail call void @llvm.dbg.value(metadata !{float %11}, i64 0, metadata !18), !dbg !23 + br label %bb2, !dbg !23 + +bb1: ; preds = %entry + %12 = fdiv float %d, %c, !dbg !24 ; [#uses=3] + tail call void @llvm.dbg.value(metadata !{float %12}, i64 0, metadata !16), !dbg !24 + %13 = fmul float %12, %d, !dbg !25 ; [#uses=1] + %14 = fadd float %13, %c, !dbg !25 ; [#uses=2] + tail call void @llvm.dbg.value(metadata !{float %14}, i64 0, metadata !14), !dbg !25 + %15 = fmul float %12, %b, !dbg !26 ; [#uses=1] + %16 = fadd float %15, %a, !dbg !26 ; [#uses=1] + %17 = fdiv float %16, %14, !dbg !26 ; [#uses=1] + tail call void @llvm.dbg.value(metadata !{float %17}, i64 0, metadata !17), !dbg !26 + %18 = fmul float %12, %a, !dbg !27 ; [#uses=1] + %19 = fsub float %b, %18, !dbg !27 ; [#uses=1] + %20 = fdiv float %19, %14, !dbg !27 ; [#uses=1] + tail call void @llvm.dbg.value(metadata !{float %20}, i64 0, metadata !18), !dbg !27 + br label %bb2, !dbg !27 + +bb2: ; preds = %bb1, %bb + %y.0 = phi float [ %11, %bb ], [ %20, %bb1 ] ; [#uses=5] + %x.0 = phi float [ %8, %bb ], [ %17, %bb1 ] ; [#uses=5] + %21 = fcmp uno float %x.0, 0.000000e+00, !dbg !28 ; [#uses=1] + %22 = fcmp uno float %y.0, 0.000000e+00, !dbg !28 ; [#uses=1] + %or.cond = and i1 %21, %22 ; [#uses=1] + br i1 %or.cond, label %bb4, label %bb46, !dbg !28 + +bb4: ; preds = %bb2 + %23 = fcmp une float %c, 0.000000e+00, !dbg !29 ; [#uses=1] + %24 = fcmp une float %d, 0.000000e+00, !dbg !29 ; [#uses=1] + %or.cond93 = or i1 %23, %24 ; [#uses=1] + br i1 %or.cond93, label %bb9, label %bb6, !dbg !29 + +bb6: ; preds = %bb4 + %25 = fcmp uno float %a, 0.000000e+00, !dbg !29 ; [#uses=1] + %26 = fcmp uno float %b, 0.000000e+00, !dbg !29 ; [#uses=1] + %or.cond94 = and i1 %25, %26 ; [#uses=1] + br i1 %or.cond94, label %bb9, label %bb8, !dbg !29 + +bb8: ; preds = %bb6 + %27 = tail call float @copysignf(float 0x7FF0000000000000, float %c) nounwind readnone, !dbg !30 ; [#uses=2] + %28 = fmul float %27, %a, !dbg !30 ; [#uses=1] + tail call void @llvm.dbg.value(metadata !{float %28}, i64 0, metadata !17), !dbg !30 + %29 = fmul float %27, %b, !dbg !31 ; [#uses=1] + tail call void @llvm.dbg.value(metadata !{float %29}, i64 0, metadata !18), !dbg !31 + br label %bb46, !dbg !31 + +bb9: ; preds = %bb6, %bb4 + %30 = fcmp ord float %a, 0.000000e+00 ; [#uses=1] + %31 = fsub float %a, %a, !dbg !32 ; [#uses=3] + %32 = fcmp uno float %31, 0.000000e+00 ; [#uses=1] + %33 = and i1 %30, %32, !dbg !32 ; [#uses=2] + br i1 %33, label %bb14, label %bb11, !dbg !32 + +bb11: ; preds = %bb9 + %34 = fcmp ord float %b, 0.000000e+00 ; [#uses=1] + %35 = fsub float %b, %b, !dbg !32 ; [#uses=1] + %36 = fcmp uno float %35, 0.000000e+00 ; [#uses=1] + %37 = and i1 %34, %36, !dbg !32 ; [#uses=1] + br i1 %37, label %bb14, label %bb27, !dbg !32 + +bb14: ; preds = %bb11, %bb9 + %38 = fsub float %c, %c, !dbg !32 ; [#uses=1] + %39 = fcmp ord float %38, 0.000000e+00 ; [#uses=1] + br i1 %39, label %bb15, label %bb27, !dbg !32 + +bb15: ; preds = %bb14 + %40 = fsub float %d, %d, !dbg !32 ; [#uses=1] + %41 = fcmp ord float %40, 0.000000e+00 ; [#uses=1] + br i1 %41, label %bb16, label %bb27, !dbg !32 + +bb16: ; preds = %bb15 + %iftmp.0.0 = select i1 %33, float 1.000000e+00, float 0.000000e+00 ; [#uses=1] + %42 = tail call float @copysignf(float %iftmp.0.0, float %a) nounwind readnone, !dbg !33 ; [#uses=2] + tail call void @llvm.dbg.value(metadata !{float %42}, i64 0, metadata !0), !dbg !33 + %43 = fcmp ord float %b, 0.000000e+00 ; [#uses=1] + %44 = fsub float %b, %b, !dbg !34 ; [#uses=1] + %45 = fcmp uno float %44, 0.000000e+00 ; [#uses=1] + %46 = and i1 %43, %45, !dbg !34 ; [#uses=1] + %iftmp.1.0 = select i1 %46, float 1.000000e+00, float 0.000000e+00 ; [#uses=1] + %47 = tail call float @copysignf(float %iftmp.1.0, float %b) nounwind readnone, !dbg !34 ; [#uses=2] + tail call void @llvm.dbg.value(metadata !{float %47}, i64 0, metadata !11), !dbg !34 + %48 = fmul float %42, %c, !dbg !35 ; [#uses=1] + %49 = fmul float %47, %d, !dbg !35 ; [#uses=1] + %50 = fadd float %48, %49, !dbg !35 ; [#uses=1] + %51 = fmul float %50, 0x7FF0000000000000, !dbg !35 ; [#uses=1] + tail call void @llvm.dbg.value(metadata !{float %51}, i64 0, metadata !17), !dbg !35 + %52 = fmul float %47, %c, !dbg !36 ; [#uses=1] + %53 = fmul float %42, %d, !dbg !36 ; [#uses=1] + %54 = fsub float %52, %53, !dbg !36 ; [#uses=1] + %55 = fmul float %54, 0x7FF0000000000000, !dbg !36 ; [#uses=1] + tail call void @llvm.dbg.value(metadata !{float %55}, i64 0, metadata !18), !dbg !36 + br label %bb46, !dbg !36 + +bb27: ; preds = %bb15, %bb14, %bb11 + %56 = fcmp ord float %c, 0.000000e+00 ; [#uses=1] + %57 = fsub float %c, %c, !dbg !37 ; [#uses=1] + %58 = fcmp uno float %57, 0.000000e+00 ; [#uses=1] + %59 = and i1 %56, %58, !dbg !37 ; [#uses=2] + br i1 %59, label %bb33, label %bb30, !dbg !37 + +bb30: ; preds = %bb27 + %60 = fcmp ord float %d, 0.000000e+00 ; [#uses=1] + %61 = fsub float %d, %d, !dbg !37 ; [#uses=1] + %62 = fcmp uno float %61, 0.000000e+00 ; [#uses=1] + %63 = and i1 %60, %62, !dbg !37 ; [#uses=1] + %64 = fcmp ord float %31, 0.000000e+00 ; [#uses=1] + %or.cond95 = and i1 %63, %64 ; [#uses=1] + br i1 %or.cond95, label %bb34, label %bb46, !dbg !37 + +bb33: ; preds = %bb27 + %.old = fcmp ord float %31, 0.000000e+00 ; [#uses=1] + br i1 %.old, label %bb34, label %bb46, !dbg !37 + +bb34: ; preds = %bb33, %bb30 + %65 = fsub float %b, %b, !dbg !37 ; [#uses=1] + %66 = fcmp ord float %65, 0.000000e+00 ; [#uses=1] + br i1 %66, label %bb35, label %bb46, !dbg !37 + +bb35: ; preds = %bb34 + %iftmp.2.0 = select i1 %59, float 1.000000e+00, float 0.000000e+00 ; [#uses=1] + %67 = tail call float @copysignf(float %iftmp.2.0, float %c) nounwind readnone, !dbg !38 ; [#uses=2] + tail call void @llvm.dbg.value(metadata !{float %67}, i64 0, metadata !12), !dbg !38 + %68 = fcmp ord float %d, 0.000000e+00 ; [#uses=1] + %69 = fsub float %d, %d, !dbg !39 ; [#uses=1] + %70 = fcmp uno float %69, 0.000000e+00 ; [#uses=1] + %71 = and i1 %68, %70, !dbg !39 ; [#uses=1] + %iftmp.3.0 = select i1 %71, float 1.000000e+00, float 0.000000e+00 ; [#uses=1] + %72 = tail call float @copysignf(float %iftmp.3.0, float %d) nounwind readnone, !dbg !39 ; [#uses=2] + tail call void @llvm.dbg.value(metadata !{float %72}, i64 0, metadata !13), !dbg !39 + %73 = fmul float %67, %a, !dbg !40 ; [#uses=1] + %74 = fmul float %72, %b, !dbg !40 ; [#uses=1] + %75 = fadd float %73, %74, !dbg !40 ; [#uses=1] + %76 = fmul float %75, 0.000000e+00, !dbg !40 ; [#uses=1] + tail call void @llvm.dbg.value(metadata !{float %76}, i64 0, metadata !17), !dbg !40 + %77 = fmul float %67, %b, !dbg !41 ; [#uses=1] + %78 = fmul float %72, %a, !dbg !41 ; [#uses=1] + %79 = fsub float %77, %78, !dbg !41 ; [#uses=1] + %80 = fmul float %79, 0.000000e+00, !dbg !41 ; [#uses=1] + tail call void @llvm.dbg.value(metadata !{float %80}, i64 0, metadata !18), !dbg !41 + br label %bb46, !dbg !41 + +bb46: ; preds = %bb35, %bb34, %bb33, %bb30, %bb16, %bb8, %bb2 + %y.1 = phi float [ %80, %bb35 ], [ %y.0, %bb34 ], [ %y.0, %bb33 ], [ %y.0, %bb30 ], [ %55, %bb16 ], [ %29, %bb8 ], [ %y.0, %bb2 ] ; [#uses=2] + %x.1 = phi float [ %76, %bb35 ], [ %x.0, %bb34 ], [ %x.0, %bb33 ], [ %x.0, %bb30 ], [ %51, %bb16 ], [ %28, %bb8 ], [ %x.0, %bb2 ] ; [#uses=1] + %81 = fmul float %y.1, 0.000000e+00, !dbg !42 ; [#uses=1] + %82 = fadd float %y.1, 0.000000e+00, !dbg !42 ; [#uses=1] + %tmpr = fadd float %x.1, %81, !dbg !42 ; [#uses=1] + %tmp89 = bitcast float %tmpr to i32 ; [#uses=1] + %tmp90 = zext i32 %tmp89 to i64 ; [#uses=1] + %tmp85 = bitcast float %82 to i32 ; [#uses=1] + %tmp86 = zext i32 %tmp85 to i64 ; [#uses=1] + %tmp87 = shl i64 %tmp86, 32 ; [#uses=1] + %ins = or i64 %tmp90, %tmp87 ; [#uses=1] + %tmp84 = bitcast i64 %ins to double ; [#uses=1] + %mrv75 = insertvalue %0 undef, double %tmp84, 0, !dbg !42 ; <%0> [#uses=1] + ret %0 %mrv75, !dbg !42 +} + +declare float @fabsf(float) + +declare float @copysignf(float, float) nounwind readnone + +declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone + +!llvm.dbg.lv = !{!0, !11, !12, !13, !14, !16, !17, !18} + +!0 = metadata !{i32 524545, metadata !1, metadata !"a", metadata !2, i32 1921, metadata !9} ; [ DW_TAG_arg_variable ] +!1 = metadata !{i32 524334, i32 0, metadata !2, metadata !"__divsc3", metadata !"__divsc3", metadata !"__divsc3", metadata !2, i32 1922, metadata !4, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true} ; [ DW_TAG_subprogram ] +!2 = metadata !{i32 524329, metadata !"libgcc2.c", metadata !"/Users/yash/clean/LG.D/gcc/../../llvmgcc/gcc", metadata !3} ; [ DW_TAG_file_type ] +!3 = metadata !{i32 524305, i32 0, i32 1, metadata !"libgcc2.c", metadata !"/Users/yash/clean/LG.D/gcc/../../llvmgcc/gcc", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] +!4 = metadata !{i32 524309, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !5, i32 0, null} ; [ DW_TAG_subroutine_type ] +!5 = metadata !{metadata !6, metadata !9, metadata !9, metadata !9, metadata !9} +!6 = metadata !{i32 524310, metadata !7, metadata !"SCtype", metadata !7, i32 170, i64 0, i64 0, i64 0, i32 0, metadata !8} ; [ DW_TAG_typedef ] +!7 = metadata !{i32 524329, metadata !"libgcc2.h", metadata !"/Users/yash/clean/LG.D/gcc/../../llvmgcc/gcc", metadata !3} ; [ DW_TAG_file_type ] +!8 = metadata !{i32 524324, metadata !2, metadata !"complex float", metadata !2, i32 0, i64 64, i64 32, i64 0, i32 0, i32 3} ; [ DW_TAG_base_type ] +!9 = metadata !{i32 524310, metadata !7, metadata !"SFtype", metadata !7, i32 167, i64 0, i64 0, i64 0, i32 0, metadata !10} ; [ DW_TAG_typedef ] +!10 = metadata !{i32 524324, metadata !2, metadata !"float", metadata !2, i32 0, i64 32, i64 32, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ] +!11 = metadata !{i32 524545, metadata !1, metadata !"b", metadata !2, i32 1921, metadata !9} ; [ DW_TAG_arg_variable ] +!12 = metadata !{i32 524545, metadata !1, metadata !"c", metadata !2, i32 1921, metadata !9} ; [ DW_TAG_arg_variable ] +!13 = metadata !{i32 524545, metadata !1, metadata !"d", metadata !2, i32 1921, metadata !9} ; [ DW_TAG_arg_variable ] +!14 = metadata !{i32 524544, metadata !15, metadata !"denom", metadata !2, i32 1923, metadata !9} ; [ DW_TAG_auto_variable ] +!15 = metadata !{i32 524299, metadata !1, i32 1922, i32 0} ; [ DW_TAG_lexical_block ] +!16 = metadata !{i32 524544, metadata !15, metadata !"ratio", metadata !2, i32 1923, metadata !9} ; [ DW_TAG_auto_variable ] +!17 = metadata !{i32 524544, metadata !15, metadata !"x", metadata !2, i32 1923, metadata !9} ; [ DW_TAG_auto_variable ] +!18 = metadata !{i32 524544, metadata !15, metadata !"y", metadata !2, i32 1923, metadata !9} ; [ DW_TAG_auto_variable ] +!19 = metadata !{i32 1929, i32 0, metadata !15, null} +!20 = metadata !{i32 1931, i32 0, metadata !15, null} +!21 = metadata !{i32 1932, i32 0, metadata !15, null} +!22 = metadata !{i32 1933, i32 0, metadata !15, null} +!23 = metadata !{i32 1934, i32 0, metadata !15, null} +!24 = metadata !{i32 1938, i32 0, metadata !15, null} +!25 = metadata !{i32 1939, i32 0, metadata !15, null} +!26 = metadata !{i32 1940, i32 0, metadata !15, null} +!27 = metadata !{i32 1941, i32 0, metadata !15, null} +!28 = metadata !{i32 1946, i32 0, metadata !15, null} +!29 = metadata !{i32 1948, i32 0, metadata !15, null} +!30 = metadata !{i32 1950, i32 0, metadata !15, null} +!31 = metadata !{i32 1951, i32 0, metadata !15, null} +!32 = metadata !{i32 1953, i32 0, metadata !15, null} +!33 = metadata !{i32 1955, i32 0, metadata !15, null} +!34 = metadata !{i32 1956, i32 0, metadata !15, null} +!35 = metadata !{i32 1957, i32 0, metadata !15, null} +!36 = metadata !{i32 1958, i32 0, metadata !15, null} +!37 = metadata !{i32 1960, i32 0, metadata !15, null} +!38 = metadata !{i32 1962, i32 0, metadata !15, null} +!39 = metadata !{i32 1963, i32 0, metadata !15, null} +!40 = metadata !{i32 1964, i32 0, metadata !15, null} +!41 = metadata !{i32 1965, i32 0, metadata !15, null} +!42 = metadata !{i32 1969, i32 0, metadata !15, null} From stoklund at 2pi.dk Tue May 25 18:43:18 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 25 May 2010 23:43:18 -0000 Subject: [llvm-commits] [llvm] r104650 - in /llvm/trunk: include/llvm/Target/TargetRegisterInfo.h lib/Target/TargetRegisterInfo.cpp utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <20100525234318.5AC5F3128034@llvm.org> Author: stoklund Date: Tue May 25 18:43:18 2010 New Revision: 104650 URL: http://llvm.org/viewvc/llvm-project?rev=104650&view=rev Log: Drop the SuperregHashTable. It is essentially the same as SubregHashTable. Modified: llvm/trunk/include/llvm/Target/TargetRegisterInfo.h llvm/trunk/lib/Target/TargetRegisterInfo.cpp llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Modified: llvm/trunk/include/llvm/Target/TargetRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetRegisterInfo.h?rev=104650&r1=104649&r2=104650&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetRegisterInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetRegisterInfo.h Tue May 25 18:43:18 2010 @@ -260,8 +260,6 @@ protected: const unsigned* SubregHash; const unsigned SubregHashSize; - const unsigned* SuperregHash; - const unsigned SuperregHashSize; const unsigned* AliasesHash; const unsigned AliasesHashSize; public: @@ -284,8 +282,6 @@ int CallFrameDestroyOpcode = -1, const unsigned* subregs = 0, const unsigned subregsize = 0, - const unsigned* superregs = 0, - const unsigned superregsize = 0, const unsigned* aliases = 0, const unsigned aliasessize = 0); virtual ~TargetRegisterInfo(); @@ -432,19 +428,7 @@ /// isSuperRegister - Returns true if regB is a super-register of regA. /// bool isSuperRegister(unsigned regA, unsigned regB) const { - // SuperregHash is a simple quadratically probed hash table. - size_t index = (regA + regB * 37) & (SuperregHashSize-1); - unsigned ProbeAmt = 2; - while (SuperregHash[index*2] != 0 && - SuperregHash[index*2+1] != 0) { - if (SuperregHash[index*2] == regA && SuperregHash[index*2+1] == regB) - return true; - - index = (index + ProbeAmt) & (SuperregHashSize-1); - ProbeAmt += 2; - } - - return false; + return isSubRegister(regB, regA); } /// getCalleeSavedRegs - Return a null-terminated list of all of the Modified: llvm/trunk/lib/Target/TargetRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetRegisterInfo.cpp?rev=104650&r1=104649&r2=104650&view=diff ============================================================================== --- llvm/trunk/lib/Target/TargetRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/TargetRegisterInfo.cpp Tue May 25 18:43:18 2010 @@ -25,10 +25,8 @@ const char *const *subregindexnames, int CFSO, int CFDO, const unsigned* subregs, const unsigned subregsize, - const unsigned* superregs, const unsigned superregsize, const unsigned* aliases, const unsigned aliasessize) : SubregHash(subregs), SubregHashSize(subregsize), - SuperregHash(superregs), SuperregHashSize(superregsize), AliasesHash(aliases), AliasesHashSize(aliasessize), Desc(D), SubRegIndexNames(subregindexnames), NumRegs(NR), RegClassBegin(RCB), RegClassEnd(RCE) { Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp?rev=104650&r1=104649&r2=104650&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Tue May 25 18:43:18 2010 @@ -576,83 +576,6 @@ delete [] SubregHashTable; - // Print the SuperregHashTable, a simple quadratically probed - // hash table for determining if a register is a super-register - // of another register. - unsigned NumSupRegs = 0; - RegNo.clear(); - for (unsigned i = 0, e = Regs.size(); i != e; ++i) { - RegNo[Regs[i].TheDef] = i; - NumSupRegs += RegisterSuperRegs[Regs[i].TheDef].size(); - } - - unsigned SuperregHashTableSize = 2 * NextPowerOf2(2 * NumSupRegs); - unsigned* SuperregHashTable = new unsigned[2 * SuperregHashTableSize]; - std::fill(SuperregHashTable, SuperregHashTable + 2 * SuperregHashTableSize, ~0U); - - hashMisses = 0; - - for (unsigned i = 0, e = Regs.size(); i != e; ++i) { - Record* R = Regs[i].TheDef; - for (std::set::iterator I = RegisterSuperRegs[R].begin(), - E = RegisterSuperRegs[R].end(); I != E; ++I) { - Record* RJ = *I; - // We have to increase the indices of both registers by one when - // computing the hash because, in the generated code, there - // will be an extra empty slot at register 0. - size_t index = ((i+1) + (RegNo[RJ]+1) * 37) & (SuperregHashTableSize-1); - unsigned ProbeAmt = 2; - while (SuperregHashTable[index*2] != ~0U && - SuperregHashTable[index*2+1] != ~0U) { - index = (index + ProbeAmt) & (SuperregHashTableSize-1); - ProbeAmt += 2; - - hashMisses++; - } - - SuperregHashTable[index*2] = i; - SuperregHashTable[index*2+1] = RegNo[RJ]; - } - } - - OS << "\n\n // Number of hash collisions: " << hashMisses << "\n"; - - if (SuperregHashTableSize) { - std::string Namespace = Regs[0].TheDef->getValueAsString("Namespace"); - - OS << " const unsigned SuperregHashTable[] = { "; - for (unsigned i = 0; i < SuperregHashTableSize - 1; ++i) { - if (i != 0) - // Insert spaces for nice formatting. - OS << " "; - - if (SuperregHashTable[2*i] != ~0U) { - OS << getQualifiedName(Regs[SuperregHashTable[2*i]].TheDef) << ", " - << getQualifiedName(Regs[SuperregHashTable[2*i+1]].TheDef) << ", \n"; - } else { - OS << Namespace << "::NoRegister, " << Namespace << "::NoRegister, \n"; - } - } - - unsigned Idx = SuperregHashTableSize*2-2; - if (SuperregHashTable[Idx] != ~0U) { - OS << " " - << getQualifiedName(Regs[SuperregHashTable[Idx]].TheDef) << ", " - << getQualifiedName(Regs[SuperregHashTable[Idx+1]].TheDef) << " };\n"; - } else { - OS << Namespace << "::NoRegister, " << Namespace << "::NoRegister };\n"; - } - - OS << " const unsigned SuperregHashTableSize = " - << SuperregHashTableSize << ";\n"; - } else { - OS << " const unsigned SuperregHashTable[] = { ~0U, ~0U };\n" - << " const unsigned SuperregHashTableSize = 1;\n"; - } - - delete [] SuperregHashTable; - - // Print the AliasHashTable, a simple quadratically probed // hash table for determining if a register aliases another register. unsigned NumAliases = 0; @@ -792,9 +715,8 @@ // Now that register alias and sub-registers sets have been emitted, emit the // register descriptors now. - const std::vector &Registers = Target.getRegisters(); - for (unsigned i = 0, e = Registers.size(); i != e; ++i) { - const CodeGenRegister &Reg = Registers[i]; + for (unsigned i = 0, e = Regs.size(); i != e; ++i) { + const CodeGenRegister &Reg = Regs[i]; OS << " { \""; OS << Reg.getName() << "\",\t"; if (RegisterAliases.count(Reg.TheDef)) @@ -885,12 +807,11 @@ // Emit the constructor of the class... OS << ClassName << "::" << ClassName << "(int CallFrameSetupOpcode, int CallFrameDestroyOpcode)\n" - << " : TargetRegisterInfo(RegisterDescriptors, " << Registers.size()+1 + << " : TargetRegisterInfo(RegisterDescriptors, " << Regs.size()+1 << ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n" << " SubRegIndexTable,\n" << " CallFrameSetupOpcode, CallFrameDestroyOpcode,\n" << " SubregHashTable, SubregHashTableSize,\n" - << " SuperregHashTable, SuperregHashTableSize,\n" << " AliasesHashTable, AliasesHashTableSize) {\n" << "}\n\n"; @@ -898,8 +819,8 @@ // First, just pull all provided information to the map unsigned maxLength = 0; - for (unsigned i = 0, e = Registers.size(); i != e; ++i) { - Record *Reg = Registers[i].TheDef; + for (unsigned i = 0, e = Regs.size(); i != e; ++i) { + Record *Reg = Regs[i].TheDef; std::vector RegNums = Reg->getValueAsListOfInts("DwarfNumbers"); maxLength = std::max((size_t)maxLength, RegNums.size()); if (DwarfRegNums.count(Reg)) From evan.cheng at apple.com Tue May 25 18:46:18 2010 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 25 May 2010 16:46:18 -0700 Subject: [llvm-commits] [llvm] r104640 - /llvm/trunk/lib/CodeGen/StackSlotColoring.cpp In-Reply-To: References: <20100525214427.0BB0A3128034@llvm.org> Message-ID: <08125B4E-FE37-445F-A408-8E5B6FA2B5CE@apple.com> On May 25, 2010, at 2:56 PM, Dale Johannesen wrote: > On May 25, 2010, at 2:44 PMPDT, Bill Wendling wrote: >> >> +/// CheckForSetJmpCall - Return true if there's a call to setjmp/ >> sigsetjmp in >> +/// this function. >> +bool StackSlotColoring::CheckForSetJmpCall(const MachineFunction >> &MF) { >> + const Function *F = MF.getFunction(); > > Should we figure this out once and set a bit in the function? There > are other optimization phases that need to know this. I agree. This seems like something that can happen much earlier during isel. Evan > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From echristo at apple.com Tue May 25 19:02:13 2010 From: echristo at apple.com (Eric Christopher) Date: Wed, 26 May 2010 00:02:13 -0000 Subject: [llvm-commits] [llvm] r104651 - in /llvm/trunk: include/llvm/MC/MCExpr.h lib/MC/MCExpr.cpp lib/MC/MachObjectWriter.cpp Message-ID: <20100526000213.180C23128034@llvm.org> Author: echristo Date: Tue May 25 19:02:12 2010 New Revision: 104651 URL: http://llvm.org/viewvc/llvm-project?rev=104651&view=rev Log: Start adding mach-o tls reloc support. Modified: llvm/trunk/include/llvm/MC/MCExpr.h llvm/trunk/lib/MC/MCExpr.cpp llvm/trunk/lib/MC/MachObjectWriter.cpp Modified: llvm/trunk/include/llvm/MC/MCExpr.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCExpr.h?rev=104651&r1=104650&r2=104651&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCExpr.h (original) +++ llvm/trunk/include/llvm/MC/MCExpr.h Tue May 25 19:02:12 2010 @@ -136,7 +136,8 @@ VK_TLSGD, VK_TPOFF, VK_ARM_HI16, // The R_ARM_MOVT_ABS relocation (:upper16: in the asm file) - VK_ARM_LO16 // The R_ARM_MOVW_ABS_NC relocation (:lower16: in the asm file) + VK_ARM_LO16, // The R_ARM_MOVW_ABS_NC relocation (:lower16: in the asm file) + VK_TLVP // Mach-O thread local variable relocation }; private: Modified: llvm/trunk/lib/MC/MCExpr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCExpr.cpp?rev=104651&r1=104650&r2=104651&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCExpr.cpp (original) +++ llvm/trunk/lib/MC/MCExpr.cpp Tue May 25 19:02:12 2010 @@ -177,6 +177,7 @@ case VK_TPOFF: return "TPOFF"; case VK_ARM_HI16: return ":upper16:"; case VK_ARM_LO16: return ":lower16:"; + case VK_TLVP: return "TLVP"; } } @@ -192,6 +193,7 @@ .Case("PLT", VK_PLT) .Case("TLSGD", VK_TLSGD) .Case("TPOFF", VK_TPOFF) + .Case("TLVP", VK_TLVP) .Default(VK_Invalid); } Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=104651&r1=104650&r2=104651&view=diff ============================================================================== --- llvm/trunk/lib/MC/MachObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/MachObjectWriter.cpp Tue May 25 19:02:12 2010 @@ -145,7 +145,8 @@ RIT_Pair = 1, RIT_Difference = 2, RIT_PreboundLazyPointer = 3, - RIT_LocalDifference = 4 + RIT_LocalDifference = 4, + RIT_TLV = 5 }; /// X86_64 uses its own relocation types. @@ -158,7 +159,8 @@ RIT_X86_64_Subtractor = 5, RIT_X86_64_Signed1 = 6, RIT_X86_64_Signed2 = 7, - RIT_X86_64_Signed4 = 8 + RIT_X86_64_Signed4 = 8, + RIT_X86_64_TLV = 9 }; /// MachSymbolData - Helper struct for containing some precomputed information @@ -610,6 +612,8 @@ Type = RIT_X86_64_GOT; } else if (Modifier != MCSymbolRefExpr::VK_None) { report_fatal_error("unsupported symbol modifier in relocation"); + } else if (Modifier == MCSymbolRefExpr::VK_TLVP) { + Type = RIT_X86_64_TLV; } else { Type = RIT_X86_64_Signed; @@ -650,6 +654,8 @@ // required to include any necessary offset directly. Type = RIT_X86_64_GOT; IsPCRel = 1; + } else if (Modifier == MCSymbolRefExpr::VK_TLVP) { + report_fatal_error("TLVP symbol modifier should have been rip-rel"); } else if (Modifier != MCSymbolRefExpr::VK_None) report_fatal_error("unsupported symbol modifier in relocation"); else From sliao at google.com Tue May 25 19:02:28 2010 From: sliao at google.com (Shih-wei Liao) Date: Wed, 26 May 2010 00:02:28 -0000 Subject: [llvm-commits] [llvm] r104652 - /llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Message-ID: <20100526000228.D44CB3128034@llvm.org> Author: sliao Date: Tue May 25 19:02:28 2010 New Revision: 104652 URL: http://llvm.org/viewvc/llvm-project?rev=104652&view=rev Log: To handle s* registers in emitVFPLoadStoreMultipleInstruction(). Fixing http://llvm.org/bugs/show_bug.cgi?id=7221. Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=104652&r1=104651&r2=104652&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Tue May 25 19:02:28 2010 @@ -146,11 +146,11 @@ return getMachineOpValue(MI, MI.getOperand(OpIdx)); } - /// getMovi32Value - Return binary encoding of operand for movw/movt. If the + /// getMovi32Value - Return binary encoding of operand for movw/movt. If the /// machine operand requires relocation, record the relocation and return zero. - unsigned getMovi32Value(const MachineInstr &MI,const MachineOperand &MO, + unsigned getMovi32Value(const MachineInstr &MI,const MachineOperand &MO, unsigned Reloc); - unsigned getMovi32Value(const MachineInstr &MI, unsigned OpIdx, + unsigned getMovi32Value(const MachineInstr &MI, unsigned OpIdx, unsigned Reloc) { return getMovi32Value(MI, MI.getOperand(OpIdx), Reloc); } @@ -227,12 +227,12 @@ return 0; } -/// getMovi32Value - Return binary encoding of operand for movw/movt. If the +/// getMovi32Value - Return binary encoding of operand for movw/movt. If the /// machine operand requires relocation, record the relocation and return zero. unsigned ARMCodeEmitter::getMovi32Value(const MachineInstr &MI, - const MachineOperand &MO, + const MachineOperand &MO, unsigned Reloc) { - assert(((Reloc == ARM::reloc_arm_movt) || (Reloc == ARM::reloc_arm_movw)) + assert(((Reloc == ARM::reloc_arm_movt) || (Reloc == ARM::reloc_arm_movw)) && "Relocation to this function should be for movt or movw"); if (MO.isImm()) @@ -1459,7 +1459,12 @@ break; ++NumRegs; } - Binary |= NumRegs * 2; + // Bit 8 will be set if is consecutive 64-bit registers (e.g., D0) + // Otherwise, it will be 0, in the case of 32-bit registers. + if(Binary & 0x100) + Binary |= NumRegs * 2; + else + Binary |= NumRegs; emitWordLE(Binary); } From sliao at google.com Tue May 25 19:11:05 2010 From: sliao at google.com (Shih-wei Liao) Date: Tue, 25 May 2010 17:11:05 -0700 Subject: [llvm-commits] [PATCH] To handle s* registers in emitVFPLoadStoreMultipleInstruction() In-Reply-To: References: Message-ID: 1. Fixed in r104652. 2. Passed "make check": === Summary === # of expected passes 3841 # of expected failures 24 make[1]: Leaving directory `/usr/local/google/upstream/llvm-obj/test' 3. Passed "make check-lit": Expected Passes : 4100 Expected Failures : 24 Unsupported Tests : 1184 make[1]: Leaving directory `/usr/local/google/upstream/llvm-obj/test' Thanks for the reviews. I'm learning the patching from you --- I called it arm-jit-*.patch to follow your style. On Tue, May 25, 2010 at 4:00 AM, Zonr Chang wrote: > I reviewed and tested this patch. Thanks for your hard working on reporting > and resolving the bug in ARM JIT. > LGTM. > > Zonr > > From: Shih-wei Liao >> Date: Tue, May 25, 2010 at 1:21 AM >> Subject: [PATCH] To handle s* registers in >> emitVFPLoadStoreMultipleInstruction() >> To: llvm-commits >> >> >> Could someone review the patch in >> http://llvm.org/bugs/show_bug.cgi?id=7221? >> >> --- lib/Target/ARM/ARMCodeEmitter.cpp >> +++ lib/Target/ARM/ARMCodeEmitter.cpp >> break; >> ++NumRegs; >> } >> - Binary |= NumRegs * 2; >> + // bit 8 will be set if is consecutive 64-bit registers (e.g., >> d0) >> + if(Binary & 0x100) >> + Binary |= NumRegs * 2; >> + else >> + Binary |= NumRegs; >> >> emitWordLE(Binary); >> } >> >> Thanks. >> > > -- Thanks, Shih-wei -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100525/0f09867c/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: arm-jit-vstm.patch Type: text/x-patch Size: 2088 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100525/0f09867c/attachment.bin From sliao at google.com Tue May 25 19:25:05 2010 From: sliao at google.com (Shih-wei Liao) Date: Wed, 26 May 2010 00:25:05 -0000 Subject: [llvm-commits] [llvm] r104653 - /llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Message-ID: <20100526002505.7DBA93128034@llvm.org> Author: sliao Date: Tue May 25 19:25:05 2010 New Revision: 104653 URL: http://llvm.org/viewvc/llvm-project?rev=104653&view=rev Log: Adding the missing implementation of Bitfield's "clear" and "insert". Fixing http://llvm.org/bugs/show_bug.cgi?id=7222. Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=104653&r1=104652&r2=104653&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Tue May 25 19:25:05 2010 @@ -781,10 +781,6 @@ unsigned ImplicitRn) { const TargetInstrDesc &TID = MI.getDesc(); - if (TID.Opcode == ARM::BFC) { - report_fatal_error("ARMv6t2 JIT is not yet supported."); - } - // Part of binary is determined by TableGn. unsigned Binary = getBinaryCodeForInstr(MI); @@ -820,6 +816,15 @@ Binary |= ((Hi16 >> 12) & 0xF) << 16; emitWordLE(Binary); return; + } else if((TID.Opcode == ARM::BFC) || (TID.Opcode == ARM::BFI)) { + uint32_t v = ~MI.getOperand(2).getImm(); + int32_t lsb = CountTrailingZeros_32(v); + int32_t msb = (32 - CountLeadingZeros_32(v)) - 1; + // Insts[20-16] = msb, Insts[11-7] = lsb + Binary |= (msb & 0x1F) << 16; + Binary |= (lsb & 0x1F) << 7; + emitWordLE(Binary); + return; } // If this is a two-address operand, skip it. e.g. MOVCCr operand 1. From sliao at google.com Tue May 25 19:28:50 2010 From: sliao at google.com (Shih-wei Liao) Date: Tue, 25 May 2010 17:28:50 -0700 Subject: [llvm-commits] [PATCH] To fix "report_fatal_error("ARMv6t2 JIT is not yet supported.")" In-Reply-To: <43B21FD4-7E86-4434-ABDA-B80BA26AD75A@apple.com> References: <43B21FD4-7E86-4434-ABDA-B80BA26AD75A@apple.com> Message-ID: 1. Fixed in r104653. 2. "make check" and "make check-lit" both return OK. 3. Attaching the up-to-date arm-jit-bfc-and-bfi.patch Thanks. On Tue, May 25, 2010 at 8:34 AM, Chris Lattner wrote: > > On May 25, 2010, at 4:36 AM, Zonr Chang wrote: > > I just reviewed this bug and tried your patch in the bug report. It works > and solve the problem. I make this patch in more formal form (see > attachement). > > It looks great. It reuses functions Count[Trailing|Leading]Zeros_32() just > like ARMAsmPrinter::printBitfieldInvMaskImmOperand() does to decode special > imm. encoded in BFC/BFI's MachineInstr. > LGTM. > > > Patch looks ok to me, plz commit. > > -Chris > > > Zonr > > > On Tue, May 25, 2010 at 7:12 PM, Shih-wei Liao wrote: > >> Bug 7222 (http://llvm.org/bugs/show_bug.cgi?id=7222) can be taken care >> of in a straightforward manner from the ARM Architecture Reference >> Manual. Could someone please examine the solution too? Thanks. >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> > > _______________________________________________ > > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > > -- Thanks, Shih-wei -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100525/a42da34f/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: arm-jit-bfc-and-bfi.patch Type: text/x-patch Size: 1086 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100525/a42da34f/attachment.bin From stoklund at 2pi.dk Tue May 25 19:28:19 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 26 May 2010 00:28:19 -0000 Subject: [llvm-commits] [llvm] r104654 - in /llvm/trunk: include/llvm/Target/Target.td lib/Target/ARM/ARMRegisterInfo.td lib/Target/Blackfin/BlackfinRegisterInfo.td lib/Target/MBlaze/MBlazeRegisterInfo.td lib/Target/MSP430/MSP430RegisterInfo.td lib/Target/Mips/MipsRegisterInfo.td lib/Target/PowerPC/PPCRegisterInfo.td lib/Target/Sparc/SparcRegisterInfo.td lib/Target/SystemZ/SystemZRegisterInfo.td lib/Target/X86/X86RegisterInfo.td utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <20100526002819.66FF13128034@llvm.org> Author: stoklund Date: Tue May 25 19:28:19 2010 New Revision: 104654 URL: http://llvm.org/viewvc/llvm-project?rev=104654&view=rev Log: Replace the SubRegSet tablegen class with a less error-prone mechanism. A Register with subregisters must also provide SubRegIndices for adressing the subregisters. TableGen automatically inherits indices for sub-subregisters to minimize typing. CompositeIndices may be specified for the weirder cases such as the XMM sub_sd index that returns the same register, and ARM NEON Q registers where both D subregs have ssub_0 and ssub_1 sub-subregs. It is now required that all subregisters are named by an index, and a future patch will also require inherited subregisters to be named. This is necessary to allow composite subregister indices to be reduced to a single index. Modified: llvm/trunk/include/llvm/Target/Target.td llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.td llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td llvm/trunk/lib/Target/X86/X86RegisterInfo.td llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Modified: llvm/trunk/include/llvm/Target/Target.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=104654&r1=104653&r2=104654&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/Target.td (original) +++ llvm/trunk/include/llvm/Target/Target.td Tue May 25 19:28:19 2010 @@ -54,6 +54,23 @@ // not [AX, AH, AL]. list SubRegs = []; + // SubRegIndices - For each register in SubRegs, specify the SubRegIndex used + // to address it. Sub-sub-register indices are automatically inherited from + // SubRegs. + list SubRegIndices = []; + + // CompositeIndices - Specify subreg indices that don't correspond directly to + // a register in SubRegs and are not inherited. The following formats are + // supported: + // + // (a) Identity - Reg:a == Reg + // (a b) Alias - Reg:a == Reg:b + // (a b,c) Composite - Reg:a == (Reg:b):c + // + // This can be used to disambiguate a sub-sub-register that exists in more + // than one subregister and other weird stuff. + list CompositeIndices = []; + // DwarfNumbers - Numbers used internally by gcc/gdb to identify the register. // These values can be determined by locating the .h file in the // directory llvmgcc/gcc/config// and looking for REGISTER_NAMES. The @@ -73,17 +90,6 @@ let SubRegs = subregs; } -// SubRegSet - This can be used to define a specific mapping of registers to -// indices, for use as named subregs of a particular physical register. Each -// register in 'subregs' becomes an addressable subregister at index 'n' of the -// corresponding register in 'regs'. -class SubRegSet regs, list subregs> { - SubRegIndex Index = n; - - list From = regs; - list To = subregs; -} - // RegisterClass - Now that all of the registers are defined, and aliases // between registers are defined, specify which registers belong to which // register classes. This also defines the default allocation order of Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td?rev=104654&r1=104653&r2=104654&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td Tue May 25 19:28:19 2010 @@ -86,6 +86,7 @@ def S30 : ARMFReg<30, "s30">; def S31 : ARMFReg<31, "s31">; // Aliases of the F* registers used to hold 64-bit fp values (doubles) +let SubRegIndices = [ssub_0, ssub_1] in { def D0 : ARMReg< 0, "d0", [S0, S1]>; def D1 : ARMReg< 1, "d1", [S2, S3]>; def D2 : ARMReg< 2, "d2", [S4, S5]>; @@ -102,6 +103,7 @@ def D13 : ARMReg<13, "d13", [S26, S27]>; def D14 : ARMReg<14, "d14", [S28, S29]>; def D15 : ARMReg<15, "d15", [S30, S31]>; +} // VFP3 defines 16 additional double registers def D16 : ARMFReg<16, "d16">; def D17 : ARMFReg<17, "d17">; @@ -114,6 +116,9 @@ def D30 : ARMFReg<30, "d30">; def D31 : ARMFReg<31, "d31">; // Advanced SIMD (NEON) defines 16 quad-word aliases +let SubRegIndices = [dsub_0, dsub_1], + CompositeIndices = [(ssub_2 dsub_1, ssub_0), + (ssub_3 dsub_1, ssub_1)] in { def Q0 : ARMReg< 0, "q0", [D0, D1]>; def Q1 : ARMReg< 1, "q1", [D2, D3]>; def Q2 : ARMReg< 2, "q2", [D4, D5]>; @@ -122,6 +127,8 @@ def Q5 : ARMReg< 5, "q5", [D10, D11]>; def Q6 : ARMReg< 6, "q6", [D12, D13]>; def Q7 : ARMReg< 7, "q7", [D14, D15]>; +} +let SubRegIndices = [dsub_0, dsub_1] in { def Q8 : ARMReg< 8, "q8", [D16, D17]>; def Q9 : ARMReg< 9, "q9", [D18, D19]>; def Q10 : ARMReg<10, "q10", [D20, D21]>; @@ -130,6 +137,7 @@ def Q13 : ARMReg<13, "q13", [D26, D27]>; def Q14 : ARMReg<14, "q14", [D28, D29]>; def Q15 : ARMReg<15, "q15", [D30, D31]>; +} // Pseudo 256-bit registers to represent pairs of Q registers. These should // never be present in the emitted code. @@ -138,6 +146,9 @@ // starting D register number doesn't have to be multiple of 4. e.g. // D1, D2, D3, D4 would be a legal quad. But that would make the sub-register // stuffs very messy. +let SubRegIndices = [qsub_0, qsub_1], + CompositeIndices = [(dsub_2 qsub_1, dsub_0), + (dsub_3 qsub_1, dsub_1)] in { def QQ0 : ARMReg<0, "qq0", [Q0, Q1]>; def QQ1 : ARMReg<1, "qq1", [Q2, Q3]>; def QQ2 : ARMReg<2, "qq2", [Q4, Q5]>; @@ -146,12 +157,21 @@ def QQ5 : ARMReg<5, "qq5", [Q10, Q11]>; def QQ6 : ARMReg<6, "qq6", [Q12, Q13]>; def QQ7 : ARMReg<7, "qq7", [Q14, Q15]>; +} // Pseudo 512-bit registers to represent four consecutive Q registers. +let SubRegIndices = [qqsub_0, qqsub_1], + CompositeIndices = [(qsub_2 qqsub_1, qsub_0), + (qsub_3 qqsub_1, qsub_1), + (dsub_4 qqsub_1, dsub_0), + (dsub_5 qqsub_1, dsub_1), + (dsub_6 qqsub_1, dsub_2), + (dsub_7 qqsub_1, dsub_3)] in { def QQQQ0 : ARMReg<0, "qqqq0", [QQ0, QQ1]>; def QQQQ1 : ARMReg<1, "qqqq1", [QQ2, QQ3]>; def QQQQ2 : ARMReg<2, "qqqq2", [QQ4, QQ5]>; def QQQQ3 : ARMReg<3, "qqqq3", [QQ6, QQ7]>; +} // Current Program Status Register. def CPSR : ARMReg<0, "cpsr">; @@ -438,102 +458,3 @@ // Condition code registers. def CCR : RegisterClass<"ARM", [i32], 32, [CPSR]>; -//===----------------------------------------------------------------------===// -// Subregister Set Definitions... now that we have all of the pieces, define the -// sub registers for each register. -// - -// S sub-registers of D registers. -def : SubRegSet; -def : SubRegSet; - -// S sub-registers of Q registers. -def : SubRegSet; -def : SubRegSet; -def : SubRegSet; -def : SubRegSet; - -// D sub-registers of Q registers. -def : SubRegSet; -def : SubRegSet; - -// S sub-registers of QQ registers. Note there are no sub-indices -// for referencing S4 - S7, S12 - S15, and S20 - S23. It doesn't -// look like we need them. -def : SubRegSet; -def : SubRegSet; -def : SubRegSet; -def : SubRegSet; - -// D sub-registers of QQ registers. -def : SubRegSet; -def : SubRegSet; -def : SubRegSet; -def : SubRegSet; - -// Q sub-registers of QQ registers. -def : SubRegSet; -def : SubRegSet; - - -// D sub-registers of QQQQ registers. -def : SubRegSet; -def : SubRegSet; -def : SubRegSet; -def : SubRegSet; - -def : SubRegSet; -def : SubRegSet; -def : SubRegSet; -def : SubRegSet; - -// Q sub-registers of QQQQ registers. -def : SubRegSet; -def : SubRegSet; -def : SubRegSet; -def : SubRegSet; - -// QQ sub-registers of QQQQ registers. -def : SubRegSet; -def : SubRegSet; - Modified: llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td?rev=104654&r1=104653&r2=104654&view=diff ============================================================================== --- llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td (original) +++ llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td Tue May 25 19:28:19 2010 @@ -19,6 +19,7 @@ def lo16 : SubRegIndex; def hi16 : SubRegIndex; def lo32 : SubRegIndex; +def hi32 : SubRegIndex; } // Registers are identified with 3-bit group and 3-bit ID numbers. @@ -49,6 +50,7 @@ // Ra 40-bit accumulator registers class Ra num, string n, list subs> : BlackfinReg { let SubRegs = subs; + let SubRegIndices = [hi32, lo32]; let Group = 4; let Num = num; } @@ -63,6 +65,7 @@ class Rii group, bits<3> num, string n, list subs> : BlackfinReg { let SubRegs = subs; + let SubRegIndices = [hi16, lo16]; let Group = group; let Num = num; } @@ -173,7 +176,7 @@ def RETE : Ri<7, 6, "rete">, DwarfRegNum<[39]>; def ASTAT : Ri<4, 6, "astat">, DwarfRegNum<[40]> { - let SubRegs = [AZ, AN, CC, NCC, AQ, AC0, AC1, AV0, AV0S, AV1, AV1S, V, VS]; + let Aliases = [AZ, AN, CC, NCC, AQ, AC0, AC1, AV0, AV0S, AV1, AV1S, V, VS]; } def SEQSTAT : Ri<7, 1, "seqstat">, DwarfRegNum<[41]>; @@ -191,29 +194,6 @@ def LB0 : Ri<6, 2, "lb0">, DwarfRegNum<[48]>; def LB1 : Ri<6, 5, "lb1">, DwarfRegNum<[49]>; -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; -def : SubRegSet; - // Register classes. def D16 : RegisterClass<"BF", [i16], 16, [R0H, R0L, R1H, R1L, R2H, R2L, R3H, R3L, Modified: llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.td?rev=104654&r1=104653&r2=104654&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.td (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.td Tue May 25 19:28:19 2010 @@ -17,21 +17,15 @@ let Namespace = "MBlaze"; } -class MBlazeRegWithSubRegs subregs> - : RegisterWithSubRegs { - field bits<5> Num; - let Namespace = "MBlaze"; -} - // MBlaze CPU Registers class MBlazeGPRReg num, string n> : MBlazeReg { let Num = num; } // MBlaze 32-bit (aliased) FPU Registers -class FPR num, string n, list subregs> - : MBlazeRegWithSubRegs { +class FPR num, string n, list aliases> : MBlazeReg { let Num = num; + let Aliases = aliases; } //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td?rev=104654&r1=104653&r2=104654&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td (original) +++ llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td Tue May 25 19:28:19 2010 @@ -43,6 +43,9 @@ def R14B : MSP430Reg<14, "r14">; def R15B : MSP430Reg<15, "r15">; +def subreg_8bit : SubRegIndex { let Namespace = "MSP430"; } + +let SubRegIndices = [subreg_8bit] in { def PCW : MSP430RegWithSubregs<0, "r0", [PCB]>; def SPW : MSP430RegWithSubregs<1, "r1", [SPB]>; def SRW : MSP430RegWithSubregs<2, "r2", [SRB]>; @@ -59,13 +62,7 @@ def R13W : MSP430RegWithSubregs<13, "r13", [R13B]>; def R14W : MSP430RegWithSubregs<14, "r14", [R14B]>; def R15W : MSP430RegWithSubregs<15, "r15", [R15B]>; - -def subreg_8bit : SubRegIndex { let Namespace = "MSP430"; } - -def : SubRegSet; +} def GR8 : RegisterClass<"MSP430", [i8], 8, // Volatile registers Modified: llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td?rev=104654&r1=104653&r2=104654&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td (original) +++ llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td Tue May 25 19:28:19 2010 @@ -34,9 +34,14 @@ } // Mips 64-bit (aliased) FPU Registers -class AFPR num, string n, list subregs> +let Namespace = "Mips" in { +def sub_fpeven : SubRegIndex; +def sub_fpodd : SubRegIndex; +} +class AFPR num, string n, list subregs> : MipsRegWithSubRegs { let Num = num; + let SubRegIndices = [sub_fpeven, sub_fpodd]; } //===----------------------------------------------------------------------===// @@ -141,25 +146,6 @@ } //===----------------------------------------------------------------------===// -// Subregister Set Definitions -//===----------------------------------------------------------------------===// - -let Namespace = "Mips" in { -def sub_fpeven : SubRegIndex; -def sub_fpodd : SubRegIndex; -} - -def : SubRegSet; - -def : SubRegSet; - -//===----------------------------------------------------------------------===// // Register Classes //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td?rev=104654&r1=104653&r2=104654&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td (original) +++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td Tue May 25 19:28:19 2010 @@ -10,6 +10,15 @@ // //===----------------------------------------------------------------------===// +let Namespace = "PPC" in { +def sub_lt : SubRegIndex; +def sub_gt : SubRegIndex; +def sub_eq : SubRegIndex; +def sub_un : SubRegIndex; +def sub_32 : SubRegIndex; +} + + class PPCReg : Register { let Namespace = "PPC"; } @@ -25,6 +34,7 @@ class GP8 : PPCReg { field bits<5> Num = SubReg.Num; let SubRegs = [SubReg]; + let SubRegIndices = [sub_32]; } // SPR - One of the 32-bit special-purpose registers @@ -225,6 +235,7 @@ def CR7UN : CRBIT<31, "31">, DwarfRegNum<[0]>; // Condition registers +let SubRegIndices = [sub_lt, sub_gt, sub_eq, sub_un] in { def CR0 : CR<0, "cr0", [CR0LT, CR0GT, CR0EQ, CR0UN]>, DwarfRegNum<[68]>; def CR1 : CR<1, "cr1", [CR1LT, CR1GT, CR1EQ, CR1UN]>, DwarfRegNum<[69]>; def CR2 : CR<2, "cr2", [CR2LT, CR2GT, CR2EQ, CR2UN]>, DwarfRegNum<[70]>; @@ -233,27 +244,8 @@ def CR5 : CR<5, "cr5", [CR5LT, CR5GT, CR5EQ, CR5UN]>, DwarfRegNum<[73]>; def CR6 : CR<6, "cr6", [CR6LT, CR6GT, CR6EQ, CR6UN]>, DwarfRegNum<[74]>; def CR7 : CR<7, "cr7", [CR7LT, CR7GT, CR7EQ, CR7UN]>, DwarfRegNum<[75]>; - -let Namespace = "PPC" in { -def sub_lt : SubRegIndex; -def sub_gt : SubRegIndex; -def sub_eq : SubRegIndex; -def sub_un : SubRegIndex; } -def : SubRegSet; -def : SubRegSet; -def : SubRegSet; -def : SubRegSet; - // Link register def LR : SPR<8, "lr">, DwarfRegNum<[65]>; //let Aliases = [LR] in Modified: llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td?rev=104654&r1=104653&r2=104654&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td (original) +++ llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td Tue May 25 19:28:19 2010 @@ -20,6 +20,11 @@ let Namespace = "SP"; } +let Namespace = "SP" in { +def sub_even : SubRegIndex; +def sub_odd : SubRegIndex; +} + // Registers are identified with 5-bit ID numbers. // Ri - 32-bit integer registers class Ri num, string n> : SparcReg { @@ -33,6 +38,7 @@ class Rd num, string n, list subregs> : SparcReg { let Num = num; let SubRegs = subregs; + let SubRegIndices = [sub_even, sub_odd]; } // Control Registers Modified: llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td?rev=104654&r1=104653&r2=104654&view=diff ============================================================================== --- llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td (original) +++ llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td Tue May 25 19:28:19 2010 @@ -53,6 +53,14 @@ field bits<4> Num = num; } +let Namespace = "SystemZ" in { +def subreg_32bit : SubRegIndex; +def subreg_even32 : SubRegIndex; +def subreg_odd32 : SubRegIndex; +def subreg_even : SubRegIndex; +def subreg_odd : SubRegIndex; +} + // General-purpose registers def R0W : GPR32< 0, "r0">, DwarfRegNum<[0]>; def R1W : GPR32< 1, "r1">, DwarfRegNum<[1]>; @@ -71,6 +79,7 @@ def R14W : GPR32<14, "r14">, DwarfRegNum<[14]>; def R15W : GPR32<15, "r15">, DwarfRegNum<[15]>; +let SubRegIndices = [subreg_32bit] in { def R0D : GPR64< 0, "r0", [R0W]>, DwarfRegNum<[0]>; def R1D : GPR64< 1, "r1", [R1W]>, DwarfRegNum<[1]>; def R2D : GPR64< 2, "r2", [R2W]>, DwarfRegNum<[2]>; @@ -87,8 +96,10 @@ def R13D : GPR64<13, "r13", [R13W]>, DwarfRegNum<[13]>; def R14D : GPR64<14, "r14", [R14W]>, DwarfRegNum<[14]>; def R15D : GPR64<15, "r15", [R15W]>, DwarfRegNum<[15]>; +} // Register pairs +let SubRegIndices = [subreg_even32, subreg_odd32] in { def R0P : GPR64< 0, "r0", [R0W, R1W], [R0D, R1D]>, DwarfRegNum<[0]>; def R2P : GPR64< 2, "r2", [R2W, R3W], [R2D, R3D]>, DwarfRegNum<[2]>; def R4P : GPR64< 4, "r4", [R4W, R5W], [R4D, R5D]>, DwarfRegNum<[4]>; @@ -97,7 +108,11 @@ def R10P : GPR64<10, "r10", [R10W, R11W], [R10D, R11D]>, DwarfRegNum<[10]>; def R12P : GPR64<12, "r12", [R12W, R13W], [R12D, R13D]>, DwarfRegNum<[12]>; def R14P : GPR64<14, "r14", [R14W, R15W], [R14D, R15D]>, DwarfRegNum<[14]>; +} +let SubRegIndices = [subreg_even, subreg_odd], + CompositeIndices = [(subreg_even32 subreg_even, subreg_32bit), + (subreg_odd32 subreg_odd, subreg_32bit)] in { def R0Q : GPR128< 0, "r0", [R0D, R1D], [R0P]>, DwarfRegNum<[0]>; def R2Q : GPR128< 2, "r2", [R2D, R3D], [R2P]>, DwarfRegNum<[2]>; def R4Q : GPR128< 4, "r4", [R4D, R5D], [R4P]>, DwarfRegNum<[4]>; @@ -106,6 +121,7 @@ def R10Q : GPR128<10, "r10", [R10D, R11D], [R10P]>, DwarfRegNum<[10]>; def R12Q : GPR128<12, "r12", [R12D, R13D], [R12P]>, DwarfRegNum<[12]>; def R14Q : GPR128<14, "r14", [R14D, R15D], [R14P]>, DwarfRegNum<[14]>; +} // Floating-point registers def F0S : FPRS< 0, "f0">, DwarfRegNum<[16]>; @@ -125,6 +141,7 @@ def F14S : FPRS<14, "f14">, DwarfRegNum<[30]>; def F15S : FPRS<15, "f15">, DwarfRegNum<[31]>; +let SubRegIndices = [subreg_32bit] in { def F0L : FPRL< 0, "f0", [F0S]>, DwarfRegNum<[16]>; def F1L : FPRL< 1, "f1", [F1S]>, DwarfRegNum<[17]>; def F2L : FPRL< 2, "f2", [F2S]>, DwarfRegNum<[18]>; @@ -141,41 +158,11 @@ def F13L : FPRL<13, "f13", [F13S]>, DwarfRegNum<[29]>; def F14L : FPRL<14, "f14", [F14S]>, DwarfRegNum<[30]>; def F15L : FPRL<15, "f15", [F15S]>, DwarfRegNum<[31]>; +} // Status register def PSW : SystemZReg<"psw">; -let Namespace = "SystemZ" in { -def subreg_32bit : SubRegIndex; -def subreg_even32 : SubRegIndex; -def subreg_odd32 : SubRegIndex; -def subreg_even : SubRegIndex; -def subreg_odd : SubRegIndex; -} - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - /// Register classes def GR32 : RegisterClass<"SystemZ", [i32], 32, // Volatile registers Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.td?rev=104654&r1=104653&r2=104654&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.td Tue May 25 19:28:19 2010 @@ -68,17 +68,22 @@ def BH : Register<"bh">, DwarfRegNum<[3, 3, 3]>; // 16-bit registers + let SubRegIndices = [sub_8bit, sub_8bit_hi] in { def AX : RegisterWithSubRegs<"ax", [AL,AH]>, DwarfRegNum<[0, 0, 0]>; def DX : RegisterWithSubRegs<"dx", [DL,DH]>, DwarfRegNum<[1, 2, 2]>; def CX : RegisterWithSubRegs<"cx", [CL,CH]>, DwarfRegNum<[2, 1, 1]>; def BX : RegisterWithSubRegs<"bx", [BL,BH]>, DwarfRegNum<[3, 3, 3]>; + } + let SubRegIndices = [sub_8bit] in { def SI : RegisterWithSubRegs<"si", [SIL]>, DwarfRegNum<[4, 6, 6]>; def DI : RegisterWithSubRegs<"di", [DIL]>, DwarfRegNum<[5, 7, 7]>; def BP : RegisterWithSubRegs<"bp", [BPL]>, DwarfRegNum<[6, 4, 5]>; def SP : RegisterWithSubRegs<"sp", [SPL]>, DwarfRegNum<[7, 5, 4]>; + } def IP : Register<"ip">, DwarfRegNum<[16]>; // X86-64 only + let SubRegIndices = [sub_8bit] in { def R8W : RegisterWithSubRegs<"r8w", [R8B]>, DwarfRegNum<[8, -2, -2]>; def R9W : RegisterWithSubRegs<"r9w", [R9B]>, DwarfRegNum<[9, -2, -2]>; def R10W : RegisterWithSubRegs<"r10w", [R10B]>, DwarfRegNum<[10, -2, -2]>; @@ -87,8 +92,9 @@ def R13W : RegisterWithSubRegs<"r13w", [R13B]>, DwarfRegNum<[13, -2, -2]>; def R14W : RegisterWithSubRegs<"r14w", [R14B]>, DwarfRegNum<[14, -2, -2]>; def R15W : RegisterWithSubRegs<"r15w", [R15B]>, DwarfRegNum<[15, -2, -2]>; - + } // 32-bit registers + let SubRegIndices = [sub_16bit] in { def EAX : RegisterWithSubRegs<"eax", [AX]>, DwarfRegNum<[0, 0, 0]>; def EDX : RegisterWithSubRegs<"edx", [DX]>, DwarfRegNum<[1, 2, 2]>; def ECX : RegisterWithSubRegs<"ecx", [CX]>, DwarfRegNum<[2, 1, 1]>; @@ -108,8 +114,10 @@ def R13D : RegisterWithSubRegs<"r13d", [R13W]>, DwarfRegNum<[13, -2, -2]>; def R14D : RegisterWithSubRegs<"r14d", [R14W]>, DwarfRegNum<[14, -2, -2]>; def R15D : RegisterWithSubRegs<"r15d", [R15W]>, DwarfRegNum<[15, -2, -2]>; + } // 64-bit registers, X86-64 only + let SubRegIndices = [sub_32bit] in { def RAX : RegisterWithSubRegs<"rax", [EAX]>, DwarfRegNum<[0, -2, -2]>; def RDX : RegisterWithSubRegs<"rdx", [EDX]>, DwarfRegNum<[1, -2, -2]>; def RCX : RegisterWithSubRegs<"rcx", [ECX]>, DwarfRegNum<[2, -2, -2]>; @@ -128,6 +136,7 @@ def R14 : RegisterWithSubRegs<"r14", [R14D]>, DwarfRegNum<[14, -2, -2]>; def R15 : RegisterWithSubRegs<"r15", [R15D]>, DwarfRegNum<[15, -2, -2]>; def RIP : RegisterWithSubRegs<"rip", [EIP]>, DwarfRegNum<[16, -2, -2]>; + } // MMX Registers. These are actually aliased to ST0 .. ST7 def MM0 : Register<"mm0">, DwarfRegNum<[41, 29, 29]>; @@ -148,7 +157,9 @@ def FP5 : Register<"fp5">; def FP6 : Register<"fp6">; - // XMM Registers, used by the various SSE instruction set extensions + // XMM Registers, used by the various SSE instruction set extensions. + // The sub_ss and sub_sd subregs are the same registers with another regclass. + let CompositeIndices = [(sub_ss), (sub_sd)] in { def XMM0: Register<"xmm0">, DwarfRegNum<[17, 21, 21]>; def XMM1: Register<"xmm1">, DwarfRegNum<[18, 22, 22]>; def XMM2: Register<"xmm2">, DwarfRegNum<[19, 23, 23]>; @@ -167,8 +178,10 @@ def XMM13: Register<"xmm13">, DwarfRegNum<[30, -2, -2]>; def XMM14: Register<"xmm14">, DwarfRegNum<[31, -2, -2]>; def XMM15: Register<"xmm15">, DwarfRegNum<[32, -2, -2]>; + } // YMM Registers, used by AVX instructions + let SubRegIndices = [sub_xmm] in { def YMM0: RegisterWithSubRegs<"ymm0", [XMM0]>, DwarfRegNum<[17, 21, 21]>; def YMM1: RegisterWithSubRegs<"ymm1", [XMM1]>, DwarfRegNum<[18, 22, 22]>; def YMM2: RegisterWithSubRegs<"ymm2", [XMM2]>, DwarfRegNum<[19, 23, 23]>; @@ -185,6 +198,7 @@ def YMM13: RegisterWithSubRegs<"ymm13", [XMM13]>, DwarfRegNum<[30, -2, -2]>; def YMM14: RegisterWithSubRegs<"ymm14", [XMM14]>, DwarfRegNum<[31, -2, -2]>; def YMM15: RegisterWithSubRegs<"ymm15", [XMM15]>, DwarfRegNum<[32, -2, -2]>; + } // Floating point stack registers def ST0 : Register<"st(0)">, DwarfRegNum<[33, 12, 11]>; @@ -231,75 +245,6 @@ //===----------------------------------------------------------------------===// -// Subregister Set Definitions... now that we have all of the pieces, define the -// sub registers for each register. -// - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -//===----------------------------------------------------------------------===// // Register Class Definitions... now that we have all of the pieces, define the // top-level register classes. The order specified in the register list is // implicitly defined to be the register allocation order. Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp?rev=104654&r1=104653&r2=104654&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Tue May 25 19:28:19 2010 @@ -171,6 +171,67 @@ addSubSuperReg(R, *I, SubRegs, SuperRegs, Aliases); } +// Map SubRegIndex -> Register +typedef std::map SubRegMap; +// Map Register -> SubRegMap +typedef std::map AllSubRegMap; + +// Calculate all subregindices for Reg. Loopy subregs cause infinite recursion. +static SubRegMap &inferSubRegIndices(Record *Reg, AllSubRegMap &ASRM) { + SubRegMap &SRM = ASRM[Reg]; + if (!SRM.empty()) + return SRM; + std::vector SubRegs = Reg->getValueAsListOfDefs("SubRegs"); + std::vector Indices = Reg->getValueAsListOfDefs("SubRegIndices"); + if (SubRegs.size() != Indices.size()) + throw "Register " + Reg->getName() + " SubRegIndices doesn't match SubRegs"; + + // First insert the direct subregs. + for (unsigned i = 0, e = SubRegs.size(); i != e; ++i) { + if (!SRM.insert(std::make_pair(Indices[i], SubRegs[i])).second) + throw "SubRegIndex " + Indices[i]->getName() + + " appears twice in Register " + Reg->getName(); + inferSubRegIndices(SubRegs[i], ASRM); + } + + // Clone inherited subregs. Here the order is important - earlier subregs take + // precedence. + for (unsigned i = 0, e = SubRegs.size(); i != e; ++i) { + SubRegMap &M = ASRM[SubRegs[i]]; + SRM.insert(M.begin(), M.end()); + } + + // Finally process the composites. + ListInit *Comps = Reg->getValueAsListInit("CompositeIndices"); + for (unsigned i = 0, e = Comps->size(); i != e; ++i) { + DagInit *Pat = dynamic_cast(Comps->getElement(i)); + if (!Pat) + throw "Invalid dag '" + Comps->getElement(i)->getAsString() + + "' in CompositeIndices"; + DefInit *BaseIdxInit = dynamic_cast(Pat->getOperator()); + if (!BaseIdxInit || !BaseIdxInit->getDef()->isSubClassOf("SubRegIndex")) + throw "Invalid SubClassIndex in " + Pat->getAsString(); + + // Resolve list of subreg indices into R2. + Record *R2 = Reg; + for (DagInit::const_arg_iterator di = Pat->arg_begin(), + de = Pat->arg_end(); di != de; ++di) { + DefInit *IdxInit = dynamic_cast(*di); + if (!IdxInit || !IdxInit->getDef()->isSubClassOf("SubRegIndex")) + throw "Invalid SubClassIndex in " + Pat->getAsString(); + SubRegMap::const_iterator ni = ASRM[R2].find(IdxInit->getDef()); + if (ni == ASRM[R2].end()) + throw "Composite " + Pat->getAsString() + " refers to bad index in " + + R2->getName(); + R2 = ni->second; + } + + // Insert composite index. Allow overriding inherited indices etc. + SRM[BaseIdxInit->getDef()] = R2; + } + return SRM; +} + class RegisterSorter { private: std::map, LessRecord> &RegisterSubRegs; @@ -455,8 +516,6 @@ std::map, LessRecord> RegisterSubRegs; std::map, LessRecord> RegisterSuperRegs; std::map, LessRecord> RegisterAliases; - // Register -> [(SubRegIndex, Register)] - std::map > > SubRegVectors; typedef std::map, LessRecord> DwarfRegNumsMapTy; DwarfRegNumsMapTy DwarfRegNums; @@ -748,56 +807,44 @@ std::string ClassName = Target.getName() + "GenRegisterInfo"; // Calculate the mapping of subregister+index pairs to physical registers. - std::vector SubRegs = Records.getAllDerivedDefinitions("SubRegSet"); - for (unsigned i = 0, e = SubRegs.size(); i != e; ++i) { - Record *subRegIndex = SubRegs[i]->getValueAsDef("Index"); - std::vector From = SubRegs[i]->getValueAsListOfDefs("From"); - std::vector To = SubRegs[i]->getValueAsListOfDefs("To"); - - if (From.size() != To.size()) { - errs() << "Error: register list and sub-register list not of equal length" - << " in SubRegSet\n"; - exit(1); - } - - // For each entry in from/to vectors, insert the to register at index - for (unsigned ii = 0, ee = From.size(); ii != ee; ++ii) - SubRegVectors[From[ii]].push_back(std::make_pair(subRegIndex, To[ii])); - } - + AllSubRegMap AllSRM; + // Emit the subregister + index mapping function based on the information // calculated above. - OS << "unsigned " << ClassName + OS << "unsigned " << ClassName << "::getSubReg(unsigned RegNo, unsigned Index) const {\n" << " switch (RegNo) {\n" << " default:\n return 0;\n"; - for (std::map > >::iterator - I = SubRegVectors.begin(), E = SubRegVectors.end(); I != E; ++I) { - OS << " case " << getQualifiedName(I->first) << ":\n"; + for (unsigned i = 0, e = Regs.size(); i != e; ++i) { + SubRegMap &SRM = inferSubRegIndices(Regs[i].TheDef, AllSRM); + if (SRM.empty()) + continue; + OS << " case " << getQualifiedName(Regs[i].TheDef) << ":\n"; OS << " switch (Index) {\n"; OS << " default: return 0;\n"; - for (unsigned i = 0, e = I->second.size(); i != e; ++i) - OS << " case " - << getQualifiedName((I->second)[i].first) << ": return " - << getQualifiedName((I->second)[i].second) << ";\n"; + for (SubRegMap::const_iterator ii = SRM.begin(), ie = SRM.end(); ii != ie; + ++ii) + OS << " case " << getQualifiedName(ii->first) + << ": return " << getQualifiedName(ii->second) << ";\n"; OS << " };\n" << " break;\n"; } OS << " };\n"; OS << " return 0;\n"; OS << "}\n\n"; - OS << "unsigned " << ClassName + OS << "unsigned " << ClassName << "::getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const {\n" << " switch (RegNo) {\n" << " default:\n return 0;\n"; - for (std::map > >::iterator - I = SubRegVectors.begin(), E = SubRegVectors.end(); I != E; ++I) { - OS << " case " << getQualifiedName(I->first) << ":\n"; - for (unsigned i = 0, e = I->second.size(); i != e; ++i) - OS << " if (SubRegNo == " - << getQualifiedName((I->second)[i].second) - << ") return " - << getQualifiedName((I->second)[i].first) << ";\n"; + for (unsigned i = 0, e = Regs.size(); i != e; ++i) { + SubRegMap &SRM = AllSRM[Regs[i].TheDef]; + if (SRM.empty()) + continue; + OS << " case " << getQualifiedName(Regs[i].TheDef) << ":\n"; + for (SubRegMap::const_iterator ii = SRM.begin(), ie = SRM.end(); ii != ie; + ++ii) + OS << " if (SubRegNo == " << getQualifiedName(ii->second) + << ") return " << getQualifiedName(ii->first) << ";\n"; OS << " return 0;\n"; } OS << " };\n"; From isanbard at gmail.com Tue May 25 19:32:40 2010 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 26 May 2010 00:32:40 -0000 Subject: [llvm-commits] [llvm] r104655 - in /llvm/trunk: include/llvm/CodeGen/MachineFunction.h lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp lib/CodeGen/StackSlotColoring.cpp Message-ID: <20100526003240.50F833128034@llvm.org> Author: void Date: Tue May 25 19:32:40 2010 New Revision: 104655 URL: http://llvm.org/viewvc/llvm-project?rev=104655&view=rev Log: Dale and Evan suggested putting the "check for setjmp" much earlier in the machine code generation. That's a good idea, so I made it so. Modified: llvm/trunk/include/llvm/CodeGen/MachineFunction.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Modified: llvm/trunk/include/llvm/CodeGen/MachineFunction.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineFunction.h?rev=104655&r1=104654&r2=104655&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineFunction.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineFunction.h Tue May 25 19:32:40 2010 @@ -114,9 +114,13 @@ /// unsigned FunctionNumber; - /// The alignment of the function. + /// Alignment - The alignment of the function. unsigned Alignment; + /// HasReturnsTwiceCall - Returns true if there's a call with a + /// "returns_twice" attribute, like setjmp. + bool HasReturnsTwiceCall; + MachineFunction(const MachineFunction &); // DO NOT IMPLEMENT void operator=(const MachineFunction&); // DO NOT IMPLEMENT public: @@ -181,6 +185,15 @@ void EnsureAlignment(unsigned A) { if (Alignment < A) Alignment = A; } + + /// hasReturnsTwiceCall - Returns true if there's a call with a + /// "returns_twice" attribute, like setjmp. + bool hasReturnsTwiceCall() const { + return HasReturnsTwiceCall; + } + void setReturnsTwiceCall(bool B) { + HasReturnsTwiceCall = B; + } /// getInfo - Keep track of various per-function pieces of information for /// backends that would like to do so. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=104655&r1=104654&r2=104655&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue May 25 19:32:40 2010 @@ -25,6 +25,7 @@ #include "llvm/Intrinsics.h" #include "llvm/IntrinsicInst.h" #include "llvm/LLVMContext.h" +#include "llvm/Module.h" #include "llvm/CodeGen/FastISel.h" #include "llvm/CodeGen/GCStrategy.h" #include "llvm/CodeGen/GCMetadata.h" @@ -253,6 +254,39 @@ done:; } + // Set a flag indicating if the machine function makes a call to setjmp / + // sigsetjmp (i.e., a function marked "returns_twice"). We'll use this to + // disable certain optimizations which cannot handle such control flows. + // + // FIXME: This goes beyond the setjmp/sigsetjmp functions. We should check for + // the GCC "returns twice" attribute. + const Module *M = Fn.getParent(); + const Function *SetJmp = M->getFunction("setjmp"); + const Function *SigSetJmp = M->getFunction("sigsetjmp"); + bool HasReturnsTwiceCall = false; + + if (SetJmp || SigSetJmp) { + if (SetJmp && !SetJmp->use_empty()) + for (Value::const_use_iterator + I = SetJmp->use_begin(), E = SetJmp->use_end(); I != E; ++I) + if (const CallInst *CI = dyn_cast(I)) + if (CI->getParent()->getParent() == &Fn) { + HasReturnsTwiceCall = true; + break; + } + + if (!HasReturnsTwiceCall && SigSetJmp && !SigSetJmp->use_empty()) + for (Value::const_use_iterator + I = SigSetJmp->use_begin(), E = SigSetJmp->use_end(); I != E; ++I) + if (const CallInst *CI = dyn_cast(I)) + if (CI->getParent()->getParent() == &Fn) { + HasReturnsTwiceCall = true; + break; + } + + mf.setReturnsTwiceCall(HasReturnsTwiceCall); + } + // Release function-specific state. SDB and CurDAG are already cleared // at this point. FuncInfo->clear(); Modified: llvm/trunk/lib/CodeGen/StackSlotColoring.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackSlotColoring.cpp?rev=104655&r1=104654&r2=104655&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StackSlotColoring.cpp (original) +++ llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Tue May 25 19:32:40 2010 @@ -118,7 +118,6 @@ private: void InitializeSlots(); - bool CheckForSetJmpCall(const MachineFunction &MF) const; void ScanForSpillSlotRefs(MachineFunction &MF); bool OverlapWithAssignments(LiveInterval *li, int Color) const; int ColorSlot(LiveInterval *li); @@ -162,34 +161,6 @@ }; } -/// CheckForSetJmpCall - Return true if there's a call to setjmp/sigsetjmp in -/// this function. -bool StackSlotColoring::CheckForSetJmpCall(const MachineFunction &MF) const { - const Function *F = MF.getFunction(); - const Module *M = F->getParent(); - const Function *SetJmp = M->getFunction("setjmp"); - const Function *SigSetJmp = M->getFunction("sigsetjmp"); - - if (!SetJmp && !SigSetJmp) - return false; - - if (SetJmp && !SetJmp->use_empty()) - for (Value::const_use_iterator - I = SetJmp->use_begin(), E = SetJmp->use_end(); I != E; ++I) - if (const CallInst *CI = dyn_cast(I)) - if (CI->getParent()->getParent() == F) - return true; - - if (SigSetJmp && !SigSetJmp->use_empty()) - for (Value::const_use_iterator - I = SigSetJmp->use_begin(), E = SigSetJmp->use_end(); I != E; ++I) - if (const CallInst *CI = dyn_cast(I)) - if (CI->getParent()->getParent() == F) - return true; - - return false; -} - /// ScanForSpillSlotRefs - Scan all the machine instructions for spill slot /// references and update spill slot weights. void StackSlotColoring::ScanForSpillSlotRefs(MachineFunction &MF) { @@ -753,14 +724,11 @@ return false; } - // If there are calls to setjmp or sigsetjmp, don't perform stack slot - // coloring. The stack could be modified before the longjmp is executed, - // resulting in the wrong value being used afterwards. (See - // .) - // - // FIXME: This goes beyond the setjmp/sigsetjmp functions. Ideally, we should - // check for the GCC "returns twice" attribute. - if (CheckForSetJmpCall(MF)) + // If there is a call to a function with the attribute "returns_twice" (like + // setjmp or sigsetjmp), don't perform stack slot coloring. The stack could be + // modified before the the second return, resulting in the wrong value being + // used afterwards. (See .) + if (MF.hasReturnsTwiceCall()) return false; // Gather spill slot references From gohman at apple.com Tue May 25 19:55:59 2010 From: gohman at apple.com (Dan Gohman) Date: Wed, 26 May 2010 00:55:59 -0000 Subject: [llvm-commits] [llvm] r104657 - /llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <20100526005559.B3CCE3128034@llvm.org> Author: djg Date: Tue May 25 19:55:59 2010 New Revision: 104657 URL: http://llvm.org/viewvc/llvm-project?rev=104657&view=rev Log: Trim #include. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp?rev=104657&r1=104656&r2=104657&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Tue May 25 19:55:59 2010 @@ -30,7 +30,6 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/ADT/PriorityQueue.h" #include "llvm/ADT/Statistic.h" #include using namespace llvm; From gohman at apple.com Tue May 25 19:56:27 2010 From: gohman at apple.com (Dan Gohman) Date: Wed, 26 May 2010 00:56:27 -0000 Subject: [llvm-commits] [llvm] r104658 - in /llvm/trunk/include/llvm/CodeGen: LatencyPriorityQueue.h ScheduleDAG.h Message-ID: <20100526005628.097DF3128034@llvm.org> Author: djg Date: Tue May 25 19:56:27 2010 New Revision: 104658 URL: http://llvm.org/viewvc/llvm-project?rev=104658&view=rev Log: Delete an unused function. Modified: llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Modified: llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h?rev=104658&r1=104657&r2=104658&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h (original) +++ llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h Tue May 25 19:56:27 2010 @@ -73,8 +73,6 @@ return NumNodesSolelyBlocking[NodeNum]; } - unsigned size() const { return Queue.size(); } - bool empty() const { return Queue.empty(); } virtual void push(SUnit *U) { Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=104658&r1=104657&r2=104658&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Tue May 25 19:56:27 2010 @@ -424,7 +424,6 @@ virtual void updateNode(const SUnit *SU) = 0; virtual void releaseState() = 0; - virtual unsigned size() const = 0; virtual bool empty() const = 0; virtual void push(SUnit *U) = 0; From sliao at google.com Tue May 25 19:59:39 2010 From: sliao at google.com (Shih-wei Liao) Date: Tue, 25 May 2010 17:59:39 -0700 Subject: [llvm-commits] [PATCH] [ARM JIT] To fix the missing implementation of ARM::UBFX and ARM::SBFX Message-ID: Attached is the patch that will fix the bug http://llvm.org/bugs/show_bug.cgi?id=7225. The patch passed "make check-lit" and "make check". Could someone please review it? Thanks. -- Thanks, Shih-wei -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100525/1e0e96ed/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: arm-jit-ubfx-sbfx.patch Type: text/x-patch Size: 803 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100525/1e0e96ed/attachment.bin From xuzhongxing at gmail.com Tue May 25 20:02:33 2010 From: xuzhongxing at gmail.com (Zhongxing Xu) Date: Wed, 26 May 2010 09:02:33 +0800 Subject: [llvm-commits] [PATCH] No need to check SRetReturnReg again In-Reply-To: <4BFBDA2C.6060508@free.fr> References: <4BFBDA2C.6060508@free.fr> Message-ID: It hasn't been applied. Is it okay to apply? On Tue, May 25, 2010 at 10:09 PM, Duncan Sands wrote: > Hi Zhongxing Xu, this looks ok to me. Was it applied? > > Ciao, > > Duncan. > > > ping? > > > > The reason of this change is that in LowerFormalArguments() we have: > > > > if (Is64Bit && MF.getFunction()->hasStructRetAttr()) { > > X86MachineFunctionInfo *FuncInfo = > > MF.getInfo(); > > unsigned Reg = FuncInfo->getSRetReturnReg(); > > if (!Reg) { > > Reg = > > MF.getRegInfo().createVirtualRegister(getRegClassFor(MVT::i64)); > > FuncInfo->setSRetReturnReg(Reg); > > } > > SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), dl, Reg, > > InVals[0]); > > Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Copy, Chain); > > } > > > > On Fri, May 21, 2010 at 3:45 PM, Zhongxing Xu > > wrote: > > > > Index: lib/Target/X86/X86ISelLowering.cpp > > =================================================================== > > --- lib/Target/X86/X86ISelLowering.cpp (?? 104313) > > +++ lib/Target/X86/X86ISelLowering.cpp (????) > > @@ -1256,10 +1256,8 @@ > > MachineFunction &MF = DAG.getMachineFunction(); > > X86MachineFunctionInfo *FuncInfo = > > MF.getInfo(); > > unsigned Reg = FuncInfo->getSRetReturnReg(); > > - if (!Reg) { > > - Reg = MRI.createVirtualRegister(getRegClassFor(MVT::i64)); > > - FuncInfo->setSRetReturnReg(Reg); > > - } > > + assert(Reg && > > + "SRetReturnReg should have been set in LowerFormalArguments()."); > > SDValue Val = DAG.getCopyFromReg(Chain, dl, Reg, > getPointerTy()); > > > > Chain = DAG.getCopyToReg(Chain, dl, X86::RAX, Val, Flag); > > > > > > > > > > _______________________________________________ > > llvm-commits mailing list > > llvm-commits at cs.uiuc.edu > > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100526/eb4bf190/attachment.html From gohman at apple.com Tue May 25 20:10:55 2010 From: gohman at apple.com (Dan Gohman) Date: Wed, 26 May 2010 01:10:55 -0000 Subject: [llvm-commits] [llvm] r104659 - in /llvm/trunk: include/llvm/CodeGen/LatencyPriorityQueue.h include/llvm/CodeGen/ScheduleDAG.h lib/CodeGen/LatencyPriorityQueue.cpp lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Message-ID: <20100526011055.B78C03128042@llvm.org> Author: djg Date: Tue May 25 20:10:55 2010 New Revision: 104659 URL: http://llvm.org/viewvc/llvm-project?rev=104659&view=rev Log: Change push_all to a non-virtual function and implement it in the base class, since all the implementations are the same. Modified: llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h?rev=104659&r1=104658&r2=104659&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h (original) +++ llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h Tue May 25 20:10:55 2010 @@ -75,15 +75,7 @@ bool empty() const { return Queue.empty(); } - virtual void push(SUnit *U) { - push_impl(U); - } - void push_impl(SUnit *U); - - void push_all(const std::vector &Nodes) { - for (unsigned i = 0, e = Nodes.size(); i != e; ++i) - push_impl(Nodes[i]); - } + virtual void push(SUnit *U); SUnit *pop() { if (empty()) return NULL; Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=104659&r1=104658&r2=104659&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Tue May 25 20:10:55 2010 @@ -427,7 +427,12 @@ virtual bool empty() const = 0; virtual void push(SUnit *U) = 0; - virtual void push_all(const std::vector &Nodes) = 0; + void push_all(const std::vector &Nodes) { + for (std::vector::const_iterator I = Nodes.begin(), + E = Nodes.end(); I != E; ++I) + push(*I); + } + virtual SUnit *pop() = 0; virtual void remove(SUnit *SU) = 0; Modified: llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp?rev=104659&r1=104658&r2=104659&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp (original) +++ llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp Tue May 25 20:10:55 2010 @@ -68,7 +68,7 @@ return OnlyAvailablePred; } -void LatencyPriorityQueue::push_impl(SUnit *SU) { +void LatencyPriorityQueue::push(SUnit *SU) { // Look at all of the successors of this node. Count the number of nodes that // this node is the sole unscheduled node for. unsigned NumNodesBlocking = 0; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=104659&r1=104658&r2=104659&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Tue May 25 20:10:55 2010 @@ -1115,11 +1115,6 @@ Queue.push(U); } - void push_all(const std::vector &Nodes) { - for (unsigned i = 0, e = Nodes.size(); i != e; ++i) - push(Nodes[i]); - } - SUnit *pop() { if (empty()) return NULL; SUnit *V = Queue.top(); From stoklund at 2pi.dk Tue May 25 20:21:14 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 26 May 2010 01:21:14 -0000 Subject: [llvm-commits] [llvm] r104660 - in /llvm/trunk: include/llvm/Target/Target.td lib/Target/ARM/ARMRegisterInfo.td lib/Target/Blackfin/BlackfinRegisterInfo.td lib/Target/MBlaze/MBlazeRegisterInfo.td lib/Target/MSP430/MSP430RegisterInfo.td lib/Target/Mips/MipsRegisterInfo.td lib/Target/PowerPC/PPCRegisterInfo.td lib/Target/Sparc/SparcRegisterInfo.td lib/Target/SystemZ/SystemZRegisterInfo.td lib/Target/X86/X86RegisterInfo.td utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <20100526012115.18DA53128042@llvm.org> Author: stoklund Date: Tue May 25 20:21:14 2010 New Revision: 104660 URL: http://llvm.org/viewvc/llvm-project?rev=104660&view=rev Log: Revert "Replace the SubRegSet tablegen class with a less error-prone mechanism." This reverts commit 104654. Modified: llvm/trunk/include/llvm/Target/Target.td llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.td llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td llvm/trunk/lib/Target/X86/X86RegisterInfo.td llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Modified: llvm/trunk/include/llvm/Target/Target.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=104660&r1=104659&r2=104660&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/Target.td (original) +++ llvm/trunk/include/llvm/Target/Target.td Tue May 25 20:21:14 2010 @@ -54,23 +54,6 @@ // not [AX, AH, AL]. list SubRegs = []; - // SubRegIndices - For each register in SubRegs, specify the SubRegIndex used - // to address it. Sub-sub-register indices are automatically inherited from - // SubRegs. - list SubRegIndices = []; - - // CompositeIndices - Specify subreg indices that don't correspond directly to - // a register in SubRegs and are not inherited. The following formats are - // supported: - // - // (a) Identity - Reg:a == Reg - // (a b) Alias - Reg:a == Reg:b - // (a b,c) Composite - Reg:a == (Reg:b):c - // - // This can be used to disambiguate a sub-sub-register that exists in more - // than one subregister and other weird stuff. - list CompositeIndices = []; - // DwarfNumbers - Numbers used internally by gcc/gdb to identify the register. // These values can be determined by locating the .h file in the // directory llvmgcc/gcc/config// and looking for REGISTER_NAMES. The @@ -90,6 +73,17 @@ let SubRegs = subregs; } +// SubRegSet - This can be used to define a specific mapping of registers to +// indices, for use as named subregs of a particular physical register. Each +// register in 'subregs' becomes an addressable subregister at index 'n' of the +// corresponding register in 'regs'. +class SubRegSet regs, list subregs> { + SubRegIndex Index = n; + + list From = regs; + list To = subregs; +} + // RegisterClass - Now that all of the registers are defined, and aliases // between registers are defined, specify which registers belong to which // register classes. This also defines the default allocation order of Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td?rev=104660&r1=104659&r2=104660&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td Tue May 25 20:21:14 2010 @@ -86,7 +86,6 @@ def S30 : ARMFReg<30, "s30">; def S31 : ARMFReg<31, "s31">; // Aliases of the F* registers used to hold 64-bit fp values (doubles) -let SubRegIndices = [ssub_0, ssub_1] in { def D0 : ARMReg< 0, "d0", [S0, S1]>; def D1 : ARMReg< 1, "d1", [S2, S3]>; def D2 : ARMReg< 2, "d2", [S4, S5]>; @@ -103,7 +102,6 @@ def D13 : ARMReg<13, "d13", [S26, S27]>; def D14 : ARMReg<14, "d14", [S28, S29]>; def D15 : ARMReg<15, "d15", [S30, S31]>; -} // VFP3 defines 16 additional double registers def D16 : ARMFReg<16, "d16">; def D17 : ARMFReg<17, "d17">; @@ -116,9 +114,6 @@ def D30 : ARMFReg<30, "d30">; def D31 : ARMFReg<31, "d31">; // Advanced SIMD (NEON) defines 16 quad-word aliases -let SubRegIndices = [dsub_0, dsub_1], - CompositeIndices = [(ssub_2 dsub_1, ssub_0), - (ssub_3 dsub_1, ssub_1)] in { def Q0 : ARMReg< 0, "q0", [D0, D1]>; def Q1 : ARMReg< 1, "q1", [D2, D3]>; def Q2 : ARMReg< 2, "q2", [D4, D5]>; @@ -127,8 +122,6 @@ def Q5 : ARMReg< 5, "q5", [D10, D11]>; def Q6 : ARMReg< 6, "q6", [D12, D13]>; def Q7 : ARMReg< 7, "q7", [D14, D15]>; -} -let SubRegIndices = [dsub_0, dsub_1] in { def Q8 : ARMReg< 8, "q8", [D16, D17]>; def Q9 : ARMReg< 9, "q9", [D18, D19]>; def Q10 : ARMReg<10, "q10", [D20, D21]>; @@ -137,7 +130,6 @@ def Q13 : ARMReg<13, "q13", [D26, D27]>; def Q14 : ARMReg<14, "q14", [D28, D29]>; def Q15 : ARMReg<15, "q15", [D30, D31]>; -} // Pseudo 256-bit registers to represent pairs of Q registers. These should // never be present in the emitted code. @@ -146,9 +138,6 @@ // starting D register number doesn't have to be multiple of 4. e.g. // D1, D2, D3, D4 would be a legal quad. But that would make the sub-register // stuffs very messy. -let SubRegIndices = [qsub_0, qsub_1], - CompositeIndices = [(dsub_2 qsub_1, dsub_0), - (dsub_3 qsub_1, dsub_1)] in { def QQ0 : ARMReg<0, "qq0", [Q0, Q1]>; def QQ1 : ARMReg<1, "qq1", [Q2, Q3]>; def QQ2 : ARMReg<2, "qq2", [Q4, Q5]>; @@ -157,21 +146,12 @@ def QQ5 : ARMReg<5, "qq5", [Q10, Q11]>; def QQ6 : ARMReg<6, "qq6", [Q12, Q13]>; def QQ7 : ARMReg<7, "qq7", [Q14, Q15]>; -} // Pseudo 512-bit registers to represent four consecutive Q registers. -let SubRegIndices = [qqsub_0, qqsub_1], - CompositeIndices = [(qsub_2 qqsub_1, qsub_0), - (qsub_3 qqsub_1, qsub_1), - (dsub_4 qqsub_1, dsub_0), - (dsub_5 qqsub_1, dsub_1), - (dsub_6 qqsub_1, dsub_2), - (dsub_7 qqsub_1, dsub_3)] in { def QQQQ0 : ARMReg<0, "qqqq0", [QQ0, QQ1]>; def QQQQ1 : ARMReg<1, "qqqq1", [QQ2, QQ3]>; def QQQQ2 : ARMReg<2, "qqqq2", [QQ4, QQ5]>; def QQQQ3 : ARMReg<3, "qqqq3", [QQ6, QQ7]>; -} // Current Program Status Register. def CPSR : ARMReg<0, "cpsr">; @@ -458,3 +438,102 @@ // Condition code registers. def CCR : RegisterClass<"ARM", [i32], 32, [CPSR]>; +//===----------------------------------------------------------------------===// +// Subregister Set Definitions... now that we have all of the pieces, define the +// sub registers for each register. +// + +// S sub-registers of D registers. +def : SubRegSet; +def : SubRegSet; + +// S sub-registers of Q registers. +def : SubRegSet; +def : SubRegSet; +def : SubRegSet; +def : SubRegSet; + +// D sub-registers of Q registers. +def : SubRegSet; +def : SubRegSet; + +// S sub-registers of QQ registers. Note there are no sub-indices +// for referencing S4 - S7, S12 - S15, and S20 - S23. It doesn't +// look like we need them. +def : SubRegSet; +def : SubRegSet; +def : SubRegSet; +def : SubRegSet; + +// D sub-registers of QQ registers. +def : SubRegSet; +def : SubRegSet; +def : SubRegSet; +def : SubRegSet; + +// Q sub-registers of QQ registers. +def : SubRegSet; +def : SubRegSet; + + +// D sub-registers of QQQQ registers. +def : SubRegSet; +def : SubRegSet; +def : SubRegSet; +def : SubRegSet; + +def : SubRegSet; +def : SubRegSet; +def : SubRegSet; +def : SubRegSet; + +// Q sub-registers of QQQQ registers. +def : SubRegSet; +def : SubRegSet; +def : SubRegSet; +def : SubRegSet; + +// QQ sub-registers of QQQQ registers. +def : SubRegSet; +def : SubRegSet; + Modified: llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td?rev=104660&r1=104659&r2=104660&view=diff ============================================================================== --- llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td (original) +++ llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td Tue May 25 20:21:14 2010 @@ -19,7 +19,6 @@ def lo16 : SubRegIndex; def hi16 : SubRegIndex; def lo32 : SubRegIndex; -def hi32 : SubRegIndex; } // Registers are identified with 3-bit group and 3-bit ID numbers. @@ -50,7 +49,6 @@ // Ra 40-bit accumulator registers class Ra num, string n, list subs> : BlackfinReg { let SubRegs = subs; - let SubRegIndices = [hi32, lo32]; let Group = 4; let Num = num; } @@ -65,7 +63,6 @@ class Rii group, bits<3> num, string n, list subs> : BlackfinReg { let SubRegs = subs; - let SubRegIndices = [hi16, lo16]; let Group = group; let Num = num; } @@ -176,7 +173,7 @@ def RETE : Ri<7, 6, "rete">, DwarfRegNum<[39]>; def ASTAT : Ri<4, 6, "astat">, DwarfRegNum<[40]> { - let Aliases = [AZ, AN, CC, NCC, AQ, AC0, AC1, AV0, AV0S, AV1, AV1S, V, VS]; + let SubRegs = [AZ, AN, CC, NCC, AQ, AC0, AC1, AV0, AV0S, AV1, AV1S, V, VS]; } def SEQSTAT : Ri<7, 1, "seqstat">, DwarfRegNum<[41]>; @@ -194,6 +191,29 @@ def LB0 : Ri<6, 2, "lb0">, DwarfRegNum<[48]>; def LB1 : Ri<6, 5, "lb1">, DwarfRegNum<[49]>; +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; +def : SubRegSet; + // Register classes. def D16 : RegisterClass<"BF", [i16], 16, [R0H, R0L, R1H, R1L, R2H, R2L, R3H, R3L, Modified: llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.td?rev=104660&r1=104659&r2=104660&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.td (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.td Tue May 25 20:21:14 2010 @@ -17,15 +17,21 @@ let Namespace = "MBlaze"; } +class MBlazeRegWithSubRegs subregs> + : RegisterWithSubRegs { + field bits<5> Num; + let Namespace = "MBlaze"; +} + // MBlaze CPU Registers class MBlazeGPRReg num, string n> : MBlazeReg { let Num = num; } // MBlaze 32-bit (aliased) FPU Registers -class FPR num, string n, list aliases> : MBlazeReg { +class FPR num, string n, list subregs> + : MBlazeRegWithSubRegs { let Num = num; - let Aliases = aliases; } //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td?rev=104660&r1=104659&r2=104660&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td (original) +++ llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td Tue May 25 20:21:14 2010 @@ -43,9 +43,6 @@ def R14B : MSP430Reg<14, "r14">; def R15B : MSP430Reg<15, "r15">; -def subreg_8bit : SubRegIndex { let Namespace = "MSP430"; } - -let SubRegIndices = [subreg_8bit] in { def PCW : MSP430RegWithSubregs<0, "r0", [PCB]>; def SPW : MSP430RegWithSubregs<1, "r1", [SPB]>; def SRW : MSP430RegWithSubregs<2, "r2", [SRB]>; @@ -62,7 +59,13 @@ def R13W : MSP430RegWithSubregs<13, "r13", [R13B]>; def R14W : MSP430RegWithSubregs<14, "r14", [R14B]>; def R15W : MSP430RegWithSubregs<15, "r15", [R15B]>; -} + +def subreg_8bit : SubRegIndex { let Namespace = "MSP430"; } + +def : SubRegSet; def GR8 : RegisterClass<"MSP430", [i8], 8, // Volatile registers Modified: llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td?rev=104660&r1=104659&r2=104660&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td (original) +++ llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td Tue May 25 20:21:14 2010 @@ -34,14 +34,9 @@ } // Mips 64-bit (aliased) FPU Registers -let Namespace = "Mips" in { -def sub_fpeven : SubRegIndex; -def sub_fpodd : SubRegIndex; -} -class AFPR num, string n, list subregs> +class AFPR num, string n, list subregs> : MipsRegWithSubRegs { let Num = num; - let SubRegIndices = [sub_fpeven, sub_fpodd]; } //===----------------------------------------------------------------------===// @@ -146,6 +141,25 @@ } //===----------------------------------------------------------------------===// +// Subregister Set Definitions +//===----------------------------------------------------------------------===// + +let Namespace = "Mips" in { +def sub_fpeven : SubRegIndex; +def sub_fpodd : SubRegIndex; +} + +def : SubRegSet; + +def : SubRegSet; + +//===----------------------------------------------------------------------===// // Register Classes //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td?rev=104660&r1=104659&r2=104660&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td (original) +++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td Tue May 25 20:21:14 2010 @@ -10,15 +10,6 @@ // //===----------------------------------------------------------------------===// -let Namespace = "PPC" in { -def sub_lt : SubRegIndex; -def sub_gt : SubRegIndex; -def sub_eq : SubRegIndex; -def sub_un : SubRegIndex; -def sub_32 : SubRegIndex; -} - - class PPCReg : Register { let Namespace = "PPC"; } @@ -34,7 +25,6 @@ class GP8 : PPCReg { field bits<5> Num = SubReg.Num; let SubRegs = [SubReg]; - let SubRegIndices = [sub_32]; } // SPR - One of the 32-bit special-purpose registers @@ -235,7 +225,6 @@ def CR7UN : CRBIT<31, "31">, DwarfRegNum<[0]>; // Condition registers -let SubRegIndices = [sub_lt, sub_gt, sub_eq, sub_un] in { def CR0 : CR<0, "cr0", [CR0LT, CR0GT, CR0EQ, CR0UN]>, DwarfRegNum<[68]>; def CR1 : CR<1, "cr1", [CR1LT, CR1GT, CR1EQ, CR1UN]>, DwarfRegNum<[69]>; def CR2 : CR<2, "cr2", [CR2LT, CR2GT, CR2EQ, CR2UN]>, DwarfRegNum<[70]>; @@ -244,8 +233,27 @@ def CR5 : CR<5, "cr5", [CR5LT, CR5GT, CR5EQ, CR5UN]>, DwarfRegNum<[73]>; def CR6 : CR<6, "cr6", [CR6LT, CR6GT, CR6EQ, CR6UN]>, DwarfRegNum<[74]>; def CR7 : CR<7, "cr7", [CR7LT, CR7GT, CR7EQ, CR7UN]>, DwarfRegNum<[75]>; + +let Namespace = "PPC" in { +def sub_lt : SubRegIndex; +def sub_gt : SubRegIndex; +def sub_eq : SubRegIndex; +def sub_un : SubRegIndex; } +def : SubRegSet; +def : SubRegSet; +def : SubRegSet; +def : SubRegSet; + // Link register def LR : SPR<8, "lr">, DwarfRegNum<[65]>; //let Aliases = [LR] in Modified: llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td?rev=104660&r1=104659&r2=104660&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td (original) +++ llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td Tue May 25 20:21:14 2010 @@ -20,11 +20,6 @@ let Namespace = "SP"; } -let Namespace = "SP" in { -def sub_even : SubRegIndex; -def sub_odd : SubRegIndex; -} - // Registers are identified with 5-bit ID numbers. // Ri - 32-bit integer registers class Ri num, string n> : SparcReg { @@ -38,7 +33,6 @@ class Rd num, string n, list subregs> : SparcReg { let Num = num; let SubRegs = subregs; - let SubRegIndices = [sub_even, sub_odd]; } // Control Registers Modified: llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td?rev=104660&r1=104659&r2=104660&view=diff ============================================================================== --- llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td (original) +++ llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td Tue May 25 20:21:14 2010 @@ -53,14 +53,6 @@ field bits<4> Num = num; } -let Namespace = "SystemZ" in { -def subreg_32bit : SubRegIndex; -def subreg_even32 : SubRegIndex; -def subreg_odd32 : SubRegIndex; -def subreg_even : SubRegIndex; -def subreg_odd : SubRegIndex; -} - // General-purpose registers def R0W : GPR32< 0, "r0">, DwarfRegNum<[0]>; def R1W : GPR32< 1, "r1">, DwarfRegNum<[1]>; @@ -79,7 +71,6 @@ def R14W : GPR32<14, "r14">, DwarfRegNum<[14]>; def R15W : GPR32<15, "r15">, DwarfRegNum<[15]>; -let SubRegIndices = [subreg_32bit] in { def R0D : GPR64< 0, "r0", [R0W]>, DwarfRegNum<[0]>; def R1D : GPR64< 1, "r1", [R1W]>, DwarfRegNum<[1]>; def R2D : GPR64< 2, "r2", [R2W]>, DwarfRegNum<[2]>; @@ -96,10 +87,8 @@ def R13D : GPR64<13, "r13", [R13W]>, DwarfRegNum<[13]>; def R14D : GPR64<14, "r14", [R14W]>, DwarfRegNum<[14]>; def R15D : GPR64<15, "r15", [R15W]>, DwarfRegNum<[15]>; -} // Register pairs -let SubRegIndices = [subreg_even32, subreg_odd32] in { def R0P : GPR64< 0, "r0", [R0W, R1W], [R0D, R1D]>, DwarfRegNum<[0]>; def R2P : GPR64< 2, "r2", [R2W, R3W], [R2D, R3D]>, DwarfRegNum<[2]>; def R4P : GPR64< 4, "r4", [R4W, R5W], [R4D, R5D]>, DwarfRegNum<[4]>; @@ -108,11 +97,7 @@ def R10P : GPR64<10, "r10", [R10W, R11W], [R10D, R11D]>, DwarfRegNum<[10]>; def R12P : GPR64<12, "r12", [R12W, R13W], [R12D, R13D]>, DwarfRegNum<[12]>; def R14P : GPR64<14, "r14", [R14W, R15W], [R14D, R15D]>, DwarfRegNum<[14]>; -} -let SubRegIndices = [subreg_even, subreg_odd], - CompositeIndices = [(subreg_even32 subreg_even, subreg_32bit), - (subreg_odd32 subreg_odd, subreg_32bit)] in { def R0Q : GPR128< 0, "r0", [R0D, R1D], [R0P]>, DwarfRegNum<[0]>; def R2Q : GPR128< 2, "r2", [R2D, R3D], [R2P]>, DwarfRegNum<[2]>; def R4Q : GPR128< 4, "r4", [R4D, R5D], [R4P]>, DwarfRegNum<[4]>; @@ -121,7 +106,6 @@ def R10Q : GPR128<10, "r10", [R10D, R11D], [R10P]>, DwarfRegNum<[10]>; def R12Q : GPR128<12, "r12", [R12D, R13D], [R12P]>, DwarfRegNum<[12]>; def R14Q : GPR128<14, "r14", [R14D, R15D], [R14P]>, DwarfRegNum<[14]>; -} // Floating-point registers def F0S : FPRS< 0, "f0">, DwarfRegNum<[16]>; @@ -141,7 +125,6 @@ def F14S : FPRS<14, "f14">, DwarfRegNum<[30]>; def F15S : FPRS<15, "f15">, DwarfRegNum<[31]>; -let SubRegIndices = [subreg_32bit] in { def F0L : FPRL< 0, "f0", [F0S]>, DwarfRegNum<[16]>; def F1L : FPRL< 1, "f1", [F1S]>, DwarfRegNum<[17]>; def F2L : FPRL< 2, "f2", [F2S]>, DwarfRegNum<[18]>; @@ -158,11 +141,41 @@ def F13L : FPRL<13, "f13", [F13S]>, DwarfRegNum<[29]>; def F14L : FPRL<14, "f14", [F14S]>, DwarfRegNum<[30]>; def F15L : FPRL<15, "f15", [F15S]>, DwarfRegNum<[31]>; -} // Status register def PSW : SystemZReg<"psw">; +let Namespace = "SystemZ" in { +def subreg_32bit : SubRegIndex; +def subreg_even32 : SubRegIndex; +def subreg_odd32 : SubRegIndex; +def subreg_even : SubRegIndex; +def subreg_odd : SubRegIndex; +} + +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; + /// Register classes def GR32 : RegisterClass<"SystemZ", [i32], 32, // Volatile registers Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.td?rev=104660&r1=104659&r2=104660&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.td Tue May 25 20:21:14 2010 @@ -68,22 +68,17 @@ def BH : Register<"bh">, DwarfRegNum<[3, 3, 3]>; // 16-bit registers - let SubRegIndices = [sub_8bit, sub_8bit_hi] in { def AX : RegisterWithSubRegs<"ax", [AL,AH]>, DwarfRegNum<[0, 0, 0]>; def DX : RegisterWithSubRegs<"dx", [DL,DH]>, DwarfRegNum<[1, 2, 2]>; def CX : RegisterWithSubRegs<"cx", [CL,CH]>, DwarfRegNum<[2, 1, 1]>; def BX : RegisterWithSubRegs<"bx", [BL,BH]>, DwarfRegNum<[3, 3, 3]>; - } - let SubRegIndices = [sub_8bit] in { def SI : RegisterWithSubRegs<"si", [SIL]>, DwarfRegNum<[4, 6, 6]>; def DI : RegisterWithSubRegs<"di", [DIL]>, DwarfRegNum<[5, 7, 7]>; def BP : RegisterWithSubRegs<"bp", [BPL]>, DwarfRegNum<[6, 4, 5]>; def SP : RegisterWithSubRegs<"sp", [SPL]>, DwarfRegNum<[7, 5, 4]>; - } def IP : Register<"ip">, DwarfRegNum<[16]>; // X86-64 only - let SubRegIndices = [sub_8bit] in { def R8W : RegisterWithSubRegs<"r8w", [R8B]>, DwarfRegNum<[8, -2, -2]>; def R9W : RegisterWithSubRegs<"r9w", [R9B]>, DwarfRegNum<[9, -2, -2]>; def R10W : RegisterWithSubRegs<"r10w", [R10B]>, DwarfRegNum<[10, -2, -2]>; @@ -92,9 +87,8 @@ def R13W : RegisterWithSubRegs<"r13w", [R13B]>, DwarfRegNum<[13, -2, -2]>; def R14W : RegisterWithSubRegs<"r14w", [R14B]>, DwarfRegNum<[14, -2, -2]>; def R15W : RegisterWithSubRegs<"r15w", [R15B]>, DwarfRegNum<[15, -2, -2]>; - } + // 32-bit registers - let SubRegIndices = [sub_16bit] in { def EAX : RegisterWithSubRegs<"eax", [AX]>, DwarfRegNum<[0, 0, 0]>; def EDX : RegisterWithSubRegs<"edx", [DX]>, DwarfRegNum<[1, 2, 2]>; def ECX : RegisterWithSubRegs<"ecx", [CX]>, DwarfRegNum<[2, 1, 1]>; @@ -114,10 +108,8 @@ def R13D : RegisterWithSubRegs<"r13d", [R13W]>, DwarfRegNum<[13, -2, -2]>; def R14D : RegisterWithSubRegs<"r14d", [R14W]>, DwarfRegNum<[14, -2, -2]>; def R15D : RegisterWithSubRegs<"r15d", [R15W]>, DwarfRegNum<[15, -2, -2]>; - } // 64-bit registers, X86-64 only - let SubRegIndices = [sub_32bit] in { def RAX : RegisterWithSubRegs<"rax", [EAX]>, DwarfRegNum<[0, -2, -2]>; def RDX : RegisterWithSubRegs<"rdx", [EDX]>, DwarfRegNum<[1, -2, -2]>; def RCX : RegisterWithSubRegs<"rcx", [ECX]>, DwarfRegNum<[2, -2, -2]>; @@ -136,7 +128,6 @@ def R14 : RegisterWithSubRegs<"r14", [R14D]>, DwarfRegNum<[14, -2, -2]>; def R15 : RegisterWithSubRegs<"r15", [R15D]>, DwarfRegNum<[15, -2, -2]>; def RIP : RegisterWithSubRegs<"rip", [EIP]>, DwarfRegNum<[16, -2, -2]>; - } // MMX Registers. These are actually aliased to ST0 .. ST7 def MM0 : Register<"mm0">, DwarfRegNum<[41, 29, 29]>; @@ -157,9 +148,7 @@ def FP5 : Register<"fp5">; def FP6 : Register<"fp6">; - // XMM Registers, used by the various SSE instruction set extensions. - // The sub_ss and sub_sd subregs are the same registers with another regclass. - let CompositeIndices = [(sub_ss), (sub_sd)] in { + // XMM Registers, used by the various SSE instruction set extensions def XMM0: Register<"xmm0">, DwarfRegNum<[17, 21, 21]>; def XMM1: Register<"xmm1">, DwarfRegNum<[18, 22, 22]>; def XMM2: Register<"xmm2">, DwarfRegNum<[19, 23, 23]>; @@ -178,10 +167,8 @@ def XMM13: Register<"xmm13">, DwarfRegNum<[30, -2, -2]>; def XMM14: Register<"xmm14">, DwarfRegNum<[31, -2, -2]>; def XMM15: Register<"xmm15">, DwarfRegNum<[32, -2, -2]>; - } // YMM Registers, used by AVX instructions - let SubRegIndices = [sub_xmm] in { def YMM0: RegisterWithSubRegs<"ymm0", [XMM0]>, DwarfRegNum<[17, 21, 21]>; def YMM1: RegisterWithSubRegs<"ymm1", [XMM1]>, DwarfRegNum<[18, 22, 22]>; def YMM2: RegisterWithSubRegs<"ymm2", [XMM2]>, DwarfRegNum<[19, 23, 23]>; @@ -198,7 +185,6 @@ def YMM13: RegisterWithSubRegs<"ymm13", [XMM13]>, DwarfRegNum<[30, -2, -2]>; def YMM14: RegisterWithSubRegs<"ymm14", [XMM14]>, DwarfRegNum<[31, -2, -2]>; def YMM15: RegisterWithSubRegs<"ymm15", [XMM15]>, DwarfRegNum<[32, -2, -2]>; - } // Floating point stack registers def ST0 : Register<"st(0)">, DwarfRegNum<[33, 12, 11]>; @@ -245,6 +231,75 @@ //===----------------------------------------------------------------------===// +// Subregister Set Definitions... now that we have all of the pieces, define the +// sub registers for each register. +// + +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; + +def : SubRegSet; + +//===----------------------------------------------------------------------===// // Register Class Definitions... now that we have all of the pieces, define the // top-level register classes. The order specified in the register list is // implicitly defined to be the register allocation order. Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp?rev=104660&r1=104659&r2=104660&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Tue May 25 20:21:14 2010 @@ -171,67 +171,6 @@ addSubSuperReg(R, *I, SubRegs, SuperRegs, Aliases); } -// Map SubRegIndex -> Register -typedef std::map SubRegMap; -// Map Register -> SubRegMap -typedef std::map AllSubRegMap; - -// Calculate all subregindices for Reg. Loopy subregs cause infinite recursion. -static SubRegMap &inferSubRegIndices(Record *Reg, AllSubRegMap &ASRM) { - SubRegMap &SRM = ASRM[Reg]; - if (!SRM.empty()) - return SRM; - std::vector SubRegs = Reg->getValueAsListOfDefs("SubRegs"); - std::vector Indices = Reg->getValueAsListOfDefs("SubRegIndices"); - if (SubRegs.size() != Indices.size()) - throw "Register " + Reg->getName() + " SubRegIndices doesn't match SubRegs"; - - // First insert the direct subregs. - for (unsigned i = 0, e = SubRegs.size(); i != e; ++i) { - if (!SRM.insert(std::make_pair(Indices[i], SubRegs[i])).second) - throw "SubRegIndex " + Indices[i]->getName() - + " appears twice in Register " + Reg->getName(); - inferSubRegIndices(SubRegs[i], ASRM); - } - - // Clone inherited subregs. Here the order is important - earlier subregs take - // precedence. - for (unsigned i = 0, e = SubRegs.size(); i != e; ++i) { - SubRegMap &M = ASRM[SubRegs[i]]; - SRM.insert(M.begin(), M.end()); - } - - // Finally process the composites. - ListInit *Comps = Reg->getValueAsListInit("CompositeIndices"); - for (unsigned i = 0, e = Comps->size(); i != e; ++i) { - DagInit *Pat = dynamic_cast(Comps->getElement(i)); - if (!Pat) - throw "Invalid dag '" + Comps->getElement(i)->getAsString() - + "' in CompositeIndices"; - DefInit *BaseIdxInit = dynamic_cast(Pat->getOperator()); - if (!BaseIdxInit || !BaseIdxInit->getDef()->isSubClassOf("SubRegIndex")) - throw "Invalid SubClassIndex in " + Pat->getAsString(); - - // Resolve list of subreg indices into R2. - Record *R2 = Reg; - for (DagInit::const_arg_iterator di = Pat->arg_begin(), - de = Pat->arg_end(); di != de; ++di) { - DefInit *IdxInit = dynamic_cast(*di); - if (!IdxInit || !IdxInit->getDef()->isSubClassOf("SubRegIndex")) - throw "Invalid SubClassIndex in " + Pat->getAsString(); - SubRegMap::const_iterator ni = ASRM[R2].find(IdxInit->getDef()); - if (ni == ASRM[R2].end()) - throw "Composite " + Pat->getAsString() + " refers to bad index in " - + R2->getName(); - R2 = ni->second; - } - - // Insert composite index. Allow overriding inherited indices etc. - SRM[BaseIdxInit->getDef()] = R2; - } - return SRM; -} - class RegisterSorter { private: std::map, LessRecord> &RegisterSubRegs; @@ -516,6 +455,8 @@ std::map, LessRecord> RegisterSubRegs; std::map, LessRecord> RegisterSuperRegs; std::map, LessRecord> RegisterAliases; + // Register -> [(SubRegIndex, Register)] + std::map > > SubRegVectors; typedef std::map, LessRecord> DwarfRegNumsMapTy; DwarfRegNumsMapTy DwarfRegNums; @@ -807,44 +748,56 @@ std::string ClassName = Target.getName() + "GenRegisterInfo"; // Calculate the mapping of subregister+index pairs to physical registers. - AllSubRegMap AllSRM; - + std::vector SubRegs = Records.getAllDerivedDefinitions("SubRegSet"); + for (unsigned i = 0, e = SubRegs.size(); i != e; ++i) { + Record *subRegIndex = SubRegs[i]->getValueAsDef("Index"); + std::vector From = SubRegs[i]->getValueAsListOfDefs("From"); + std::vector To = SubRegs[i]->getValueAsListOfDefs("To"); + + if (From.size() != To.size()) { + errs() << "Error: register list and sub-register list not of equal length" + << " in SubRegSet\n"; + exit(1); + } + + // For each entry in from/to vectors, insert the to register at index + for (unsigned ii = 0, ee = From.size(); ii != ee; ++ii) + SubRegVectors[From[ii]].push_back(std::make_pair(subRegIndex, To[ii])); + } + // Emit the subregister + index mapping function based on the information // calculated above. - OS << "unsigned " << ClassName + OS << "unsigned " << ClassName << "::getSubReg(unsigned RegNo, unsigned Index) const {\n" << " switch (RegNo) {\n" << " default:\n return 0;\n"; - for (unsigned i = 0, e = Regs.size(); i != e; ++i) { - SubRegMap &SRM = inferSubRegIndices(Regs[i].TheDef, AllSRM); - if (SRM.empty()) - continue; - OS << " case " << getQualifiedName(Regs[i].TheDef) << ":\n"; + for (std::map > >::iterator + I = SubRegVectors.begin(), E = SubRegVectors.end(); I != E; ++I) { + OS << " case " << getQualifiedName(I->first) << ":\n"; OS << " switch (Index) {\n"; OS << " default: return 0;\n"; - for (SubRegMap::const_iterator ii = SRM.begin(), ie = SRM.end(); ii != ie; - ++ii) - OS << " case " << getQualifiedName(ii->first) - << ": return " << getQualifiedName(ii->second) << ";\n"; + for (unsigned i = 0, e = I->second.size(); i != e; ++i) + OS << " case " + << getQualifiedName((I->second)[i].first) << ": return " + << getQualifiedName((I->second)[i].second) << ";\n"; OS << " };\n" << " break;\n"; } OS << " };\n"; OS << " return 0;\n"; OS << "}\n\n"; - OS << "unsigned " << ClassName + OS << "unsigned " << ClassName << "::getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const {\n" << " switch (RegNo) {\n" << " default:\n return 0;\n"; - for (unsigned i = 0, e = Regs.size(); i != e; ++i) { - SubRegMap &SRM = AllSRM[Regs[i].TheDef]; - if (SRM.empty()) - continue; - OS << " case " << getQualifiedName(Regs[i].TheDef) << ":\n"; - for (SubRegMap::const_iterator ii = SRM.begin(), ie = SRM.end(); ii != ie; - ++ii) - OS << " if (SubRegNo == " << getQualifiedName(ii->second) - << ") return " << getQualifiedName(ii->first) << ";\n"; + for (std::map > >::iterator + I = SubRegVectors.begin(), E = SubRegVectors.end(); I != E; ++I) { + OS << " case " << getQualifiedName(I->first) << ":\n"; + for (unsigned i = 0, e = I->second.size(); i != e; ++i) + OS << " if (SubRegNo == " + << getQualifiedName((I->second)[i].second) + << ") return " + << getQualifiedName((I->second)[i].first) << ";\n"; OS << " return 0;\n"; } OS << " };\n"; From grosbach at apple.com Tue May 25 20:22:21 2010 From: grosbach at apple.com (Jim Grosbach) Date: Wed, 26 May 2010 01:22:21 -0000 Subject: [llvm-commits] [llvm] r104661 - in /llvm/trunk/lib/Target/ARM: ARMInstrThumb.td ARMInstrThumb2.td Message-ID: <20100526012221.8D8DF3128042@llvm.org> Author: grosbach Date: Tue May 25 20:22:21 2010 New Revision: 104661 URL: http://llvm.org/viewvc/llvm-project?rev=104661&view=rev Log: fix off by 1 (insn) error in eh.sjlj.setjmp thumb code sequence. Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=104661&r1=104660&r2=104661&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Tue May 25 20:22:21 2010 @@ -930,7 +930,7 @@ AddrModeNone, SizeSpecial, NoItinerary, "str\t$val, [$src, #8]\t${:comment} begin eh.setjmp\n" "\tmov\t$val, pc\n" - "\tadds\t$val, #9\n" + "\tadds\t$val, #7\n" "\tstr\t$val, [$src, #4]\n" "\tmovs\tr0, #0\n" "\tb\t1f\n" Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=104661&r1=104660&r2=104661&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Tue May 25 20:22:21 2010 @@ -2399,7 +2399,7 @@ AddrModeNone, SizeSpecial, NoItinerary, "str\t$val, [$src, #8]\t${:comment} begin eh.setjmp\n" "\tmov\t$val, pc\n" - "\tadds\t$val, #9\n" + "\tadds\t$val, #7\n" "\tstr\t$val, [$src, #4]\n" "\tmovs\tr0, #0\n" "\tb\t1f\n" @@ -2415,7 +2415,7 @@ AddrModeNone, SizeSpecial, NoItinerary, "str\t$val, [$src, #8]\t${:comment} begin eh.setjmp\n" "\tmov\t$val, pc\n" - "\tadds\t$val, #9\n" + "\tadds\t$val, #7\n" "\tstr\t$val, [$src, #4]\n" "\tmovs\tr0, #0\n" "\tb\t1f\n" From echristo at apple.com Tue May 25 20:59:55 2010 From: echristo at apple.com (Eric Christopher) Date: Wed, 26 May 2010 01:59:55 -0000 Subject: [llvm-commits] [llvm] r104664 - in /llvm/trunk: include/llvm/CodeGen/MachineFunction.h lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp lib/CodeGen/StackSlotColoring.cpp Message-ID: <20100526015955.4C1943128060@llvm.org> Author: echristo Date: Tue May 25 20:59:55 2010 New Revision: 104664 URL: http://llvm.org/viewvc/llvm-project?rev=104664&view=rev Log: Temporarily revert r104655 as it's breaking the bots. Modified: llvm/trunk/include/llvm/CodeGen/MachineFunction.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Modified: llvm/trunk/include/llvm/CodeGen/MachineFunction.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineFunction.h?rev=104664&r1=104663&r2=104664&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineFunction.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineFunction.h Tue May 25 20:59:55 2010 @@ -114,13 +114,9 @@ /// unsigned FunctionNumber; - /// Alignment - The alignment of the function. + /// The alignment of the function. unsigned Alignment; - /// HasReturnsTwiceCall - Returns true if there's a call with a - /// "returns_twice" attribute, like setjmp. - bool HasReturnsTwiceCall; - MachineFunction(const MachineFunction &); // DO NOT IMPLEMENT void operator=(const MachineFunction&); // DO NOT IMPLEMENT public: @@ -185,15 +181,6 @@ void EnsureAlignment(unsigned A) { if (Alignment < A) Alignment = A; } - - /// hasReturnsTwiceCall - Returns true if there's a call with a - /// "returns_twice" attribute, like setjmp. - bool hasReturnsTwiceCall() const { - return HasReturnsTwiceCall; - } - void setReturnsTwiceCall(bool B) { - HasReturnsTwiceCall = B; - } /// getInfo - Keep track of various per-function pieces of information for /// backends that would like to do so. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=104664&r1=104663&r2=104664&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue May 25 20:59:55 2010 @@ -25,7 +25,6 @@ #include "llvm/Intrinsics.h" #include "llvm/IntrinsicInst.h" #include "llvm/LLVMContext.h" -#include "llvm/Module.h" #include "llvm/CodeGen/FastISel.h" #include "llvm/CodeGen/GCStrategy.h" #include "llvm/CodeGen/GCMetadata.h" @@ -254,39 +253,6 @@ done:; } - // Set a flag indicating if the machine function makes a call to setjmp / - // sigsetjmp (i.e., a function marked "returns_twice"). We'll use this to - // disable certain optimizations which cannot handle such control flows. - // - // FIXME: This goes beyond the setjmp/sigsetjmp functions. We should check for - // the GCC "returns twice" attribute. - const Module *M = Fn.getParent(); - const Function *SetJmp = M->getFunction("setjmp"); - const Function *SigSetJmp = M->getFunction("sigsetjmp"); - bool HasReturnsTwiceCall = false; - - if (SetJmp || SigSetJmp) { - if (SetJmp && !SetJmp->use_empty()) - for (Value::const_use_iterator - I = SetJmp->use_begin(), E = SetJmp->use_end(); I != E; ++I) - if (const CallInst *CI = dyn_cast(I)) - if (CI->getParent()->getParent() == &Fn) { - HasReturnsTwiceCall = true; - break; - } - - if (!HasReturnsTwiceCall && SigSetJmp && !SigSetJmp->use_empty()) - for (Value::const_use_iterator - I = SigSetJmp->use_begin(), E = SigSetJmp->use_end(); I != E; ++I) - if (const CallInst *CI = dyn_cast(I)) - if (CI->getParent()->getParent() == &Fn) { - HasReturnsTwiceCall = true; - break; - } - - mf.setReturnsTwiceCall(HasReturnsTwiceCall); - } - // Release function-specific state. SDB and CurDAG are already cleared // at this point. FuncInfo->clear(); Modified: llvm/trunk/lib/CodeGen/StackSlotColoring.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackSlotColoring.cpp?rev=104664&r1=104663&r2=104664&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StackSlotColoring.cpp (original) +++ llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Tue May 25 20:59:55 2010 @@ -118,6 +118,7 @@ private: void InitializeSlots(); + bool CheckForSetJmpCall(const MachineFunction &MF) const; void ScanForSpillSlotRefs(MachineFunction &MF); bool OverlapWithAssignments(LiveInterval *li, int Color) const; int ColorSlot(LiveInterval *li); @@ -161,6 +162,34 @@ }; } +/// CheckForSetJmpCall - Return true if there's a call to setjmp/sigsetjmp in +/// this function. +bool StackSlotColoring::CheckForSetJmpCall(const MachineFunction &MF) const { + const Function *F = MF.getFunction(); + const Module *M = F->getParent(); + const Function *SetJmp = M->getFunction("setjmp"); + const Function *SigSetJmp = M->getFunction("sigsetjmp"); + + if (!SetJmp && !SigSetJmp) + return false; + + if (SetJmp && !SetJmp->use_empty()) + for (Value::const_use_iterator + I = SetJmp->use_begin(), E = SetJmp->use_end(); I != E; ++I) + if (const CallInst *CI = dyn_cast(I)) + if (CI->getParent()->getParent() == F) + return true; + + if (SigSetJmp && !SigSetJmp->use_empty()) + for (Value::const_use_iterator + I = SigSetJmp->use_begin(), E = SigSetJmp->use_end(); I != E; ++I) + if (const CallInst *CI = dyn_cast(I)) + if (CI->getParent()->getParent() == F) + return true; + + return false; +} + /// ScanForSpillSlotRefs - Scan all the machine instructions for spill slot /// references and update spill slot weights. void StackSlotColoring::ScanForSpillSlotRefs(MachineFunction &MF) { @@ -724,11 +753,14 @@ return false; } - // If there is a call to a function with the attribute "returns_twice" (like - // setjmp or sigsetjmp), don't perform stack slot coloring. The stack could be - // modified before the the second return, resulting in the wrong value being - // used afterwards. (See .) - if (MF.hasReturnsTwiceCall()) + // If there are calls to setjmp or sigsetjmp, don't perform stack slot + // coloring. The stack could be modified before the longjmp is executed, + // resulting in the wrong value being used afterwards. (See + // .) + // + // FIXME: This goes beyond the setjmp/sigsetjmp functions. Ideally, we should + // check for the GCC "returns twice" attribute. + if (CheckForSetJmpCall(MF)) return false; // Gather spill slot references From sliao at google.com Tue May 25 22:04:19 2010 From: sliao at google.com (Shih-wei Liao) Date: Tue, 25 May 2010 20:04:19 -0700 Subject: [llvm-commits] [PATCH] [ARM JIT] To fix the missing implementation of ARM::UBFX and ARM::SBFX In-Reply-To: References: Message-ID: Thanks to Zonr's and Nick's reviews, I removed "<< 0" to make the code look cleaner. Thanks to Zonr's review, I changed the notation from Instr[] to Instr{}. Please see the new patch. On Tue, May 25, 2010 at 5:59 PM, Shih-wei Liao wrote: > Attached is the patch that will fix the bug > http://llvm.org/bugs/show_bug.cgi?id=7225. > > The patch passed "make check-lit" and "make check". > > Could someone please review it? Thanks. > -- > Thanks, > Shih-wei > -- Thanks, Shih-wei -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100525/fbd1ab31/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: arm-jit-ubfx-sbfx.patch Type: text/x-patch Size: 1084 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100525/fbd1ab31/attachment.bin From zonr.xchg at gmail.com Tue May 25 22:14:06 2010 From: zonr.xchg at gmail.com (Zonr Chang) Date: Wed, 26 May 2010 11:14:06 +0800 Subject: [llvm-commits] [PATCH] [ARM JIT] To fix the missing implementation of ARM::UBFX and ARM::SBFX In-Reply-To: References: Message-ID: I just reviewed and tested this patch. Good job! LGTM. Zonr On Wed, May 26, 2010 at 11:04 AM, Shih-wei Liao wrote: > Thanks to Zonr's and Nick's reviews, I removed "<< 0" to make the code look > cleaner. > > Thanks to Zonr's review, I changed the notation from Instr[] to Instr{}. > Please see the new patch. > > > On Tue, May 25, 2010 at 5:59 PM, Shih-wei Liao wrote: > >> Attached is the patch that will fix the bug >> http://llvm.org/bugs/show_bug.cgi?id=7225. >> >> The patch passed "make check-lit" and "make check". >> >> Could someone please review it? Thanks. >> -- >> Thanks, >> Shih-wei >> > > -- > Thanks, > Shih-wei > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100526/6c65a374/attachment.html From sliao at google.com Tue May 25 22:21:39 2010 From: sliao at google.com (Shih-wei Liao) Date: Wed, 26 May 2010 03:21:39 -0000 Subject: [llvm-commits] [llvm] r104667 - /llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Message-ID: <20100526032139.AB0D93128060@llvm.org> Author: sliao Date: Tue May 25 22:21:39 2010 New Revision: 104667 URL: http://llvm.org/viewvc/llvm-project?rev=104667&view=rev Log: Adding the missing implementation for ARM::SBFX and ARM::UBFX. Fixing http://llvm.org/bugs/show_bug.cgi?id=7225. Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=104667&r1=104666&r2=104667&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Tue May 25 22:21:39 2010 @@ -820,11 +820,23 @@ uint32_t v = ~MI.getOperand(2).getImm(); int32_t lsb = CountTrailingZeros_32(v); int32_t msb = (32 - CountLeadingZeros_32(v)) - 1; - // Insts[20-16] = msb, Insts[11-7] = lsb + // Instr{20-16} = msb, Instr{11-7} = lsb Binary |= (msb & 0x1F) << 16; Binary |= (lsb & 0x1F) << 7; emitWordLE(Binary); return; + } else if ((TID.Opcode == ARM::UBFX) || (TID.Opcode == ARM::SBFX)) { + // Encode Rn in Instr{0-3} + Binary |= getMachineOpValue(MI, OpIdx++); + + uint32_t lsb = MI.getOperand(OpIdx++).getImm(); + uint32_t widthm1 = MI.getOperand(OpIdx++).getImm() - 1; + + // Instr{20-16} = widthm1, Instr{11-7} = lsb + Binary |= (widthm1 & 0x1F) << 16; + Binary |= (lsb & 0x1F) << 7; + emitWordLE(Binary); + return; } // If this is a two-address operand, skip it. e.g. MOVCCr operand 1. From anton at korobeynikov.info Tue May 25 23:28:51 2010 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Wed, 26 May 2010 08:28:51 +0400 Subject: [llvm-commits] [llvm] r104653 - /llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp In-Reply-To: <20100526002505.7DBA93128034@llvm.org> References: <20100526002505.7DBA93128034@llvm.org> Message-ID: Hello, Shih-wei > + ?} else if((TID.Opcode == ARM::BFC) || (TID.Opcode == ARM::BFI)) { Please put a space between "if" and "(" Thanks! -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University From sliao at google.com Tue May 25 23:41:06 2010 From: sliao at google.com (Shih-wei Liao) Date: Tue, 25 May 2010 21:41:06 -0700 Subject: [llvm-commits] [llvm] r104653 - /llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp In-Reply-To: References: <20100526002505.7DBA93128034@llvm.org> Message-ID: Thanks. Now I added a space. Please see the attached patch. (I didn't run "make check" or "make check-lit" on this.) On Tue, May 25, 2010 at 9:28 PM, Anton Korobeynikov wrote: > Hello, Shih-wei > > + } else if((TID.Opcode == ARM::BFC) || (TID.Opcode == ARM::BFI)) { > Please put a space between "if" and "(" > > Thanks! > > -- > With best regards, Anton Korobeynikov > Faculty of Mathematics and Mechanics, Saint Petersburg State University > -- Thanks, Shih-wei -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100525/6ab19196/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: arm-jit-bfc-and-bfi.patch Type: text/x-patch Size: 570 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100525/6ab19196/attachment.bin From nicholas at mxc.ca Tue May 25 23:46:20 2010 From: nicholas at mxc.ca (Nick Lewycky) Date: Tue, 25 May 2010 21:46:20 -0700 Subject: [llvm-commits] [llvm] r104653 - /llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp In-Reply-To: References: <20100526002505.7DBA93128034@llvm.org> Message-ID: <4BFCA79C.9030106@mxc.ca> Shih-wei Liao wrote: > Thanks. Now I added a space. Please see the attached patch. > > (I didn't run "make check" or "make check-lit" on this.) You don't need to, please just go ahead and commit. :) The line in the developer policy is: "You are allowed to commit patches without approval which you think are obvious. This is clearly a subjective decision ? we simply expect you to use good judgement. Examples include: fixing build breakage, reverting obviously broken patches, documentation/comment changes, any other minor changes." Nick > On Tue, May 25, 2010 at 9:28 PM, Anton Korobeynikov > > wrote: > > Hello, Shih-wei > > + } else if((TID.Opcode == ARM::BFC) || (TID.Opcode == ARM::BFI)) { > Please put a space between "if" and "(" > > Thanks! > > -- > With best regards, Anton Korobeynikov > Faculty of Mathematics and Mechanics, Saint Petersburg State University > > > > > -- > Thanks, > Shih-wei > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sliao at google.com Tue May 25 23:46:50 2010 From: sliao at google.com (Shih-wei Liao) Date: Wed, 26 May 2010 04:46:50 -0000 Subject: [llvm-commits] [llvm] r104670 - /llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Message-ID: <20100526044650.2A2AE3128075@llvm.org> Author: sliao Date: Tue May 25 23:46:50 2010 New Revision: 104670 URL: http://llvm.org/viewvc/llvm-project?rev=104670&view=rev Log: Coding style change (Adding 1 missing space.) Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=104670&r1=104669&r2=104670&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Tue May 25 23:46:50 2010 @@ -816,7 +816,7 @@ Binary |= ((Hi16 >> 12) & 0xF) << 16; emitWordLE(Binary); return; - } else if((TID.Opcode == ARM::BFC) || (TID.Opcode == ARM::BFI)) { + } else if ((TID.Opcode == ARM::BFC) || (TID.Opcode == ARM::BFI)) { uint32_t v = ~MI.getOperand(2).getImm(); int32_t lsb = CountTrailingZeros_32(v); int32_t msb = (32 - CountLeadingZeros_32(v)) - 1; From sliao at google.com Tue May 25 23:49:05 2010 From: sliao at google.com (Shih-wei Liao) Date: Tue, 25 May 2010 21:49:05 -0700 Subject: [llvm-commits] [llvm] r104653 - /llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp In-Reply-To: <4BFCA79C.9030106@mxc.ca> References: <20100526002505.7DBA93128034@llvm.org> <4BFCA79C.9030106@mxc.ca> Message-ID: Thanks for shepherding the process. It's now committed as r104670. On Tue, May 25, 2010 at 9:46 PM, Nick Lewycky wrote: > Shih-wei Liao wrote: > >> Thanks. Now I added a space. Please see the attached patch. >> >> (I didn't run "make check" or "make check-lit" on this.) >> > > You don't need to, please just go ahead and commit. :) The line in the > developer policy is: > > "You are allowed to commit patches without approval which you think are > obvious. This is clearly a subjective decision ? we simply expect you to use > good judgement. Examples include: fixing build breakage, reverting obviously > broken patches, documentation/comment changes, any other minor changes." > > Nick > > On Tue, May 25, 2010 at 9:28 PM, Anton Korobeynikov >> > wrote: >> >> Hello, Shih-wei >> > + } else if((TID.Opcode == ARM::BFC) || (TID.Opcode == ARM::BFI)) { >> Please put a space between "if" and "(" >> >> Thanks! >> >> -- >> With best regards, Anton Korobeynikov >> Faculty of Mathematics and Mechanics, Saint Petersburg State University >> >> >> >> >> -- >> Thanks, >> Shih-wei >> >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> > > -- Thanks, Shih-wei -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100525/0fb4520b/attachment.html From evan.cheng at apple.com Wed May 26 00:07:46 2010 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 25 May 2010 22:07:46 -0700 Subject: [llvm-commits] [llvm] r104653 - /llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp In-Reply-To: <20100526002505.7DBA93128034@llvm.org> References: <20100526002505.7DBA93128034@llvm.org> Message-ID: <7C8551B3-8E39-484E-A2DB-C830636F141B@apple.com> Sorry I have been behind on patch reviews. I have some concerns about these patches. We want to prevent special casing for individual instructions. Is it not possible to add generic support for these? Evan On May 25, 2010, at 5:25 PM, Shih-wei Liao wrote: > Author: sliao > Date: Tue May 25 19:25:05 2010 > New Revision: 104653 > > URL: http://llvm.org/viewvc/llvm-project?rev=104653&view=rev > Log: > Adding the missing implementation of Bitfield's "clear" and "insert". > Fixing http://llvm.org/bugs/show_bug.cgi?id=7222. > > Modified: > llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp > > Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=104653&r1=104652&r2=104653&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Tue May 25 19:25:05 2010 > @@ -781,10 +781,6 @@ > unsigned ImplicitRn) { > const TargetInstrDesc &TID = MI.getDesc(); > > - if (TID.Opcode == ARM::BFC) { > - report_fatal_error("ARMv6t2 JIT is not yet supported."); > - } > - > // Part of binary is determined by TableGn. > unsigned Binary = getBinaryCodeForInstr(MI); > > @@ -820,6 +816,15 @@ > Binary |= ((Hi16 >> 12) & 0xF) << 16; > emitWordLE(Binary); > return; > + } else if((TID.Opcode == ARM::BFC) || (TID.Opcode == ARM::BFI)) { > + uint32_t v = ~MI.getOperand(2).getImm(); > + int32_t lsb = CountTrailingZeros_32(v); > + int32_t msb = (32 - CountLeadingZeros_32(v)) - 1; > + // Insts[20-16] = msb, Insts[11-7] = lsb > + Binary |= (msb & 0x1F) << 16; > + Binary |= (lsb & 0x1F) << 7; > + emitWordLE(Binary); > + return; > } > > // If this is a two-address operand, skip it. e.g. MOVCCr operand 1. > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From daniel at zuster.org Wed May 26 01:50:57 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 26 May 2010 06:50:57 -0000 Subject: [llvm-commits] [llvm] r104689 - in /llvm/trunk: include/llvm/MC/MCAssembler.h lib/MC/MCAssembler.cpp Message-ID: <20100526065057.9D94C3128060@llvm.org> Author: ddunbar Date: Wed May 26 01:50:57 2010 New Revision: 104689 URL: http://llvm.org/viewvc/llvm-project?rev=104689&view=rev Log: MC: Eliminate MCFragment vtable, which was unnecessary. Modified: llvm/trunk/include/llvm/MC/MCAssembler.h llvm/trunk/lib/MC/MCAssembler.cpp Modified: llvm/trunk/include/llvm/MC/MCAssembler.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAssembler.h?rev=104689&r1=104688&r2=104689&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCAssembler.h (original) +++ llvm/trunk/include/llvm/MC/MCAssembler.h Wed May 26 01:50:57 2010 @@ -108,7 +108,6 @@ public: // Only for sentinel. MCFragment(); - virtual ~MCFragment(); FragmentType getKind() const { return Kind; } @@ -123,7 +122,7 @@ static bool classof(const MCFragment *O) { return true; } - virtual void dump(); + void dump(); }; class MCDataFragment : public MCFragment { @@ -173,8 +172,6 @@ return F->getKind() == MCFragment::FT_Data; } static bool classof(const MCDataFragment *) { return true; } - - virtual void dump(); }; // FIXME: This current incarnation of MCInstFragment doesn't make much sense, as @@ -235,8 +232,6 @@ return F->getKind() == MCFragment::FT_Inst; } static bool classof(const MCInstFragment *) { return true; } - - virtual void dump(); }; class MCAlignFragment : public MCFragment { @@ -295,8 +290,6 @@ return F->getKind() == MCFragment::FT_Align; } static bool classof(const MCAlignFragment *) { return true; } - - virtual void dump(); }; class MCFillFragment : public MCFragment { @@ -334,8 +327,6 @@ return F->getKind() == MCFragment::FT_Fill; } static bool classof(const MCFillFragment *) { return true; } - - virtual void dump(); }; class MCOrgFragment : public MCFragment { @@ -363,8 +354,6 @@ return F->getKind() == MCFragment::FT_Org; } static bool classof(const MCOrgFragment *) { return true; } - - virtual void dump(); }; // FIXME: Should this be a separate class, or just merged into MCSection? Since Modified: llvm/trunk/lib/MC/MCAssembler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=104689&r1=104688&r2=104689&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCAssembler.cpp (original) +++ llvm/trunk/lib/MC/MCAssembler.cpp Wed May 26 01:50:57 2010 @@ -185,9 +185,6 @@ Parent->getFragmentList().push_back(this); } -MCFragment::~MCFragment() { -} - /* *** */ MCSectionData::MCSectionData() : Section(0) {} @@ -918,81 +915,77 @@ void MCFragment::dump() { raw_ostream &OS = llvm::errs(); + OS << "<"; + switch (getKind()) { + case MCFragment::FT_Align: OS << "MCAlignFragment"; break; + case MCFragment::FT_Data: OS << "MCDataFragment"; break; + case MCFragment::FT_Fill: OS << "MCFillFragment"; break; + case MCFragment::FT_Inst: OS << "MCInstFragment"; break; + case MCFragment::FT_Org: OS << "MCOrgFragment"; break; + } + OS << ""; -} -void MCAlignFragment::dump() { - raw_ostream &OS = llvm::errs(); - - OS << "MCFragment::dump(); - if (hasEmitNops()) - OS << " (emit nops)"; - if (hasOnlyAlignAddress()) - OS << " (only align section)"; - OS << "\n "; - OS << " Alignment:" << getAlignment() - << " Value:" << getValue() << " ValueSize:" << getValueSize() - << " MaxBytesToEmit:" << getMaxBytesToEmit() << ">"; -} - -void MCDataFragment::dump() { - raw_ostream &OS = llvm::errs(); + switch (getKind()) { + case MCFragment::FT_Align: { + const MCAlignFragment *AF = cast(this); + if (AF->hasEmitNops()) + OS << " (emit nops)"; + if (AF->hasOnlyAlignAddress()) + OS << " (only align section)"; + OS << "\n "; + OS << " Alignment:" << AF->getAlignment() + << " Value:" << AF->getValue() << " ValueSize:" << AF->getValueSize() + << " MaxBytesToEmit:" << AF->getMaxBytesToEmit() << ">"; + break; + } + case MCFragment::FT_Data: { + const MCDataFragment *DF = cast(this); + OS << "\n "; + OS << " Contents:["; + const SmallVectorImpl &Contents = DF->getContents(); + for (unsigned i = 0, e = Contents.size(); i != e; ++i) { + if (i) OS << ","; + OS << hexdigit((Contents[i] >> 4) & 0xF) << hexdigit(Contents[i] & 0xF); + } + OS << "] (" << Contents.size() << " bytes)"; - OS << "MCFragment::dump(); - OS << "\n "; - OS << " Contents:["; - for (unsigned i = 0, e = getContents().size(); i != e; ++i) { - if (i) OS << ","; - OS << hexdigit((Contents[i] >> 4) & 0xF) << hexdigit(Contents[i] & 0xF); - } - OS << "] (" << getContents().size() << " bytes)"; - - if (!getFixups().empty()) { - OS << ",\n "; - OS << " Fixups:["; - for (fixup_iterator it = fixup_begin(), ie = fixup_end(); it != ie; ++it) { - if (it != fixup_begin()) OS << ",\n "; - OS << *it; + if (!DF->getFixups().empty()) { + OS << ",\n "; + OS << " Fixups:["; + for (MCDataFragment::const_fixup_iterator it = DF->fixup_begin(), + ie = DF->fixup_end(); it != ie; ++it) { + if (it != DF->fixup_begin()) OS << ",\n "; + OS << *it; + } + OS << "]"; } - OS << "]"; + break; + } + case MCFragment::FT_Fill: { + const MCFillFragment *FF = cast(this); + OS << " Value:" << FF->getValue() << " ValueSize:" << FF->getValueSize() + << " Size:" << FF->getSize(); + break; + } + case MCFragment::FT_Inst: { + const MCInstFragment *IF = cast(this); + OS << "\n "; + OS << " Inst:"; + IF->getInst().dump_pretty(OS); + break; + } + case MCFragment::FT_Org: { + const MCOrgFragment *OF = cast(this); + OS << "\n "; + OS << " Offset:" << OF->getOffset() << " Value:" << OF->getValue(); + break; + } } - - OS << ">"; -} - -void MCFillFragment::dump() { - raw_ostream &OS = llvm::errs(); - - OS << "MCFragment::dump(); - OS << "\n "; - OS << " Value:" << getValue() << " ValueSize:" << getValueSize() - << " Size:" << getSize() << ">"; -} - -void MCInstFragment::dump() { - raw_ostream &OS = llvm::errs(); - - OS << "MCFragment::dump(); - OS << "\n "; - OS << " Inst:"; - getInst().dump_pretty(OS); OS << ">"; } -void MCOrgFragment::dump() { - raw_ostream &OS = llvm::errs(); - - OS << "MCFragment::dump(); - OS << "\n "; - OS << " Offset:" << getOffset() << " Value:" << getValue() << ">"; -} - void MCSectionData::dump() { raw_ostream &OS = llvm::errs(); From baldrick at free.fr Wed May 26 02:02:06 2010 From: baldrick at free.fr (Duncan Sands) Date: Wed, 26 May 2010 09:02:06 +0200 Subject: [llvm-commits] [llvm] r104632 - /llvm/trunk/test/CodeGen/X86/2010-05-25-FP_TO_INT-crash.ll In-Reply-To: <20100525204011.36BF63128026@llvm.org> References: <20100525204011.36BF63128026@llvm.org> Message-ID: <4BFCC76E.3030909@free.fr> Hi Dale, > Removing test; Chris thinks it's better to have the > bug go untested than have a testcase this large. So be it. I have two testcases (attached, unreduced) both of which showed the "Cannot yet select... X86ISD::FP_TO_INT32_IN_MEM" problem before you fixed it. I could get it by running "llc -O0 -mcpu=i386" on them. Ciao, Duncan. -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: 2003-08-05-CastFPToUint.ll Url: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100526/ced45e73/attachment.pl -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: 980605-1.ll Url: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100526/ced45e73/attachment-0001.pl From xuzhongxing at gmail.com Wed May 26 03:10:02 2010 From: xuzhongxing at gmail.com (Zhongxing Xu) Date: Wed, 26 May 2010 08:10:02 -0000 Subject: [llvm-commits] [llvm] r104691 - /llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Message-ID: <20100526081002.EC5AD312800A@llvm.org> Author: zhongxingxu Date: Wed May 26 03:10:02 2010 New Revision: 104691 URL: http://llvm.org/viewvc/llvm-project?rev=104691&view=rev Log: SRetReturnReg was set in LowerFormalArguments(). So only assert it here. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=104691&r1=104690&r2=104691&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed May 26 03:10:02 2010 @@ -1259,10 +1259,8 @@ MachineFunction &MF = DAG.getMachineFunction(); X86MachineFunctionInfo *FuncInfo = MF.getInfo(); unsigned Reg = FuncInfo->getSRetReturnReg(); - if (!Reg) { - Reg = MRI.createVirtualRegister(getRegClassFor(MVT::i64)); - FuncInfo->setSRetReturnReg(Reg); - } + assert(Reg && + "SRetReturnReg should have been set in LowerFormalArguments()."); SDValue Val = DAG.getCopyFromReg(Chain, dl, Reg, getPointerTy()); Chain = DAG.getCopyToReg(Chain, dl, X86::RAX, Val, Flag); From baldrick at free.fr Wed May 26 04:08:10 2010 From: baldrick at free.fr (Duncan Sands) Date: Wed, 26 May 2010 11:08:10 +0200 Subject: [llvm-commits] [PATCH] No need to check SRetReturnReg again In-Reply-To: References: <4BFBDA2C.6060508@free.fr> Message-ID: <4BFCE4FA.4040905@free.fr> On 26/05/10 03:02, Zhongxing Xu wrote: > It hasn't been applied. Is it okay to apply? Yes: if it passed testing, please go ahead. Ciao, Duncan. From sliao at google.com Wed May 26 04:15:39 2010 From: sliao at google.com (Shih-wei Liao) Date: Wed, 26 May 2010 02:15:39 -0700 Subject: [llvm-commits] [llvm] r104653 - /llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp In-Reply-To: <7C8551B3-8E39-484E-A2DB-C830636F141B@apple.com> References: <20100526002505.7DBA93128034@llvm.org> <7C8551B3-8E39-484E-A2DB-C830636F141B@apple.com> Message-ID: I agree that it's probably too easy to add one more to the many cases in ARMCodeEmitter.cpp. My bad. If changing ARM*.td can fix the bugs completely, that will be the best. Anyone knows of a better patch that's doable now? That will be great. I tried and stopped after the irregularities like widthm1 encoding and so on. Probably we should overhaul the ARM*.td some time soon. Currently these 2 if-conditions can make the ARM JIT usable first, and I agree that I should strive for a better solution. Stay tuned. On Tue, May 25, 2010 at 10:07 PM, Evan Cheng wrote: > > Sorry I have been behind on patch reviews. I have some concerns about these patches. We want to prevent special casing for individual instructions. Is it not possible to add generic support for these? > > Evan > > On May 25, 2010, at 5:25 PM, Shih-wei Liao wrote: > > > Author: sliao > > Date: Tue May 25 19:25:05 2010 > > New Revision: 104653 > > > > URL: http://llvm.org/viewvc/llvm-project?rev=104653&view=rev > > Log: > > Adding the missing implementation of Bitfield's "clear" and "insert". > > Fixing http://llvm.org/bugs/show_bug.cgi?id=7222. > > > > Modified: > > llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp > > > > Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=104653&r1=104652&r2=104653&view=diff > > ============================================================================== > > --- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original) > > +++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Tue May 25 19:25:05 2010 > > @@ -781,10 +781,6 @@ > > unsigned ImplicitRn) { > > const TargetInstrDesc &TID = MI.getDesc(); > > > > - if (TID.Opcode == ARM::BFC) { > > - report_fatal_error("ARMv6t2 JIT is not yet supported."); > > - } > > - > > // Part of binary is determined by TableGn. > > unsigned Binary = getBinaryCodeForInstr(MI); > > > > @@ -820,6 +816,15 @@ > > Binary |= ((Hi16 >> 12) & 0xF) << 16; > > emitWordLE(Binary); > > return; > > + } else if((TID.Opcode == ARM::BFC) || (TID.Opcode == ARM::BFI)) { > > + uint32_t v = ~MI.getOperand(2).getImm(); > > + int32_t lsb = CountTrailingZeros_32(v); > > + int32_t msb = (32 - CountLeadingZeros_32(v)) - 1; > > + // Insts[20-16] = msb, Insts[11-7] = lsb > > + Binary |= (msb & 0x1F) << 16; > > + Binary |= (lsb & 0x1F) << 7; > > + emitWordLE(Binary); > > + return; > > } > > > > // If this is a two-address operand, skip it. e.g. MOVCCr operand 1. > > > > > > _______________________________________________ > > llvm-commits mailing list > > llvm-commits at cs.uiuc.edu > > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits -- Thanks, Shih-wei -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100526/6bbb9116/attachment.html From sliao at google.com Wed May 26 04:27:54 2010 From: sliao at google.com (Shih-wei Liao) Date: Wed, 26 May 2010 02:27:54 -0700 Subject: [llvm-commits] [PATCH] [ARM JIT] To fix "llvm_unreachable("Unable to handle this constantpool entry!")" Message-ID: See http://llvm.org/bugs/show_bug.cgi?id=7226: ARM JIT couldn't?emit constant pool entry for "ConstantVector" and "ConstantArray". The patch passes both "make check" and "make check-lit". Basically, the patch added the processing of ConstantVector and ConstantArray. The problem is gone after the patch. -- Thanks, ? Shih-wei -------------- next part -------------- A non-text attachment was scrubbed... Name: arm-jit-ConstantVector-ConstantArray.patch Type: text/x-patch Size: 3591 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100526/24ced2f8/attachment.bin From benny.kra at googlemail.com Wed May 26 04:45:04 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Wed, 26 May 2010 09:45:04 -0000 Subject: [llvm-commits] [llvm] r104692 - /llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp Message-ID: <20100526094504.A5AE1312800A@llvm.org> Author: d0k Date: Wed May 26 04:45:04 2010 New Revision: 104692 URL: http://llvm.org/viewvc/llvm-project?rev=104692&view=rev Log: Kill unneeded SExt. Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp?rev=104692&r1=104691&r2=104692&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp Wed May 26 04:45:04 2010 @@ -564,7 +564,7 @@ CI->getType(), "lhsv"); Value *RHSV = B.CreateZExt(B.CreateLoad(CastToCStr(RHS, B), "rhsc"), CI->getType(), "rhsv"); - return B.CreateSExt(B.CreateSub(LHSV, RHSV, "chardiff"), CI->getType()); + return B.CreateSub(LHSV, RHSV, "chardiff"); } // Constant folding: memcmp(x, y, l) -> cnst (all arguments are constant) From sliao at google.com Wed May 26 05:19:13 2010 From: sliao at google.com (Shih-wei Liao) Date: Wed, 26 May 2010 03:19:13 -0700 Subject: [llvm-commits] [PATCH] [ARM JIT] Pseudo Instruction ARM::LEApcrel defined but not implemented Message-ID: See http://llvm.org/bugs/show_bug.cgi?id=7227: ARM JIT?misses the implementation of ARM::LEApcrel. The patch passes both "make check-lit" and "make check". For "make check-lit", Expected Passes : 4101 Expected Failures : 24 Unsupported Tests : 1184 make[1]: Leaving directory `/usr/local/google/upstream/llvm-obj/test' For "make check", === Summary === # of expected passes 3842 # of expected failures 24 make[1]: Leaving directory `/usr/local/google/upstream/llvm-obj/test' Basically, the patch added the case "ARM::LEApcrel" next to the "case ARM::LEApcrelJT". The latter was implemented, but not the former. With the added implementation, all our input programs result in correct execution under LLVM's ARM JIT. -- Thanks, ? Shih-wei -------------- next part -------------- A non-text attachment was scrubbed... Name: arm-jit-LEApcrel.patch Type: text/x-patch Size: 2255 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100526/4b2652f8/attachment.bin From baldrick at free.fr Wed May 26 09:45:57 2010 From: baldrick at free.fr (Duncan Sands) Date: Wed, 26 May 2010 14:45:57 -0000 Subject: [llvm-commits] [dragonegg] r104694 - /dragonegg/trunk/llvm-backend.cpp Message-ID: <20100526144557.BF06D312800A@llvm.org> Author: baldrick Date: Wed May 26 09:45:57 2010 New Revision: 104694 URL: http://llvm.org/viewvc/llvm-project?rev=104694&view=rev Log: Try turning on the ODR for C++ again. Modified: dragonegg/trunk/llvm-backend.cpp Modified: dragonegg/trunk/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-backend.cpp?rev=104694&r1=104693&r2=104694&view=diff ============================================================================== --- dragonegg/trunk/llvm-backend.cpp (original) +++ dragonegg/trunk/llvm-backend.cpp Wed May 26 09:45:57 2010 @@ -533,7 +533,7 @@ static void InstallLanguageSettings() { // The principal here is that not doing any language-specific configuration // should still result in correct code. The language-specific settings are - // only for obtaining better code, but exploiting language-specific features. + // only for obtaining better code, by exploiting language-specific features. StringRef LanguageName = lang_hooks.name; if (LanguageName == "GNU Ada") { @@ -542,7 +542,7 @@ } else if (LanguageName == "GNU C") { flag_vararg_requires_arguments = true; // "T foo() {}" -> "T foo(void) {}" } else if (LanguageName == "GNU C++") { -//FIXME flag_odr = true; // C++ obeys the one-definition-rule + flag_odr = true; // C++ obeys the one-definition-rule } else if (LanguageName == "GNU Fortran") { } else if (LanguageName == "GNU GIMPLE") { // LTO gold plugin } else if (LanguageName == "GNU Java") { From daniel at zuster.org Wed May 26 10:18:13 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 26 May 2010 15:18:13 -0000 Subject: [llvm-commits] [llvm] r104696 - in /llvm/trunk/lib: MC/MCAsmStreamer.cpp MC/MCInst.cpp Target/X86/X86AsmBackend.cpp Message-ID: <20100526151813.D0D65312800A@llvm.org> Author: ddunbar Date: Wed May 26 10:18:13 2010 New Revision: 104696 URL: http://llvm.org/viewvc/llvm-project?rev=104696&view=rev Log: MC: Change MCInst::dump_pretty to not include a trailing newline. Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp llvm/trunk/lib/MC/MCInst.cpp llvm/trunk/lib/Target/X86/X86AsmBackend.cpp Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=104696&r1=104695&r2=104696&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Wed May 26 10:18:13 2010 @@ -669,9 +669,11 @@ AddEncodingComment(Inst); // Show the MCInst if enabled. - if (ShowInst) + if (ShowInst) { Inst.dump_pretty(GetCommentOS(), &MAI, InstPrinter.get(), "\n "); - + GetCommentOS() << "\n"; + } + // If we have an AsmPrinter, use that to print, otherwise print the MCInst. if (InstPrinter) InstPrinter->printInst(&Inst, OS); Modified: llvm/trunk/lib/MC/MCInst.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCInst.cpp?rev=104696&r1=104695&r2=104696&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCInst.cpp (original) +++ llvm/trunk/lib/MC/MCInst.cpp Wed May 26 10:18:13 2010 @@ -57,7 +57,7 @@ OS << Separator; getOperand(i).print(OS, MAI); } - OS << ">\n"; + OS << ">"; } void MCInst::dump() const { Modified: llvm/trunk/lib/Target/X86/X86AsmBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86AsmBackend.cpp?rev=104696&r1=104695&r2=104696&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86AsmBackend.cpp (original) +++ llvm/trunk/lib/Target/X86/X86AsmBackend.cpp Wed May 26 10:18:13 2010 @@ -124,6 +124,7 @@ SmallString<256> Tmp; raw_svector_ostream OS(Tmp); IF->getInst().dump_pretty(OS); + OS << "\n"; report_fatal_error("unexpected instruction to relax: " + OS.str()); } From daniel at zuster.org Wed May 26 10:18:31 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 26 May 2010 15:18:31 -0000 Subject: [llvm-commits] [llvm] r104697 - in /llvm/trunk: include/llvm/MC/MCAssembler.h lib/MC/MCAssembler.cpp lib/MC/MCMachOStreamer.cpp lib/MC/MachObjectWriter.cpp lib/Target/X86/X86AsmBackend.cpp Message-ID: <20100526151831.8B0C2312800A@llvm.org> Author: ddunbar Date: Wed May 26 10:18:31 2010 New Revision: 104697 URL: http://llvm.org/viewvc/llvm-project?rev=104697&view=rev Log: MC: Use accessors for access to MCAsmFixup. Modified: llvm/trunk/include/llvm/MC/MCAssembler.h llvm/trunk/lib/MC/MCAssembler.cpp llvm/trunk/lib/MC/MCMachOStreamer.cpp llvm/trunk/lib/MC/MachObjectWriter.cpp llvm/trunk/lib/Target/X86/X86AsmBackend.cpp Modified: llvm/trunk/include/llvm/MC/MCAssembler.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAssembler.h?rev=104697&r1=104696&r2=104697&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCAssembler.h (original) +++ llvm/trunk/include/llvm/MC/MCAssembler.h Wed May 26 10:18:31 2010 @@ -42,7 +42,6 @@ // // FIXME: This should probably just be merged with MCFixup. class MCAsmFixup { -public: /// Offset - The offset inside the fragment which needs to be rewritten. uint64_t Offset; @@ -55,6 +54,13 @@ public: MCAsmFixup(uint64_t _Offset, const MCExpr &_Value, MCFixupKind _Kind) : Offset(_Offset), Value(&_Value), Kind(_Kind) {} + + MCFixupKind getKind() const { return MCFixupKind(Kind); } + + uint64_t getOffset() const { return Offset; } + void setOffset(uint64_t Value) { Offset = Value; } + + const MCExpr *getValue() const { return Value; } }; class MCFragment : public ilist_node { @@ -150,7 +156,7 @@ void addFixup(MCAsmFixup Fixup) { // Enforce invariant that fixups are in offset order. - assert((Fixups.empty() || Fixup.Offset > Fixups.back().Offset) && + assert((Fixups.empty() || Fixup.getOffset() > Fixups.back().getOffset()) && "Fixups must be added in order!"); Fixups.push_back(Fixup); } Modified: llvm/trunk/lib/MC/MCAssembler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=104697&r1=104696&r2=104697&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCAssembler.cpp (original) +++ llvm/trunk/lib/MC/MCAssembler.cpp Wed May 26 10:18:31 2010 @@ -347,7 +347,7 @@ MCValue &Target, uint64_t &Value) const { ++stats::EvaluateFixup; - if (!Fixup.Value->EvaluateAsRelocatable(Target, &Layout)) + if (!Fixup.getValue()->EvaluateAsRelocatable(Target, &Layout)) report_fatal_error("expected relocatable expression"); // FIXME: How do non-scattered symbols work in ELF? I presume the linker @@ -356,8 +356,8 @@ Value = Target.getConstant(); - bool IsPCRel = - Emitter.getFixupKindInfo(Fixup.Kind).Flags & MCFixupKindInfo::FKF_IsPCRel; + bool IsPCRel = Emitter.getFixupKindInfo( + Fixup.getKind()).Flags & MCFixupKindInfo::FKF_IsPCRel; bool IsResolved = true; if (const MCSymbolRefExpr *A = Target.getSymA()) { if (A->getSymbol().isDefined()) @@ -399,7 +399,7 @@ } if (IsPCRel) - Value -= Layout.getFragmentAddress(DF) + Fixup.Offset; + Value -= Layout.getFragmentAddress(DF) + Fixup.getOffset(); return IsResolved; } @@ -905,8 +905,9 @@ namespace llvm { raw_ostream &operator<<(raw_ostream &OS, const MCAsmFixup &AF) { - OS << ""; + OS << ""; return OS; } Modified: llvm/trunk/lib/MC/MCMachOStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCMachOStreamer.cpp?rev=104697&r1=104696&r2=104697&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCMachOStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCMachOStreamer.cpp Wed May 26 10:18:31 2010 @@ -471,7 +471,7 @@ // Add the fixups and data. MCDataFragment *DF = getOrCreateDataFragment(); for (unsigned i = 0, e = AsmFixups.size(); i != e; ++i) { - AsmFixups[i].Offset += DF->getContents().size(); + AsmFixups[i].setOffset(AsmFixups[i].getOffset() + DF->getContents().size()); DF->addFixup(AsmFixups[i]); } DF->getContents().append(Code.begin(), Code.end()); Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=104697&r1=104696&r2=104697&view=diff ============================================================================== --- llvm/trunk/lib/MC/MachObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/MachObjectWriter.cpp Wed May 26 10:18:31 2010 @@ -474,13 +474,15 @@ const MCFragment *Fragment, const MCAsmFixup &Fixup, MCValue Target, uint64_t &FixedValue) { - unsigned IsPCRel = isFixupKindPCRel(Fixup.Kind); - unsigned IsRIPRel = isFixupKindRIPRel(Fixup.Kind); - unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind); + unsigned IsPCRel = isFixupKindPCRel(Fixup.getKind()); + unsigned IsRIPRel = isFixupKindRIPRel(Fixup.getKind()); + unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind()); // See . - uint32_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.Offset; - uint32_t FixupAddress = Layout.getFragmentAddress(Fragment) + Fixup.Offset; + uint32_t FixupOffset = + Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); + uint32_t FixupAddress = + Layout.getFragmentAddress(Fragment) + Fixup.getOffset(); int64_t Value = 0; unsigned Index = 0; unsigned IsExtern = 0; @@ -606,7 +608,7 @@ // x86_64 distinguishes movq foo at GOTPCREL so that the linker can // rewrite the movq to an leaq at link time if the symbol ends up in // the same linkage unit. - if (unsigned(Fixup.Kind) == X86::reloc_riprel_4byte_movq_load) + if (unsigned(Fixup.getKind()) == X86::reloc_riprel_4byte_movq_load) Type = RIT_X86_64_GOTLoad; else Type = RIT_X86_64_GOT; @@ -682,9 +684,9 @@ const MCFragment *Fragment, const MCAsmFixup &Fixup, MCValue Target, uint64_t &FixedValue) { - uint32_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.Offset; - unsigned IsPCRel = isFixupKindPCRel(Fixup.Kind); - unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind); + uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); + unsigned IsPCRel = isFixupKindPCRel(Fixup.getKind()); + unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind()); unsigned Type = RIT_Vanilla; // See . @@ -744,8 +746,8 @@ return; } - unsigned IsPCRel = isFixupKindPCRel(Fixup.Kind); - unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind); + unsigned IsPCRel = isFixupKindPCRel(Fixup.getKind()); + unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind()); // If this is a difference or a defined symbol plus an offset, then we need // a scattered relocation entry. @@ -769,7 +771,7 @@ Target, FixedValue); // See . - uint32_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.Offset; + uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); uint32_t Value = 0; unsigned Index = 0; unsigned IsExtern = 0; Modified: llvm/trunk/lib/Target/X86/X86AsmBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86AsmBackend.cpp?rev=104697&r1=104696&r2=104697&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86AsmBackend.cpp (original) +++ llvm/trunk/lib/Target/X86/X86AsmBackend.cpp Wed May 26 10:18:31 2010 @@ -46,12 +46,12 @@ void ApplyFixup(const MCAsmFixup &Fixup, MCDataFragment &DF, uint64_t Value) const { - unsigned Size = 1 << getFixupKindLog2Size(Fixup.Kind); + unsigned Size = 1 << getFixupKindLog2Size(Fixup.getKind()); - assert(Fixup.Offset + Size <= DF.getContents().size() && + assert(Fixup.getOffset() + Size <= DF.getContents().size() && "Invalid fixup offset!"); for (unsigned i = 0; i != Size; ++i) - DF.getContents()[Fixup.Offset + i] = uint8_t(Value >> (i * 8)); + DF.getContents()[Fixup.getOffset() + i] = uint8_t(Value >> (i * 8)); } bool MayNeedRelaxation(const MCInst &Inst, @@ -91,6 +91,8 @@ bool X86AsmBackend::MayNeedRelaxation(const MCInst &Inst, const SmallVectorImpl &Fixups) const { for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { + const MCAsmFixup &F = Fixups[i]; + // We don't support relaxing anything else currently. Make sure we error out // if we see a non-constant 1 or 2 byte fixup. // @@ -98,13 +100,13 @@ // object writer which should be verifying that any final relocations match // the expected fixup. However, that code is more complicated and hasn't // been written yet. See the FIXMEs in MachObjectWriter.cpp. - if ((Fixups[i].Kind == FK_Data_1 || Fixups[i].Kind == FK_Data_2) && - !isa(Fixups[i].Value)) + if ((F.getKind() == FK_Data_1 || F.getKind() == FK_Data_2) && + !isa(F.getValue())) report_fatal_error("unexpected small fixup with a non-constant operand!"); // Check for a 1byte pcrel fixup, and enforce that we would know how to // relax this instruction. - if (unsigned(Fixups[i].Kind) == X86::reloc_pcrel_1byte) { + if (unsigned(F.getKind()) == X86::reloc_pcrel_1byte) { assert(getRelaxedOpcode(Inst.getOpcode()) != Inst.getOpcode()); return true; } From daniel at zuster.org Wed May 26 10:18:41 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 26 May 2010 15:18:41 -0000 Subject: [llvm-commits] [llvm] r104698 - /llvm/trunk/include/llvm/MC/MCFixup.h Message-ID: <20100526151841.1CE0B312800A@llvm.org> Author: ddunbar Date: Wed May 26 10:18:40 2010 New Revision: 104698 URL: http://llvm.org/viewvc/llvm-project?rev=104698&view=rev Log: MC: Simplify MCFixup and increase the available offset size. Modified: llvm/trunk/include/llvm/MC/MCFixup.h Modified: llvm/trunk/include/llvm/MC/MCFixup.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCFixup.h?rev=104698&r1=104697&r2=104698&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCFixup.h (original) +++ llvm/trunk/include/llvm/MC/MCFixup.h Wed May 26 10:18:40 2010 @@ -10,26 +10,12 @@ #ifndef LLVM_MC_MCFIXUP_H #define LLVM_MC_MCFIXUP_H +#include "llvm/System/DataTypes.h" #include namespace llvm { class MCExpr; -// Private constants, do not use. -// -// This is currently laid out so that the MCFixup fields can be efficiently -// accessed, while keeping the offset field large enough that the assembler -// backend can reasonably use the MCFixup representation for an entire fragment -// (splitting any overly large fragments). -// -// The division of bits between the kind and the opindex can be tweaked if we -// end up needing more bits for target dependent kinds. -enum { - MCFIXUP_NUM_GENERIC_KINDS = 128, - MCFIXUP_NUM_KIND_BITS = 16, - MCFIXUP_NUM_OFFSET_BITS = (32 - MCFIXUP_NUM_KIND_BITS) -}; - /// MCFixupKind - Extensible enumeration to represent the type of a fixup. enum MCFixupKind { FK_Data_1 = 0, ///< A one-byte fixup. @@ -37,12 +23,14 @@ FK_Data_4, ///< A four-byte fixup. FK_Data_8, ///< A eight-byte fixup. - FirstTargetFixupKind = MCFIXUP_NUM_GENERIC_KINDS, + FirstTargetFixupKind = 128, - MaxTargetFixupKind = (1 << MCFIXUP_NUM_KIND_BITS) + // Limit range of target fixups, in case we want to pack more efficiently + // later. + MaxTargetFixupKind = (1 << 8) }; -/// MCFixup - Encode information on a single operation to perform on an byte +/// MCFixup - Encode information on a single operation to perform on a byte /// sequence (e.g., an encoded instruction) which requires assemble- or run- /// time patching. /// @@ -57,36 +45,33 @@ /// fixups become relocations in the object file (or errors, if the fixup cannot /// be encoded on the target). class MCFixup { - static const unsigned MaxOffset = 1 << MCFIXUP_NUM_KIND_BITS; - /// The value to put into the fixup location. The exact interpretation of the - /// expression is target dependent, usually it will one of the operands to an - /// instruction or an assembler directive. + /// expression is target dependent, usually it will be one of the operands to + /// an instruction or an assembler directive. const MCExpr *Value; /// The byte index of start of the relocation inside the encoded instruction. - unsigned Offset : MCFIXUP_NUM_OFFSET_BITS; + uint32_t Offset; /// The target dependent kind of fixup item this is. The kind is used to /// determine how the operand value should be encoded into the instruction. - unsigned Kind : MCFIXUP_NUM_KIND_BITS; + unsigned Kind; public: - static MCFixup Create(unsigned Offset, const MCExpr *Value, + static MCFixup Create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind) { + assert(unsigned(Kind) < MaxTargetFixupKind && "Kind out of range!"); MCFixup FI; FI.Value = Value; FI.Offset = Offset; FI.Kind = unsigned(Kind); - - assert(Offset == FI.getOffset() && "Offset out of range!"); - assert(Kind == FI.getKind() && "Kind out of range!"); return FI; } MCFixupKind getKind() const { return MCFixupKind(Kind); } - unsigned getOffset() const { return Offset; } + uint32_t getOffset() const { return Offset; } + void setOffset(uint32_t Value) { Offset = Value; } const MCExpr *getValue() const { return Value; } From daniel at zuster.org Wed May 26 10:18:56 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 26 May 2010 15:18:56 -0000 Subject: [llvm-commits] [llvm] r104699 - in /llvm/trunk: include/llvm/MC/MCAssembler.h include/llvm/MC/MCObjectWriter.h include/llvm/MC/MachObjectWriter.h include/llvm/Target/TargetAsmBackend.h lib/MC/MCAssembler.cpp lib/MC/MCMachOStreamer.cpp lib/MC/MachObjectWriter.cpp lib/Target/X86/X86AsmBackend.cpp Message-ID: <20100526151856.8F889312800A@llvm.org> Author: ddunbar Date: Wed May 26 10:18:56 2010 New Revision: 104699 URL: http://llvm.org/viewvc/llvm-project?rev=104699&view=rev Log: MC: Eliminate MCAsmFixup, replace with MCFixup. Modified: llvm/trunk/include/llvm/MC/MCAssembler.h llvm/trunk/include/llvm/MC/MCObjectWriter.h llvm/trunk/include/llvm/MC/MachObjectWriter.h llvm/trunk/include/llvm/Target/TargetAsmBackend.h llvm/trunk/lib/MC/MCAssembler.cpp llvm/trunk/lib/MC/MCMachOStreamer.cpp llvm/trunk/lib/MC/MachObjectWriter.cpp llvm/trunk/lib/Target/X86/X86AsmBackend.cpp Modified: llvm/trunk/include/llvm/MC/MCAssembler.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAssembler.h?rev=104699&r1=104698&r2=104699&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCAssembler.h (original) +++ llvm/trunk/include/llvm/MC/MCAssembler.h Wed May 26 10:18:56 2010 @@ -36,33 +36,6 @@ class MCValue; class TargetAsmBackend; -/// MCAsmFixup - Represent a fixed size region of bytes inside some fragment -/// which needs to be rewritten. This region will either be rewritten by the -/// assembler or cause a relocation entry to be generated. -// -// FIXME: This should probably just be merged with MCFixup. -class MCAsmFixup { - /// Offset - The offset inside the fragment which needs to be rewritten. - uint64_t Offset; - - /// Value - The expression to eventually write into the fragment. - const MCExpr *Value; - - /// Kind - The fixup kind. - MCFixupKind Kind; - -public: - MCAsmFixup(uint64_t _Offset, const MCExpr &_Value, MCFixupKind _Kind) - : Offset(_Offset), Value(&_Value), Kind(_Kind) {} - - MCFixupKind getKind() const { return MCFixupKind(Kind); } - - uint64_t getOffset() const { return Offset; } - void setOffset(uint64_t Value) { Offset = Value; } - - const MCExpr *getValue() const { return Value; } -}; - class MCFragment : public ilist_node { friend class MCAsmLayout; @@ -135,11 +108,11 @@ SmallString<32> Contents; /// Fixups - The list of fixups in this fragment. - std::vector Fixups; + std::vector Fixups; public: - typedef std::vector::const_iterator const_fixup_iterator; - typedef std::vector::iterator fixup_iterator; + typedef std::vector::const_iterator const_fixup_iterator; + typedef std::vector::iterator fixup_iterator; public: MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {} @@ -154,15 +127,15 @@ /// @name Fixup Access /// @{ - void addFixup(MCAsmFixup Fixup) { + void addFixup(MCFixup Fixup) { // Enforce invariant that fixups are in offset order. assert((Fixups.empty() || Fixup.getOffset() > Fixups.back().getOffset()) && "Fixups must be added in order!"); Fixups.push_back(Fixup); } - std::vector &getFixups() { return Fixups; } - const std::vector &getFixups() const { return Fixups; } + std::vector &getFixups() { return Fixups; } + const std::vector &getFixups() const { return Fixups; } fixup_iterator fixup_begin() { return Fixups.begin(); } const_fixup_iterator fixup_begin() const { return Fixups.begin(); } @@ -193,11 +166,11 @@ SmallString<8> Code; /// Fixups - The list of fixups in this fragment. - SmallVector Fixups; + SmallVector Fixups; public: - typedef SmallVectorImpl::const_iterator const_fixup_iterator; - typedef SmallVectorImpl::iterator fixup_iterator; + typedef SmallVectorImpl::const_iterator const_fixup_iterator; + typedef SmallVectorImpl::iterator fixup_iterator; public: MCInstFragment(MCInst _Inst, MCSectionData *SD = 0) @@ -221,8 +194,8 @@ /// @name Fixup Access /// @{ - SmallVectorImpl &getFixups() { return Fixups; } - const SmallVectorImpl &getFixups() const { return Fixups; } + SmallVectorImpl &getFixups() { return Fixups; } + const SmallVectorImpl &getFixups() const { return Fixups; } fixup_iterator fixup_begin() { return Fixups.begin(); } const_fixup_iterator fixup_begin() const { return Fixups.begin(); } @@ -633,12 +606,12 @@ /// \arg Value result is fixed, otherwise the value may change due to /// relocation. bool EvaluateFixup(const MCAsmLayout &Layout, - const MCAsmFixup &Fixup, const MCFragment *DF, + const MCFixup &Fixup, const MCFragment *DF, MCValue &Target, uint64_t &Value) const; /// Check whether a fixup can be satisfied, or whether it needs to be relaxed /// (increased in size, in order to hold its value correctly). - bool FixupNeedsRelaxation(const MCAsmFixup &Fixup, const MCFragment *DF, + bool FixupNeedsRelaxation(const MCFixup &Fixup, const MCFragment *DF, const MCAsmLayout &Layout) const; /// Check whether the given fragment needs relaxation. Modified: llvm/trunk/include/llvm/MC/MCObjectWriter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCObjectWriter.h?rev=104699&r1=104698&r2=104699&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCObjectWriter.h (original) +++ llvm/trunk/include/llvm/MC/MCObjectWriter.h Wed May 26 10:18:56 2010 @@ -15,9 +15,9 @@ #include namespace llvm { -class MCAsmFixup; class MCAsmLayout; class MCAssembler; +class MCFixup; class MCFragment; class MCValue; class raw_ostream; @@ -72,7 +72,7 @@ virtual void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, - const MCAsmFixup &Fixup, MCValue Target, + const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue) = 0; /// Write the object file. Modified: llvm/trunk/include/llvm/MC/MachObjectWriter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MachObjectWriter.h?rev=104699&r1=104698&r2=104699&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MachObjectWriter.h (original) +++ llvm/trunk/include/llvm/MC/MachObjectWriter.h Wed May 26 10:18:56 2010 @@ -15,9 +15,9 @@ #include namespace llvm { -class MCAsmFixup; class MCAssembler; class MCFragment; +class MCFixup; class MCValue; class raw_ostream; @@ -33,7 +33,7 @@ virtual void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, - const MCAsmFixup &Fixup, MCValue Target, + const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue); virtual void WriteObject(const MCAssembler &Asm, const MCAsmLayout &Layout); Modified: llvm/trunk/include/llvm/Target/TargetAsmBackend.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetAsmBackend.h?rev=104699&r1=104698&r2=104699&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetAsmBackend.h (original) +++ llvm/trunk/include/llvm/Target/TargetAsmBackend.h Wed May 26 10:18:56 2010 @@ -13,8 +13,8 @@ #include "llvm/System/DataTypes.h" namespace llvm { -class MCAsmFixup; class MCDataFragment; +class MCFixup; class MCInst; class MCInstFragment; class MCObjectWriter; @@ -105,7 +105,7 @@ /// ApplyFixup - Apply the \arg Value for given \arg Fixup into the provided /// data fragment, at the offset specified by the fixup and following the /// fixup kind as appropriate. - virtual void ApplyFixup(const MCAsmFixup &Fixup, MCDataFragment &Fragment, + virtual void ApplyFixup(const MCFixup &Fixup, MCDataFragment &Fragment, uint64_t Value) const = 0; /// MayNeedRelaxation - Check whether the given instruction may need @@ -115,7 +115,7 @@ /// \arg Fixups - The actual fixups this instruction encoded to, for potential /// use by the target backend. virtual bool MayNeedRelaxation(const MCInst &Inst, - const SmallVectorImpl &Fixups) const = 0; + const SmallVectorImpl &Fixups) const = 0; /// RelaxInstruction - Relax the instruction in the given fragment to the next /// wider instruction. Modified: llvm/trunk/lib/MC/MCAssembler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=104699&r1=104698&r2=104699&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCAssembler.cpp (original) +++ llvm/trunk/lib/MC/MCAssembler.cpp Wed May 26 10:18:56 2010 @@ -226,7 +226,7 @@ } static bool isScatteredFixupFullyResolvedSimple(const MCAssembler &Asm, - const MCAsmFixup &Fixup, + const MCFixup &Fixup, const MCValue Target, const MCSection *BaseSection) { // The effective fixup address is @@ -264,7 +264,7 @@ static bool isScatteredFixupFullyResolved(const MCAssembler &Asm, const MCAsmLayout &Layout, - const MCAsmFixup &Fixup, + const MCFixup &Fixup, const MCValue Target, const MCSymbolData *BaseSymbol) { // The effective fixup address is @@ -343,7 +343,7 @@ } bool MCAssembler::EvaluateFixup(const MCAsmLayout &Layout, - const MCAsmFixup &Fixup, const MCFragment *DF, + const MCFixup &Fixup, const MCFragment *DF, MCValue &Target, uint64_t &Value) const { ++stats::EvaluateFixup; @@ -740,7 +740,7 @@ for (MCDataFragment::fixup_iterator it3 = DF->fixup_begin(), ie3 = DF->fixup_end(); it3 != ie3; ++it3) { - MCAsmFixup &Fixup = *it3; + MCFixup &Fixup = *it3; // Evaluate the fixup. MCValue Target; @@ -764,7 +764,7 @@ stats::ObjectBytes += OS.tell() - StartOffset; } -bool MCAssembler::FixupNeedsRelaxation(const MCAsmFixup &Fixup, +bool MCAssembler::FixupNeedsRelaxation(const MCFixup &Fixup, const MCFragment *DF, const MCAsmLayout &Layout) const { if (getRelaxAll()) @@ -841,11 +841,9 @@ IF->setInst(Relaxed); IF->getCode() = Code; IF->getFixups().clear(); - for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { - MCFixup &F = Fixups[i]; - IF->getFixups().push_back(MCAsmFixup(F.getOffset(), *F.getValue(), - F.getKind())); - } + // FIXME: Eliminate copy. + for (unsigned i = 0, e = Fixups.size(); i != e; ++i) + IF->getFixups().push_back(Fixups[i]); // Update the layout, and remember that we relaxed. If we are relaxing // everything, we can skip this step since nothing will depend on updating @@ -904,8 +902,8 @@ namespace llvm { -raw_ostream &operator<<(raw_ostream &OS, const MCAsmFixup &AF) { - OS << ""; return OS; Modified: llvm/trunk/lib/MC/MCMachOStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCMachOStreamer.cpp?rev=104699&r1=104698&r2=104699&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCMachOStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCMachOStreamer.cpp Wed May 26 10:18:56 2010 @@ -376,8 +376,9 @@ for (unsigned i = 0; i != Size; ++i) DF->getContents().push_back(uint8_t(AbsValue >> (i * 8))); } else { - DF->addFixup(MCAsmFixup(DF->getContents().size(), *AddValueSymbols(Value), - MCFixup::getKindForSize(Size))); + DF->addFixup(MCFixup::Create(DF->getContents().size(), + AddValueSymbols(Value), + MCFixup::getKindForSize(Size))); DF->getContents().resize(DF->getContents().size() + Size, 0); } } @@ -434,12 +435,9 @@ VecOS.flush(); // FIXME: Eliminate this copy. - SmallVector AsmFixups; - for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { - MCFixup &F = Fixups[i]; - AsmFixups.push_back(MCAsmFixup(F.getOffset(), *F.getValue(), - F.getKind())); - } + SmallVector AsmFixups; + for (unsigned i = 0, e = Fixups.size(); i != e; ++i) + AsmFixups.push_back(Fixups[i]); // See if we might need to relax this instruction, if so it needs its own // fragment. Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=104699&r1=104698&r2=104699&view=diff ============================================================================== --- llvm/trunk/lib/MC/MachObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/MachObjectWriter.cpp Wed May 26 10:18:56 2010 @@ -472,7 +472,7 @@ void RecordX86_64Relocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, - const MCAsmFixup &Fixup, MCValue Target, + const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue) { unsigned IsPCRel = isFixupKindPCRel(Fixup.getKind()); unsigned IsRIPRel = isFixupKindRIPRel(Fixup.getKind()); @@ -682,7 +682,7 @@ void RecordScatteredRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, - const MCAsmFixup &Fixup, MCValue Target, + const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue) { uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); unsigned IsPCRel = isFixupKindPCRel(Fixup.getKind()); @@ -739,7 +739,7 @@ } void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, - const MCFragment *Fragment, const MCAsmFixup &Fixup, + const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue) { if (Is64Bit) { RecordX86_64Relocation(Asm, Layout, Fragment, Fixup, Target, FixedValue); @@ -1168,7 +1168,7 @@ void MachObjectWriter::RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, - const MCAsmFixup &Fixup, MCValue Target, + const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue) { ((MachObjectWriterImpl*) Impl)->RecordRelocation(Asm, Layout, Fragment, Fixup, Target, FixedValue); Modified: llvm/trunk/lib/Target/X86/X86AsmBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86AsmBackend.cpp?rev=104699&r1=104698&r2=104699&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86AsmBackend.cpp (original) +++ llvm/trunk/lib/Target/X86/X86AsmBackend.cpp Wed May 26 10:18:56 2010 @@ -44,7 +44,7 @@ X86AsmBackend(const Target &T) : TargetAsmBackend(T) {} - void ApplyFixup(const MCAsmFixup &Fixup, MCDataFragment &DF, + void ApplyFixup(const MCFixup &Fixup, MCDataFragment &DF, uint64_t Value) const { unsigned Size = 1 << getFixupKindLog2Size(Fixup.getKind()); @@ -55,7 +55,7 @@ } bool MayNeedRelaxation(const MCInst &Inst, - const SmallVectorImpl &Fixups) const; + const SmallVectorImpl &Fixups) const; void RelaxInstruction(const MCInstFragment *IF, MCInst &Res) const; @@ -89,9 +89,9 @@ } bool X86AsmBackend::MayNeedRelaxation(const MCInst &Inst, - const SmallVectorImpl &Fixups) const { + const SmallVectorImpl &Fixups) const { for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { - const MCAsmFixup &F = Fixups[i]; + const MCFixup &F = Fixups[i]; // We don't support relaxing anything else currently. Make sure we error out // if we see a non-constant 1 or 2 byte fixup. From grosbach at apple.com Wed May 26 11:21:41 2010 From: grosbach at apple.com (Jim Grosbach) Date: Wed, 26 May 2010 16:21:41 -0000 Subject: [llvm-commits] [llvm] r104703 - /llvm/trunk/docs/ExceptionHandling.html Message-ID: <20100526162141.543F4312800A@llvm.org> Author: grosbach Date: Wed May 26 11:21:41 2010 New Revision: 104703 URL: http://llvm.org/viewvc/llvm-project?rev=104703&view=rev Log: Add entry for llvm.eh.sjlj.longjmp. PR4999. Modified: llvm/trunk/docs/ExceptionHandling.html Modified: llvm/trunk/docs/ExceptionHandling.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/ExceptionHandling.html?rev=104703&r1=104702&r2=104703&view=diff ============================================================================== --- llvm/trunk/docs/ExceptionHandling.html (original) +++ llvm/trunk/docs/ExceptionHandling.html Wed May 26 11:21:41 2010 @@ -492,6 +492,26 @@

+ +
+ +
+  void %llvm.eh.sjlj.setjmp(i8*)
+
+ +

The llvm.eh.sjlj.longjmp + intrinsic is used to implement __builtin_longjmp() for SJLJ + style exception handling. The single parameter is a pointer to a + buffer populated by + llvm.eh.sjlj.setjmp. The frame pointer and stack pointer + are restored from the buffer, then control is transfered to the + destination address.

+ +
+ + From stoklund at 2pi.dk Wed May 26 12:27:12 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 26 May 2010 17:27:12 -0000 Subject: [llvm-commits] [llvm] r104704 - in /llvm/trunk: include/llvm/Target/Target.td lib/Target/ARM/ARMRegisterInfo.td lib/Target/Blackfin/BlackfinRegisterInfo.td lib/Target/MBlaze/MBlazeRegisterInfo.td lib/Target/MSP430/MSP430RegisterInfo.td lib/Target/Mips/MipsRegisterInfo.td lib/Target/PowerPC/PPCRegisterInfo.td lib/Target/Sparc/SparcRegisterInfo.td lib/Target/SystemZ/SystemZRegisterInfo.td lib/Target/X86/X86RegisterInfo.td utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <20100526172712.69519312800A@llvm.org> Author: stoklund Date: Wed May 26 12:27:12 2010 New Revision: 104704 URL: http://llvm.org/viewvc/llvm-project?rev=104704&view=rev Log: Replace the SubRegSet tablegen class with a less error-prone mechanism. A Register with subregisters must also provide SubRegIndices for adressing the subregisters. TableGen automatically inherits indices for sub-subregisters to minimize typing. CompositeIndices may be specified for the weirder cases such as the XMM sub_sd index that returns the same register, and ARM NEON Q registers where both D subregs have ssub_0 and ssub_1 sub-subregs. It is now required that all subregisters are named by an index, and a future patch will also require inherited subregisters to be named. This is necessary to allow composite subregister indices to be reduced to a single index. Modified: llvm/trunk/include/llvm/Target/Target.td llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.td llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td llvm/trunk/lib/Target/X86/X86RegisterInfo.td llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Modified: llvm/trunk/include/llvm/Target/Target.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=104704&r1=104703&r2=104704&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/Target.td (original) +++ llvm/trunk/include/llvm/Target/Target.td Wed May 26 12:27:12 2010 @@ -54,6 +54,23 @@ // not [AX, AH, AL]. list SubRegs = []; + // SubRegIndices - For each register in SubRegs, specify the SubRegIndex used + // to address it. Sub-sub-register indices are automatically inherited from + // SubRegs. + list SubRegIndices = []; + + // CompositeIndices - Specify subreg indices that don't correspond directly to + // a register in SubRegs and are not inherited. The following formats are + // supported: + // + // (a) Identity - Reg:a == Reg + // (a b) Alias - Reg:a == Reg:b + // (a b,c) Composite - Reg:a == (Reg:b):c + // + // This can be used to disambiguate a sub-sub-register that exists in more + // than one subregister and other weird stuff. + list CompositeIndices = []; + // DwarfNumbers - Numbers used internally by gcc/gdb to identify the register. // These values can be determined by locating the .h file in the // directory llvmgcc/gcc/config// and looking for REGISTER_NAMES. The @@ -73,17 +90,6 @@ let SubRegs = subregs; } -// SubRegSet - This can be used to define a specific mapping of registers to -// indices, for use as named subregs of a particular physical register. Each -// register in 'subregs' becomes an addressable subregister at index 'n' of the -// corresponding register in 'regs'. -class SubRegSet regs, list subregs> { - SubRegIndex Index = n; - - list From = regs; - list To = subregs; -} - // RegisterClass - Now that all of the registers are defined, and aliases // between registers are defined, specify which registers belong to which // register classes. This also defines the default allocation order of Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td?rev=104704&r1=104703&r2=104704&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td Wed May 26 12:27:12 2010 @@ -86,6 +86,7 @@ def S30 : ARMFReg<30, "s30">; def S31 : ARMFReg<31, "s31">; // Aliases of the F* registers used to hold 64-bit fp values (doubles) +let SubRegIndices = [ssub_0, ssub_1] in { def D0 : ARMReg< 0, "d0", [S0, S1]>; def D1 : ARMReg< 1, "d1", [S2, S3]>; def D2 : ARMReg< 2, "d2", [S4, S5]>; @@ -102,6 +103,7 @@ def D13 : ARMReg<13, "d13", [S26, S27]>; def D14 : ARMReg<14, "d14", [S28, S29]>; def D15 : ARMReg<15, "d15", [S30, S31]>; +} // VFP3 defines 16 additional double registers def D16 : ARMFReg<16, "d16">; def D17 : ARMFReg<17, "d17">; @@ -114,6 +116,9 @@ def D30 : ARMFReg<30, "d30">; def D31 : ARMFReg<31, "d31">; // Advanced SIMD (NEON) defines 16 quad-word aliases +let SubRegIndices = [dsub_0, dsub_1], + CompositeIndices = [(ssub_2 dsub_1, ssub_0), + (ssub_3 dsub_1, ssub_1)] in { def Q0 : ARMReg< 0, "q0", [D0, D1]>; def Q1 : ARMReg< 1, "q1", [D2, D3]>; def Q2 : ARMReg< 2, "q2", [D4, D5]>; @@ -122,6 +127,8 @@ def Q5 : ARMReg< 5, "q5", [D10, D11]>; def Q6 : ARMReg< 6, "q6", [D12, D13]>; def Q7 : ARMReg< 7, "q7", [D14, D15]>; +} +let SubRegIndices = [dsub_0, dsub_1] in { def Q8 : ARMReg< 8, "q8", [D16, D17]>; def Q9 : ARMReg< 9, "q9", [D18, D19]>; def Q10 : ARMReg<10, "q10", [D20, D21]>; @@ -130,6 +137,7 @@ def Q13 : ARMReg<13, "q13", [D26, D27]>; def Q14 : ARMReg<14, "q14", [D28, D29]>; def Q15 : ARMReg<15, "q15", [D30, D31]>; +} // Pseudo 256-bit registers to represent pairs of Q registers. These should // never be present in the emitted code. @@ -138,6 +146,9 @@ // starting D register number doesn't have to be multiple of 4. e.g. // D1, D2, D3, D4 would be a legal quad. But that would make the sub-register // stuffs very messy. +let SubRegIndices = [qsub_0, qsub_1], + CompositeIndices = [(dsub_2 qsub_1, dsub_0), + (dsub_3 qsub_1, dsub_1)] in { def QQ0 : ARMReg<0, "qq0", [Q0, Q1]>; def QQ1 : ARMReg<1, "qq1", [Q2, Q3]>; def QQ2 : ARMReg<2, "qq2", [Q4, Q5]>; @@ -146,12 +157,21 @@ def QQ5 : ARMReg<5, "qq5", [Q10, Q11]>; def QQ6 : ARMReg<6, "qq6", [Q12, Q13]>; def QQ7 : ARMReg<7, "qq7", [Q14, Q15]>; +} // Pseudo 512-bit registers to represent four consecutive Q registers. +let SubRegIndices = [qqsub_0, qqsub_1], + CompositeIndices = [(qsub_2 qqsub_1, qsub_0), + (qsub_3 qqsub_1, qsub_1), + (dsub_4 qqsub_1, dsub_0), + (dsub_5 qqsub_1, dsub_1), + (dsub_6 qqsub_1, dsub_2), + (dsub_7 qqsub_1, dsub_3)] in { def QQQQ0 : ARMReg<0, "qqqq0", [QQ0, QQ1]>; def QQQQ1 : ARMReg<1, "qqqq1", [QQ2, QQ3]>; def QQQQ2 : ARMReg<2, "qqqq2", [QQ4, QQ5]>; def QQQQ3 : ARMReg<3, "qqqq3", [QQ6, QQ7]>; +} // Current Program Status Register. def CPSR : ARMReg<0, "cpsr">; @@ -438,102 +458,3 @@ // Condition code registers. def CCR : RegisterClass<"ARM", [i32], 32, [CPSR]>; -//===----------------------------------------------------------------------===// -// Subregister Set Definitions... now that we have all of the pieces, define the -// sub registers for each register. -// - -// S sub-registers of D registers. -def : SubRegSet; -def : SubRegSet; - -// S sub-registers of Q registers. -def : SubRegSet; -def : SubRegSet; -def : SubRegSet; -def : SubRegSet; - -// D sub-registers of Q registers. -def : SubRegSet; -def : SubRegSet; - -// S sub-registers of QQ registers. Note there are no sub-indices -// for referencing S4 - S7, S12 - S15, and S20 - S23. It doesn't -// look like we need them. -def : SubRegSet; -def : SubRegSet; -def : SubRegSet; -def : SubRegSet; - -// D sub-registers of QQ registers. -def : SubRegSet; -def : SubRegSet; -def : SubRegSet; -def : SubRegSet; - -// Q sub-registers of QQ registers. -def : SubRegSet; -def : SubRegSet; - - -// D sub-registers of QQQQ registers. -def : SubRegSet; -def : SubRegSet; -def : SubRegSet; -def : SubRegSet; - -def : SubRegSet; -def : SubRegSet; -def : SubRegSet; -def : SubRegSet; - -// Q sub-registers of QQQQ registers. -def : SubRegSet; -def : SubRegSet; -def : SubRegSet; -def : SubRegSet; - -// QQ sub-registers of QQQQ registers. -def : SubRegSet; -def : SubRegSet; - Modified: llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td?rev=104704&r1=104703&r2=104704&view=diff ============================================================================== --- llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td (original) +++ llvm/trunk/lib/Target/Blackfin/BlackfinRegisterInfo.td Wed May 26 12:27:12 2010 @@ -19,6 +19,7 @@ def lo16 : SubRegIndex; def hi16 : SubRegIndex; def lo32 : SubRegIndex; +def hi32 : SubRegIndex; } // Registers are identified with 3-bit group and 3-bit ID numbers. @@ -49,6 +50,7 @@ // Ra 40-bit accumulator registers class Ra num, string n, list subs> : BlackfinReg { let SubRegs = subs; + let SubRegIndices = [hi32, lo32]; let Group = 4; let Num = num; } @@ -63,6 +65,7 @@ class Rii group, bits<3> num, string n, list subs> : BlackfinReg { let SubRegs = subs; + let SubRegIndices = [hi16, lo16]; let Group = group; let Num = num; } @@ -173,7 +176,7 @@ def RETE : Ri<7, 6, "rete">, DwarfRegNum<[39]>; def ASTAT : Ri<4, 6, "astat">, DwarfRegNum<[40]> { - let SubRegs = [AZ, AN, CC, NCC, AQ, AC0, AC1, AV0, AV0S, AV1, AV1S, V, VS]; + let Aliases = [AZ, AN, CC, NCC, AQ, AC0, AC1, AV0, AV0S, AV1, AV1S, V, VS]; } def SEQSTAT : Ri<7, 1, "seqstat">, DwarfRegNum<[41]>; @@ -191,29 +194,6 @@ def LB0 : Ri<6, 2, "lb0">, DwarfRegNum<[48]>; def LB1 : Ri<6, 5, "lb1">, DwarfRegNum<[49]>; -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; -def : SubRegSet; - // Register classes. def D16 : RegisterClass<"BF", [i16], 16, [R0H, R0L, R1H, R1L, R2H, R2L, R3H, R3L, Modified: llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.td?rev=104704&r1=104703&r2=104704&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.td (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeRegisterInfo.td Wed May 26 12:27:12 2010 @@ -17,21 +17,15 @@ let Namespace = "MBlaze"; } -class MBlazeRegWithSubRegs subregs> - : RegisterWithSubRegs { - field bits<5> Num; - let Namespace = "MBlaze"; -} - // MBlaze CPU Registers class MBlazeGPRReg num, string n> : MBlazeReg { let Num = num; } // MBlaze 32-bit (aliased) FPU Registers -class FPR num, string n, list subregs> - : MBlazeRegWithSubRegs { +class FPR num, string n, list aliases> : MBlazeReg { let Num = num; + let Aliases = aliases; } //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td?rev=104704&r1=104703&r2=104704&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td (original) +++ llvm/trunk/lib/Target/MSP430/MSP430RegisterInfo.td Wed May 26 12:27:12 2010 @@ -43,6 +43,9 @@ def R14B : MSP430Reg<14, "r14">; def R15B : MSP430Reg<15, "r15">; +def subreg_8bit : SubRegIndex { let Namespace = "MSP430"; } + +let SubRegIndices = [subreg_8bit] in { def PCW : MSP430RegWithSubregs<0, "r0", [PCB]>; def SPW : MSP430RegWithSubregs<1, "r1", [SPB]>; def SRW : MSP430RegWithSubregs<2, "r2", [SRB]>; @@ -59,13 +62,7 @@ def R13W : MSP430RegWithSubregs<13, "r13", [R13B]>; def R14W : MSP430RegWithSubregs<14, "r14", [R14B]>; def R15W : MSP430RegWithSubregs<15, "r15", [R15B]>; - -def subreg_8bit : SubRegIndex { let Namespace = "MSP430"; } - -def : SubRegSet; +} def GR8 : RegisterClass<"MSP430", [i8], 8, // Volatile registers Modified: llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td?rev=104704&r1=104703&r2=104704&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td (original) +++ llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td Wed May 26 12:27:12 2010 @@ -34,9 +34,14 @@ } // Mips 64-bit (aliased) FPU Registers -class AFPR num, string n, list subregs> +let Namespace = "Mips" in { +def sub_fpeven : SubRegIndex; +def sub_fpodd : SubRegIndex; +} +class AFPR num, string n, list subregs> : MipsRegWithSubRegs { let Num = num; + let SubRegIndices = [sub_fpeven, sub_fpodd]; } //===----------------------------------------------------------------------===// @@ -141,25 +146,6 @@ } //===----------------------------------------------------------------------===// -// Subregister Set Definitions -//===----------------------------------------------------------------------===// - -let Namespace = "Mips" in { -def sub_fpeven : SubRegIndex; -def sub_fpodd : SubRegIndex; -} - -def : SubRegSet; - -def : SubRegSet; - -//===----------------------------------------------------------------------===// // Register Classes //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td?rev=104704&r1=104703&r2=104704&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td (original) +++ llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.td Wed May 26 12:27:12 2010 @@ -10,6 +10,15 @@ // //===----------------------------------------------------------------------===// +let Namespace = "PPC" in { +def sub_lt : SubRegIndex; +def sub_gt : SubRegIndex; +def sub_eq : SubRegIndex; +def sub_un : SubRegIndex; +def sub_32 : SubRegIndex; +} + + class PPCReg : Register { let Namespace = "PPC"; } @@ -25,6 +34,7 @@ class GP8 : PPCReg { field bits<5> Num = SubReg.Num; let SubRegs = [SubReg]; + let SubRegIndices = [sub_32]; } // SPR - One of the 32-bit special-purpose registers @@ -225,6 +235,7 @@ def CR7UN : CRBIT<31, "31">, DwarfRegNum<[0]>; // Condition registers +let SubRegIndices = [sub_lt, sub_gt, sub_eq, sub_un] in { def CR0 : CR<0, "cr0", [CR0LT, CR0GT, CR0EQ, CR0UN]>, DwarfRegNum<[68]>; def CR1 : CR<1, "cr1", [CR1LT, CR1GT, CR1EQ, CR1UN]>, DwarfRegNum<[69]>; def CR2 : CR<2, "cr2", [CR2LT, CR2GT, CR2EQ, CR2UN]>, DwarfRegNum<[70]>; @@ -233,27 +244,8 @@ def CR5 : CR<5, "cr5", [CR5LT, CR5GT, CR5EQ, CR5UN]>, DwarfRegNum<[73]>; def CR6 : CR<6, "cr6", [CR6LT, CR6GT, CR6EQ, CR6UN]>, DwarfRegNum<[74]>; def CR7 : CR<7, "cr7", [CR7LT, CR7GT, CR7EQ, CR7UN]>, DwarfRegNum<[75]>; - -let Namespace = "PPC" in { -def sub_lt : SubRegIndex; -def sub_gt : SubRegIndex; -def sub_eq : SubRegIndex; -def sub_un : SubRegIndex; } -def : SubRegSet; -def : SubRegSet; -def : SubRegSet; -def : SubRegSet; - // Link register def LR : SPR<8, "lr">, DwarfRegNum<[65]>; //let Aliases = [LR] in Modified: llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td?rev=104704&r1=104703&r2=104704&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td (original) +++ llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td Wed May 26 12:27:12 2010 @@ -20,6 +20,11 @@ let Namespace = "SP"; } +let Namespace = "SP" in { +def sub_even : SubRegIndex; +def sub_odd : SubRegIndex; +} + // Registers are identified with 5-bit ID numbers. // Ri - 32-bit integer registers class Ri num, string n> : SparcReg { @@ -33,6 +38,7 @@ class Rd num, string n, list subregs> : SparcReg { let Num = num; let SubRegs = subregs; + let SubRegIndices = [sub_even, sub_odd]; } // Control Registers Modified: llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td?rev=104704&r1=104703&r2=104704&view=diff ============================================================================== --- llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td (original) +++ llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td Wed May 26 12:27:12 2010 @@ -53,6 +53,14 @@ field bits<4> Num = num; } +let Namespace = "SystemZ" in { +def subreg_32bit : SubRegIndex; +def subreg_even32 : SubRegIndex; +def subreg_odd32 : SubRegIndex; +def subreg_even : SubRegIndex; +def subreg_odd : SubRegIndex; +} + // General-purpose registers def R0W : GPR32< 0, "r0">, DwarfRegNum<[0]>; def R1W : GPR32< 1, "r1">, DwarfRegNum<[1]>; @@ -71,6 +79,7 @@ def R14W : GPR32<14, "r14">, DwarfRegNum<[14]>; def R15W : GPR32<15, "r15">, DwarfRegNum<[15]>; +let SubRegIndices = [subreg_32bit] in { def R0D : GPR64< 0, "r0", [R0W]>, DwarfRegNum<[0]>; def R1D : GPR64< 1, "r1", [R1W]>, DwarfRegNum<[1]>; def R2D : GPR64< 2, "r2", [R2W]>, DwarfRegNum<[2]>; @@ -87,8 +96,10 @@ def R13D : GPR64<13, "r13", [R13W]>, DwarfRegNum<[13]>; def R14D : GPR64<14, "r14", [R14W]>, DwarfRegNum<[14]>; def R15D : GPR64<15, "r15", [R15W]>, DwarfRegNum<[15]>; +} // Register pairs +let SubRegIndices = [subreg_even32, subreg_odd32] in { def R0P : GPR64< 0, "r0", [R0W, R1W], [R0D, R1D]>, DwarfRegNum<[0]>; def R2P : GPR64< 2, "r2", [R2W, R3W], [R2D, R3D]>, DwarfRegNum<[2]>; def R4P : GPR64< 4, "r4", [R4W, R5W], [R4D, R5D]>, DwarfRegNum<[4]>; @@ -97,7 +108,11 @@ def R10P : GPR64<10, "r10", [R10W, R11W], [R10D, R11D]>, DwarfRegNum<[10]>; def R12P : GPR64<12, "r12", [R12W, R13W], [R12D, R13D]>, DwarfRegNum<[12]>; def R14P : GPR64<14, "r14", [R14W, R15W], [R14D, R15D]>, DwarfRegNum<[14]>; +} +let SubRegIndices = [subreg_even, subreg_odd], + CompositeIndices = [(subreg_even32 subreg_even, subreg_32bit), + (subreg_odd32 subreg_odd, subreg_32bit)] in { def R0Q : GPR128< 0, "r0", [R0D, R1D], [R0P]>, DwarfRegNum<[0]>; def R2Q : GPR128< 2, "r2", [R2D, R3D], [R2P]>, DwarfRegNum<[2]>; def R4Q : GPR128< 4, "r4", [R4D, R5D], [R4P]>, DwarfRegNum<[4]>; @@ -106,6 +121,7 @@ def R10Q : GPR128<10, "r10", [R10D, R11D], [R10P]>, DwarfRegNum<[10]>; def R12Q : GPR128<12, "r12", [R12D, R13D], [R12P]>, DwarfRegNum<[12]>; def R14Q : GPR128<14, "r14", [R14D, R15D], [R14P]>, DwarfRegNum<[14]>; +} // Floating-point registers def F0S : FPRS< 0, "f0">, DwarfRegNum<[16]>; @@ -125,6 +141,7 @@ def F14S : FPRS<14, "f14">, DwarfRegNum<[30]>; def F15S : FPRS<15, "f15">, DwarfRegNum<[31]>; +let SubRegIndices = [subreg_32bit] in { def F0L : FPRL< 0, "f0", [F0S]>, DwarfRegNum<[16]>; def F1L : FPRL< 1, "f1", [F1S]>, DwarfRegNum<[17]>; def F2L : FPRL< 2, "f2", [F2S]>, DwarfRegNum<[18]>; @@ -141,41 +158,11 @@ def F13L : FPRL<13, "f13", [F13S]>, DwarfRegNum<[29]>; def F14L : FPRL<14, "f14", [F14S]>, DwarfRegNum<[30]>; def F15L : FPRL<15, "f15", [F15S]>, DwarfRegNum<[31]>; +} // Status register def PSW : SystemZReg<"psw">; -let Namespace = "SystemZ" in { -def subreg_32bit : SubRegIndex; -def subreg_even32 : SubRegIndex; -def subreg_odd32 : SubRegIndex; -def subreg_even : SubRegIndex; -def subreg_odd : SubRegIndex; -} - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - /// Register classes def GR32 : RegisterClass<"SystemZ", [i32], 32, // Volatile registers Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.td?rev=104704&r1=104703&r2=104704&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.td Wed May 26 12:27:12 2010 @@ -68,17 +68,22 @@ def BH : Register<"bh">, DwarfRegNum<[3, 3, 3]>; // 16-bit registers + let SubRegIndices = [sub_8bit, sub_8bit_hi] in { def AX : RegisterWithSubRegs<"ax", [AL,AH]>, DwarfRegNum<[0, 0, 0]>; def DX : RegisterWithSubRegs<"dx", [DL,DH]>, DwarfRegNum<[1, 2, 2]>; def CX : RegisterWithSubRegs<"cx", [CL,CH]>, DwarfRegNum<[2, 1, 1]>; def BX : RegisterWithSubRegs<"bx", [BL,BH]>, DwarfRegNum<[3, 3, 3]>; + } + let SubRegIndices = [sub_8bit] in { def SI : RegisterWithSubRegs<"si", [SIL]>, DwarfRegNum<[4, 6, 6]>; def DI : RegisterWithSubRegs<"di", [DIL]>, DwarfRegNum<[5, 7, 7]>; def BP : RegisterWithSubRegs<"bp", [BPL]>, DwarfRegNum<[6, 4, 5]>; def SP : RegisterWithSubRegs<"sp", [SPL]>, DwarfRegNum<[7, 5, 4]>; + } def IP : Register<"ip">, DwarfRegNum<[16]>; // X86-64 only + let SubRegIndices = [sub_8bit] in { def R8W : RegisterWithSubRegs<"r8w", [R8B]>, DwarfRegNum<[8, -2, -2]>; def R9W : RegisterWithSubRegs<"r9w", [R9B]>, DwarfRegNum<[9, -2, -2]>; def R10W : RegisterWithSubRegs<"r10w", [R10B]>, DwarfRegNum<[10, -2, -2]>; @@ -87,8 +92,9 @@ def R13W : RegisterWithSubRegs<"r13w", [R13B]>, DwarfRegNum<[13, -2, -2]>; def R14W : RegisterWithSubRegs<"r14w", [R14B]>, DwarfRegNum<[14, -2, -2]>; def R15W : RegisterWithSubRegs<"r15w", [R15B]>, DwarfRegNum<[15, -2, -2]>; - + } // 32-bit registers + let SubRegIndices = [sub_16bit] in { def EAX : RegisterWithSubRegs<"eax", [AX]>, DwarfRegNum<[0, 0, 0]>; def EDX : RegisterWithSubRegs<"edx", [DX]>, DwarfRegNum<[1, 2, 2]>; def ECX : RegisterWithSubRegs<"ecx", [CX]>, DwarfRegNum<[2, 1, 1]>; @@ -108,8 +114,10 @@ def R13D : RegisterWithSubRegs<"r13d", [R13W]>, DwarfRegNum<[13, -2, -2]>; def R14D : RegisterWithSubRegs<"r14d", [R14W]>, DwarfRegNum<[14, -2, -2]>; def R15D : RegisterWithSubRegs<"r15d", [R15W]>, DwarfRegNum<[15, -2, -2]>; + } // 64-bit registers, X86-64 only + let SubRegIndices = [sub_32bit] in { def RAX : RegisterWithSubRegs<"rax", [EAX]>, DwarfRegNum<[0, -2, -2]>; def RDX : RegisterWithSubRegs<"rdx", [EDX]>, DwarfRegNum<[1, -2, -2]>; def RCX : RegisterWithSubRegs<"rcx", [ECX]>, DwarfRegNum<[2, -2, -2]>; @@ -128,6 +136,7 @@ def R14 : RegisterWithSubRegs<"r14", [R14D]>, DwarfRegNum<[14, -2, -2]>; def R15 : RegisterWithSubRegs<"r15", [R15D]>, DwarfRegNum<[15, -2, -2]>; def RIP : RegisterWithSubRegs<"rip", [EIP]>, DwarfRegNum<[16, -2, -2]>; + } // MMX Registers. These are actually aliased to ST0 .. ST7 def MM0 : Register<"mm0">, DwarfRegNum<[41, 29, 29]>; @@ -148,7 +157,9 @@ def FP5 : Register<"fp5">; def FP6 : Register<"fp6">; - // XMM Registers, used by the various SSE instruction set extensions + // XMM Registers, used by the various SSE instruction set extensions. + // The sub_ss and sub_sd subregs are the same registers with another regclass. + let CompositeIndices = [(sub_ss), (sub_sd)] in { def XMM0: Register<"xmm0">, DwarfRegNum<[17, 21, 21]>; def XMM1: Register<"xmm1">, DwarfRegNum<[18, 22, 22]>; def XMM2: Register<"xmm2">, DwarfRegNum<[19, 23, 23]>; @@ -167,8 +178,10 @@ def XMM13: Register<"xmm13">, DwarfRegNum<[30, -2, -2]>; def XMM14: Register<"xmm14">, DwarfRegNum<[31, -2, -2]>; def XMM15: Register<"xmm15">, DwarfRegNum<[32, -2, -2]>; + } // YMM Registers, used by AVX instructions + let SubRegIndices = [sub_xmm] in { def YMM0: RegisterWithSubRegs<"ymm0", [XMM0]>, DwarfRegNum<[17, 21, 21]>; def YMM1: RegisterWithSubRegs<"ymm1", [XMM1]>, DwarfRegNum<[18, 22, 22]>; def YMM2: RegisterWithSubRegs<"ymm2", [XMM2]>, DwarfRegNum<[19, 23, 23]>; @@ -185,6 +198,7 @@ def YMM13: RegisterWithSubRegs<"ymm13", [XMM13]>, DwarfRegNum<[30, -2, -2]>; def YMM14: RegisterWithSubRegs<"ymm14", [XMM14]>, DwarfRegNum<[31, -2, -2]>; def YMM15: RegisterWithSubRegs<"ymm15", [XMM15]>, DwarfRegNum<[32, -2, -2]>; + } // Floating point stack registers def ST0 : Register<"st(0)">, DwarfRegNum<[33, 12, 11]>; @@ -231,75 +245,6 @@ //===----------------------------------------------------------------------===// -// Subregister Set Definitions... now that we have all of the pieces, define the -// sub registers for each register. -// - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -def : SubRegSet; - -//===----------------------------------------------------------------------===// // Register Class Definitions... now that we have all of the pieces, define the // top-level register classes. The order specified in the register list is // implicitly defined to be the register allocation order. Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp?rev=104704&r1=104703&r2=104704&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Wed May 26 12:27:12 2010 @@ -171,6 +171,67 @@ addSubSuperReg(R, *I, SubRegs, SuperRegs, Aliases); } +// Map SubRegIndex -> Register +typedef std::map SubRegMap; +// Map Register -> SubRegMap +typedef std::map AllSubRegMap; + +// Calculate all subregindices for Reg. Loopy subregs cause infinite recursion. +static SubRegMap &inferSubRegIndices(Record *Reg, AllSubRegMap &ASRM) { + SubRegMap &SRM = ASRM[Reg]; + if (!SRM.empty()) + return SRM; + std::vector SubRegs = Reg->getValueAsListOfDefs("SubRegs"); + std::vector Indices = Reg->getValueAsListOfDefs("SubRegIndices"); + if (SubRegs.size() != Indices.size()) + throw "Register " + Reg->getName() + " SubRegIndices doesn't match SubRegs"; + + // First insert the direct subregs. + for (unsigned i = 0, e = SubRegs.size(); i != e; ++i) { + if (!SRM.insert(std::make_pair(Indices[i], SubRegs[i])).second) + throw "SubRegIndex " + Indices[i]->getName() + + " appears twice in Register " + Reg->getName(); + inferSubRegIndices(SubRegs[i], ASRM); + } + + // Clone inherited subregs. Here the order is important - earlier subregs take + // precedence. + for (unsigned i = 0, e = SubRegs.size(); i != e; ++i) { + SubRegMap &M = ASRM[SubRegs[i]]; + SRM.insert(M.begin(), M.end()); + } + + // Finally process the composites. + ListInit *Comps = Reg->getValueAsListInit("CompositeIndices"); + for (unsigned i = 0, e = Comps->size(); i != e; ++i) { + DagInit *Pat = dynamic_cast(Comps->getElement(i)); + if (!Pat) + throw "Invalid dag '" + Comps->getElement(i)->getAsString() + + "' in CompositeIndices"; + DefInit *BaseIdxInit = dynamic_cast(Pat->getOperator()); + if (!BaseIdxInit || !BaseIdxInit->getDef()->isSubClassOf("SubRegIndex")) + throw "Invalid SubClassIndex in " + Pat->getAsString(); + + // Resolve list of subreg indices into R2. + Record *R2 = Reg; + for (DagInit::const_arg_iterator di = Pat->arg_begin(), + de = Pat->arg_end(); di != de; ++di) { + DefInit *IdxInit = dynamic_cast(*di); + if (!IdxInit || !IdxInit->getDef()->isSubClassOf("SubRegIndex")) + throw "Invalid SubClassIndex in " + Pat->getAsString(); + SubRegMap::const_iterator ni = ASRM[R2].find(IdxInit->getDef()); + if (ni == ASRM[R2].end()) + throw "Composite " + Pat->getAsString() + " refers to bad index in " + + R2->getName(); + R2 = ni->second; + } + + // Insert composite index. Allow overriding inherited indices etc. + SRM[BaseIdxInit->getDef()] = R2; + } + return SRM; +} + class RegisterSorter { private: std::map, LessRecord> &RegisterSubRegs; @@ -455,8 +516,6 @@ std::map, LessRecord> RegisterSubRegs; std::map, LessRecord> RegisterSuperRegs; std::map, LessRecord> RegisterAliases; - // Register -> [(SubRegIndex, Register)] - std::map > > SubRegVectors; typedef std::map, LessRecord> DwarfRegNumsMapTy; DwarfRegNumsMapTy DwarfRegNums; @@ -748,56 +807,44 @@ std::string ClassName = Target.getName() + "GenRegisterInfo"; // Calculate the mapping of subregister+index pairs to physical registers. - std::vector SubRegs = Records.getAllDerivedDefinitions("SubRegSet"); - for (unsigned i = 0, e = SubRegs.size(); i != e; ++i) { - Record *subRegIndex = SubRegs[i]->getValueAsDef("Index"); - std::vector From = SubRegs[i]->getValueAsListOfDefs("From"); - std::vector To = SubRegs[i]->getValueAsListOfDefs("To"); - - if (From.size() != To.size()) { - errs() << "Error: register list and sub-register list not of equal length" - << " in SubRegSet\n"; - exit(1); - } - - // For each entry in from/to vectors, insert the to register at index - for (unsigned ii = 0, ee = From.size(); ii != ee; ++ii) - SubRegVectors[From[ii]].push_back(std::make_pair(subRegIndex, To[ii])); - } - + AllSubRegMap AllSRM; + // Emit the subregister + index mapping function based on the information // calculated above. - OS << "unsigned " << ClassName + OS << "unsigned " << ClassName << "::getSubReg(unsigned RegNo, unsigned Index) const {\n" << " switch (RegNo) {\n" << " default:\n return 0;\n"; - for (std::map > >::iterator - I = SubRegVectors.begin(), E = SubRegVectors.end(); I != E; ++I) { - OS << " case " << getQualifiedName(I->first) << ":\n"; + for (unsigned i = 0, e = Regs.size(); i != e; ++i) { + SubRegMap &SRM = inferSubRegIndices(Regs[i].TheDef, AllSRM); + if (SRM.empty()) + continue; + OS << " case " << getQualifiedName(Regs[i].TheDef) << ":\n"; OS << " switch (Index) {\n"; OS << " default: return 0;\n"; - for (unsigned i = 0, e = I->second.size(); i != e; ++i) - OS << " case " - << getQualifiedName((I->second)[i].first) << ": return " - << getQualifiedName((I->second)[i].second) << ";\n"; + for (SubRegMap::const_iterator ii = SRM.begin(), ie = SRM.end(); ii != ie; + ++ii) + OS << " case " << getQualifiedName(ii->first) + << ": return " << getQualifiedName(ii->second) << ";\n"; OS << " };\n" << " break;\n"; } OS << " };\n"; OS << " return 0;\n"; OS << "}\n\n"; - OS << "unsigned " << ClassName + OS << "unsigned " << ClassName << "::getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const {\n" << " switch (RegNo) {\n" << " default:\n return 0;\n"; - for (std::map > >::iterator - I = SubRegVectors.begin(), E = SubRegVectors.end(); I != E; ++I) { - OS << " case " << getQualifiedName(I->first) << ":\n"; - for (unsigned i = 0, e = I->second.size(); i != e; ++i) - OS << " if (SubRegNo == " - << getQualifiedName((I->second)[i].second) - << ") return " - << getQualifiedName((I->second)[i].first) << ";\n"; + for (unsigned i = 0, e = Regs.size(); i != e; ++i) { + SubRegMap &SRM = AllSRM[Regs[i].TheDef]; + if (SRM.empty()) + continue; + OS << " case " << getQualifiedName(Regs[i].TheDef) << ":\n"; + for (SubRegMap::const_iterator ii = SRM.begin(), ie = SRM.end(); ii != ie; + ++ii) + OS << " if (SubRegNo == " << getQualifiedName(ii->second) + << ") return " << getQualifiedName(ii->first) << ";\n"; OS << " return 0;\n"; } OS << " };\n"; From dpatel at apple.com Wed May 26 12:29:32 2010 From: dpatel at apple.com (Devang Patel) Date: Wed, 26 May 2010 17:29:32 -0000 Subject: [llvm-commits] [llvm] r104705 - /llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Message-ID: <20100526172932.DF07D312800A@llvm.org> Author: dpatel Date: Wed May 26 12:29:32 2010 New Revision: 104705 URL: http://llvm.org/viewvc/llvm-project?rev=104705&view=rev Log: Do not construct location list backword! Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=104705&r1=104704&r2=104705&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Wed May 26 12:29:32 2010 @@ -2215,22 +2215,26 @@ RegVar->setDotDebugLocOffset(DotDebugLocEntries.size()); if (DotDebugLocEntries.empty()) DotDebugLocEntries.push_back(DotDebugLocEntry()); - const MachineInstr *Current = MultipleValues.back(); - MultipleValues.pop_back(); - while (!MultipleValues.empty()) { - const MachineInstr *Next = MultipleValues.back(); - MultipleValues.pop_back(); - DbgValueStartMap[Next] = RegVar; + const MachineInstr *Begin = NULL; + const MachineInstr *End = NULL; + for (SmallVector::iterator + MVI = MultipleValues.begin(), MVE = MultipleValues.end(); MVI != MVE; ++MVI) { + if (!Begin) { + Begin = *MVI; + continue; + } + End = *MVI; + DbgValueStartMap[End] = RegVar; MachineLocation MLoc; - MLoc.set(Current->getOperand(0).getReg(), 0); - const MCSymbol *FLabel = getLabelBeforeInsn(Next); - const MCSymbol *SLabel = getLabelBeforeInsn(Current); + MLoc.set(Begin->getOperand(0).getReg(), 0); + const MCSymbol *FLabel = getLabelBeforeInsn(Begin); + const MCSymbol *SLabel = getLabelBeforeInsn(End); DotDebugLocEntries.push_back(DotDebugLocEntry(FLabel, SLabel, MLoc)); - Current = Next; - if (MultipleValues.empty()) { - // If Next is the last instruction then its value is valid + Begin = End; + if (MVI + 1 == MVE) { + // If End is the last instruction then its value is valid // until the end of the funtion. - MLoc.set(Next->getOperand(0).getReg(), 0); + MLoc.set(End->getOperand(0).getReg(), 0); DotDebugLocEntries. push_back(DotDebugLocEntry(SLabel, FunctionEndSym, MLoc)); } From dpatel at apple.com Wed May 26 12:42:50 2010 From: dpatel at apple.com (Devang Patel) Date: Wed, 26 May 2010 17:42:50 -0000 Subject: [llvm-commits] [llvm] r104706 - in /llvm/trunk/lib/CodeGen/AsmPrinter: DwarfDebug.cpp DwarfDebug.h Message-ID: <20100526174250.95674312800A@llvm.org> Author: dpatel Date: Wed May 26 12:42:50 2010 New Revision: 104706 URL: http://llvm.org/viewvc/llvm-project?rev=104706&view=rev Log: Remove dead code. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=104706&r1=104705&r2=104706&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Wed May 26 12:42:50 2010 @@ -2198,10 +2198,8 @@ Processed.insert(DV); DbgVariable *RegVar = new DbgVariable(DV); Scope->addVariable(RegVar); - if (DV.getTag() != dwarf::DW_TAG_arg_variable) { - DbgValueStartMap[MInsn] = RegVar; + if (DV.getTag() != dwarf::DW_TAG_arg_variable) DbgVariableLabelsMap[RegVar] = getLabelBeforeInsn(MInsn); - } if (DbgVariable *AbsVar = findAbstractVariable(DV, MInsn->getDebugLoc())) { DbgVariableToDbgInstMap[AbsVar] = MInsn; VarToAbstractVarMap[RegVar] = AbsVar; @@ -2224,7 +2222,6 @@ continue; } End = *MVI; - DbgValueStartMap[End] = RegVar; MachineLocation MLoc; MLoc.set(Begin->getOperand(0).getReg(), 0); const MCSymbol *FLabel = getLabelBeforeInsn(Begin); @@ -2683,7 +2680,6 @@ DeleteContainerSeconds(DbgScopeMap); InsnsBeginScopeSet.clear(); InsnsEndScopeSet.clear(); - DbgValueStartMap.clear(); ConcreteScopes.clear(); DeleteContainerSeconds(AbstractScopes); AbstractScopesList.clear(); Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=104706&r1=104705&r2=104706&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Wed May 26 12:42:50 2010 @@ -164,12 +164,6 @@ /// DbgScopes in AbstractScopes. DenseMap AbstractVariables; - /// DbgValueStartMap - Tracks starting scope of variable DIEs. - /// If the scope of an object begins sometime after the low pc value for the - /// scope most closely enclosing the object, the object entry may have a - /// DW_AT_start_scope attribute. - DenseMap DbgValueStartMap; - /// DbgVariableToFrameIndexMap - Tracks frame index used to find /// variable's value. DenseMap DbgVariableToFrameIndexMap; From anton at korobeynikov.info Wed May 26 12:45:02 2010 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Wed, 26 May 2010 21:45:02 +0400 Subject: [llvm-commits] [llvm] r104704 - in /llvm/trunk: include/llvm/Target/Target.td lib/Target/ARM/ARMRegisterInfo.td lib/Target/Blackfin/BlackfinRegisterInfo.td lib/Target/MBlaze/MBlazeRegisterInfo.td lib/Target/MSP430/MSP430RegisterInfo.td lib/Target Message-ID: Hello, Jakob > CompositeIndices may be specified for the weirder cases such as the XMM sub_sd > index that returns the same register, and ARM NEON Q registers where both D > subregs have ssub_0 and ssub_1 sub-subregs. Strictly speaking, this is not true. It's not possible to access S subregs in NEON mode (thus D subregs of Q registers do not have any subregs). VFP-addressable D registers should have S subregs though, but there are no Q superregisters for such D registers. -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University From daniel at zuster.org Wed May 26 12:45:29 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 26 May 2010 17:45:29 -0000 Subject: [llvm-commits] [llvm] r104707 - in /llvm/trunk: include/llvm/Target/TargetAsmBackend.h lib/MC/MCAssembler.cpp lib/MC/MCMachOStreamer.cpp lib/Target/X86/X86AsmBackend.cpp Message-ID: <20100526174529.7007A312800A@llvm.org> Author: ddunbar Date: Wed May 26 12:45:29 2010 New Revision: 104707 URL: http://llvm.org/viewvc/llvm-project?rev=104707&view=rev Log: MC: Simplify MayNeedRelaxation to not provide the fixups, so we can query it before encoding. Modified: llvm/trunk/include/llvm/Target/TargetAsmBackend.h llvm/trunk/lib/MC/MCAssembler.cpp llvm/trunk/lib/MC/MCMachOStreamer.cpp llvm/trunk/lib/Target/X86/X86AsmBackend.cpp Modified: llvm/trunk/include/llvm/Target/TargetAsmBackend.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetAsmBackend.h?rev=104707&r1=104706&r2=104707&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetAsmBackend.h (original) +++ llvm/trunk/include/llvm/Target/TargetAsmBackend.h Wed May 26 12:45:29 2010 @@ -112,10 +112,7 @@ /// relaxation. /// /// \arg Inst - The instruction to test. - /// \arg Fixups - The actual fixups this instruction encoded to, for potential - /// use by the target backend. - virtual bool MayNeedRelaxation(const MCInst &Inst, - const SmallVectorImpl &Fixups) const = 0; + virtual bool MayNeedRelaxation(const MCInst &Inst) const = 0; /// RelaxInstruction - Relax the instruction in the given fragment to the next /// wider instruction. Modified: llvm/trunk/lib/MC/MCAssembler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=104707&r1=104706&r2=104707&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCAssembler.cpp (original) +++ llvm/trunk/lib/MC/MCAssembler.cpp Wed May 26 12:45:29 2010 @@ -787,7 +787,7 @@ // If this inst doesn't ever need relaxation, ignore it. This occurs when we // are intentionally pushing out inst fragments, or because we relaxed a // previous instruction to one that doesn't need relaxation. - if (!getBackend().MayNeedRelaxation(IF->getInst(), IF->getFixups())) + if (!getBackend().MayNeedRelaxation(IF->getInst())) return false; for (MCInstFragment::const_fixup_iterator it = IF->fixup_begin(), Modified: llvm/trunk/lib/MC/MCMachOStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCMachOStreamer.cpp?rev=104707&r1=104706&r2=104707&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCMachOStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCMachOStreamer.cpp Wed May 26 12:45:29 2010 @@ -452,7 +452,7 @@ // total knowledge about undefined symbols at that point). Even now, though, // we can do a decent job, especially on Darwin where scattering means that we // are going to often know that we can never fully resolve a fixup. - if (Assembler.getBackend().MayNeedRelaxation(Inst, AsmFixups)) { + if (Assembler.getBackend().MayNeedRelaxation(Inst)) { MCInstFragment *IF = new MCInstFragment(Inst, CurSectionData); IF->setAtom(CurrentAtomMap.lookup(CurSectionData)); Modified: llvm/trunk/lib/Target/X86/X86AsmBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86AsmBackend.cpp?rev=104707&r1=104706&r2=104707&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86AsmBackend.cpp (original) +++ llvm/trunk/lib/Target/X86/X86AsmBackend.cpp Wed May 26 12:45:29 2010 @@ -54,8 +54,7 @@ DF.getContents()[Fixup.getOffset() + i] = uint8_t(Value >> (i * 8)); } - bool MayNeedRelaxation(const MCInst &Inst, - const SmallVectorImpl &Fixups) const; + bool MayNeedRelaxation(const MCInst &Inst) const; void RelaxInstruction(const MCInstFragment *IF, MCInst &Res) const; @@ -88,31 +87,16 @@ } } -bool X86AsmBackend::MayNeedRelaxation(const MCInst &Inst, - const SmallVectorImpl &Fixups) const { - for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { - const MCFixup &F = Fixups[i]; - - // We don't support relaxing anything else currently. Make sure we error out - // if we see a non-constant 1 or 2 byte fixup. - // - // FIXME: We should need to check this here, this is better checked in the - // object writer which should be verifying that any final relocations match - // the expected fixup. However, that code is more complicated and hasn't - // been written yet. See the FIXMEs in MachObjectWriter.cpp. - if ((F.getKind() == FK_Data_1 || F.getKind() == FK_Data_2) && - !isa(F.getValue())) - report_fatal_error("unexpected small fixup with a non-constant operand!"); - - // Check for a 1byte pcrel fixup, and enforce that we would know how to - // relax this instruction. - if (unsigned(F.getKind()) == X86::reloc_pcrel_1byte) { - assert(getRelaxedOpcode(Inst.getOpcode()) != Inst.getOpcode()); - return true; - } - } - - return false; +bool X86AsmBackend::MayNeedRelaxation(const MCInst &Inst) const { + // Check if this instruction is ever relaxable. + if (getRelaxedOpcode(Inst.getOpcode()) == Inst.getOpcode()) + return false; + + // If so, just assume it can be relaxed. Once we support relaxing more complex + // instructions we should check that the instruction actually has symbolic + // operands before doing this, but we need to be careful about things like + // PCrel. + return true; } // FIXME: Can tblgen help at all here to verify there aren't other instructions From daniel at zuster.org Wed May 26 12:50:16 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 26 May 2010 17:50:16 -0000 Subject: [llvm-commits] [llvm] r104709 - /llvm/trunk/lib/MC/MCMachOStreamer.cpp Message-ID: <20100526175017.0A4F7312800A@llvm.org> Author: ddunbar Date: Wed May 26 12:50:16 2010 New Revision: 104709 URL: http://llvm.org/viewvc/llvm-project?rev=104709&view=rev Log: MC: Eliminate an unnecessary copy. Modified: llvm/trunk/lib/MC/MCMachOStreamer.cpp Modified: llvm/trunk/lib/MC/MCMachOStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCMachOStreamer.cpp?rev=104709&r1=104708&r2=104709&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCMachOStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCMachOStreamer.cpp Wed May 26 12:50:16 2010 @@ -434,11 +434,6 @@ Assembler.getEmitter().EncodeInstruction(Inst, VecOS, Fixups); VecOS.flush(); - // FIXME: Eliminate this copy. - SmallVector AsmFixups; - for (unsigned i = 0, e = Fixups.size(); i != e; ++i) - AsmFixups.push_back(Fixups[i]); - // See if we might need to relax this instruction, if so it needs its own // fragment. // @@ -461,16 +456,16 @@ // FIXME: Revisit this design decision when relaxation is done, we may be // able to get away with not storing any extra data in the MCInst. IF->getCode() = Code; - IF->getFixups() = AsmFixups; + IF->getFixups() = Fixups; return; } // Add the fixups and data. MCDataFragment *DF = getOrCreateDataFragment(); - for (unsigned i = 0, e = AsmFixups.size(); i != e; ++i) { - AsmFixups[i].setOffset(AsmFixups[i].getOffset() + DF->getContents().size()); - DF->addFixup(AsmFixups[i]); + for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { + Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size()); + DF->addFixup(Fixups[i]); } DF->getContents().append(Code.begin(), Code.end()); } From stoklund at 2pi.dk Wed May 26 12:56:03 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 26 May 2010 10:56:03 -0700 Subject: [llvm-commits] [llvm] r104704 - in /llvm/trunk: include/llvm/Target/Target.td lib/Target/ARM/ARMRegisterInfo.td lib/Target/Blackfin/BlackfinRegisterInfo.td lib/Target/MBlaze/MBlazeRegisterInfo.td lib/Target/MSP430/MSP430RegisterInfo.td lib/Target In-Reply-To: References: Message-ID: <5602E18C-2FC2-4D0C-8879-73B78FA7844A@2pi.dk> On May 26, 2010, at 10:45 AM, Anton Korobeynikov wrote: > Hello, Jakob > >> CompositeIndices may be specified for the weirder cases such as the XMM sub_sd >> index that returns the same register, and ARM NEON Q registers where both D >> subregs have ssub_0 and ssub_1 sub-subregs. > Strictly speaking, this is not true. It's not possible to access S > subregs in NEON mode (thus D subregs of Q registers do not have any > subregs). > VFP-addressable D registers should have S subregs though, but there > are no Q superregisters for such D registers. OK, thanks. I didn't mean to change the subregister structure of NEON/VFP registers. I hope, I didn't. The CompositeIndices is still neccessary to disambiguate in the QQQQ -> QQ -> Q -> D tree. Is it wrong that we have ssub_0 to ssub_3? It sounds like ssub_2 and ssub_3 are not legal? From dalej at apple.com Wed May 26 12:55:45 2010 From: dalej at apple.com (Dale Johannesen) Date: Wed, 26 May 2010 17:55:45 -0000 Subject: [llvm-commits] [llvm] r104710 - /llvm/trunk/test/CodeGen/X86/2010-05-26-FP_TO_INT-crash.ll Message-ID: <20100526175545.C6835312800A@llvm.org> Author: johannes Date: Wed May 26 12:55:45 2010 New Revision: 104710 URL: http://llvm.org/viewvc/llvm-project?rev=104710&view=rev Log: Testcase for 104624/104619/PR7191/8023512. Reduced from one provided by Duncan Sands, thanks! Added: llvm/trunk/test/CodeGen/X86/2010-05-26-FP_TO_INT-crash.ll Added: llvm/trunk/test/CodeGen/X86/2010-05-26-FP_TO_INT-crash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2010-05-26-FP_TO_INT-crash.ll?rev=104710&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2010-05-26-FP_TO_INT-crash.ll (added) +++ llvm/trunk/test/CodeGen/X86/2010-05-26-FP_TO_INT-crash.ll Wed May 26 12:55:45 2010 @@ -0,0 +1,16 @@ +; RUN: llc -O0 -mcpu=i386 -mattr=-sse,-mmx < %s +; ModuleID = '' +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32" +target triple = "i386-pc-linux-gnu" + +module asm "\09.ident\09\22GCC: (GNU) 4.5.1 20100510 (prerelease) LLVM: 104604:104605\22" + +define i32 @f2(double %x) nounwind { +entry: + %0 = load double* undef, align 64 ; [#uses=1] + %1 = fptoui double %0 to i16 ; [#uses=1] + %2 = zext i16 %1 to i32 ; [#uses=1] + %3 = add nsw i32 0, %2 ; [#uses=1] + store i32 %3, i32* undef, align 1 + ret i32 0 +} From anton at korobeynikov.info Wed May 26 13:05:26 2010 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Wed, 26 May 2010 22:05:26 +0400 Subject: [llvm-commits] [llvm] r104704 - in /llvm/trunk: include/llvm/Target/Target.td lib/Target/ARM/ARMRegisterInfo.td lib/Target/Blackfin/BlackfinRegisterInfo.td lib/Target/MBlaze/MBlazeRegisterInfo.td lib/Target/MSP430/MSP430RegisterInfo.td lib/Target In-Reply-To: <5602E18C-2FC2-4D0C-8879-73B78FA7844A@2pi.dk> References: <5602E18C-2FC2-4D0C-8879-73B78FA7844A@2pi.dk> Message-ID: > Is it wrong that we have ssub_0 to ssub_3? It sounds like ssub_2 and ssub_3 are not legal? Well, this is pretty good question :) For some operations we need to restrict to some part of register file (all that _VFP2 / _8 regclasses). And thus we have to model the whole hierarchy of subregs. -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University From gohman at apple.com Wed May 26 13:03:53 2010 From: gohman at apple.com (Dan Gohman) Date: Wed, 26 May 2010 18:03:53 -0000 Subject: [llvm-commits] [llvm] r104711 - /llvm/trunk/lib/Target/X86/X86InstrSSE.td Message-ID: <20100526180353.E3F3B312800A@llvm.org> Author: djg Date: Wed May 26 13:03:53 2010 New Revision: 104711 URL: http://llvm.org/viewvc/llvm-project?rev=104711&view=rev Log: Fix a typo in a comment that Gabor noticed. Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=104711&r1=104710&r2=104711&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Wed May 26 13:03:53 2010 @@ -449,7 +449,7 @@ [(set GR32:$dst, (int_x86_sse_cvtss2si (load addr:$src)))]>; -// Match intrinisics which expect MM and XMM operand(s). +// Match intrinsics which expect MM and XMM operand(s). def Int_CVTPS2PIrr : PSI<0x2D, MRMSrcReg, (outs VR64:$dst), (ins VR128:$src), "cvtps2pi\t{$src, $dst|$dst, $src}", [(set VR64:$dst, (int_x86_sse_cvtps2pi VR128:$src))]>; @@ -1277,7 +1277,7 @@ [(set GR32:$dst, (int_x86_sse2_cvtsd2si (load addr:$src)))]>; -// Match intrinisics which expect MM and XMM operand(s). +// Match intrinsics which expect MM and XMM operand(s). def Int_CVTPD2PIrr : PDI<0x2D, MRMSrcReg, (outs VR64:$dst), (ins VR128:$src), "cvtpd2pi\t{$src, $dst|$dst, $src}", [(set VR64:$dst, (int_x86_sse_cvtpd2pi VR128:$src))]>; @@ -2460,7 +2460,7 @@ "mfence", [(int_x86_sse2_mfence)]>, TB, Requires<[HasSSE2]>; // Pause. This "instruction" is encoded as "rep; nop", so even though it -// was introduced with SSE2, it's backward compabitle. +// was introduced with SSE2, it's backward compatible. def PAUSE : I<0x90, RawFrm, (outs), (ins), "pause", []>, REP; //TODO: custom lower this so as to never even generate the noop From daniel at zuster.org Wed May 26 13:15:06 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 26 May 2010 18:15:06 -0000 Subject: [llvm-commits] [llvm] r104713 - in /llvm/trunk: include/llvm/Target/TargetAsmBackend.h lib/MC/MCAssembler.cpp lib/Target/X86/X86AsmBackend.cpp Message-ID: <20100526181506.74974312800A@llvm.org> Author: ddunbar Date: Wed May 26 13:15:06 2010 New Revision: 104713 URL: http://llvm.org/viewvc/llvm-project?rev=104713&view=rev Log: MC: Change RelaxInstruction to only take the input and output instructions. Modified: llvm/trunk/include/llvm/Target/TargetAsmBackend.h llvm/trunk/lib/MC/MCAssembler.cpp llvm/trunk/lib/Target/X86/X86AsmBackend.cpp Modified: llvm/trunk/include/llvm/Target/TargetAsmBackend.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetAsmBackend.h?rev=104713&r1=104712&r2=104713&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetAsmBackend.h (original) +++ llvm/trunk/include/llvm/Target/TargetAsmBackend.h Wed May 26 13:15:06 2010 @@ -16,7 +16,6 @@ class MCDataFragment; class MCFixup; class MCInst; -class MCInstFragment; class MCObjectWriter; class MCSection; template @@ -111,13 +110,16 @@ /// MayNeedRelaxation - Check whether the given instruction may need /// relaxation. /// - /// \arg Inst - The instruction to test. + /// \param Inst - The instruction to test. virtual bool MayNeedRelaxation(const MCInst &Inst) const = 0; /// RelaxInstruction - Relax the instruction in the given fragment to the next /// wider instruction. - virtual void RelaxInstruction(const MCInstFragment *IF, - MCInst &Res) const = 0; + /// + /// \param Inst - The instruction to relax, which may be the same as the + /// output. + /// \parm Res [output] - On return, the relaxed instruction. + virtual void RelaxInstruction(const MCInst &Inst, MCInst &Res) const = 0; /// WriteNopData - Write an (optimal) nop sequence of Count bytes to the given /// output. If the target cannot generate such a sequence, it should return an Modified: llvm/trunk/lib/MC/MCAssembler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=104713&r1=104712&r2=104713&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCAssembler.cpp (original) +++ llvm/trunk/lib/MC/MCAssembler.cpp Wed May 26 13:15:06 2010 @@ -824,7 +824,7 @@ // Relax the fragment. MCInst Relaxed; - getBackend().RelaxInstruction(IF, Relaxed); + getBackend().RelaxInstruction(IF->getInst(), Relaxed); // Encode the new instruction. // Modified: llvm/trunk/lib/Target/X86/X86AsmBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86AsmBackend.cpp?rev=104713&r1=104712&r2=104713&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86AsmBackend.cpp (original) +++ llvm/trunk/lib/Target/X86/X86AsmBackend.cpp Wed May 26 13:15:06 2010 @@ -56,7 +56,7 @@ bool MayNeedRelaxation(const MCInst &Inst) const; - void RelaxInstruction(const MCInstFragment *IF, MCInst &Res) const; + void RelaxInstruction(const MCInst &Inst, MCInst &Res) const; bool WriteNopData(uint64_t Count, MCObjectWriter *OW) const; }; @@ -101,20 +101,19 @@ // FIXME: Can tblgen help at all here to verify there aren't other instructions // we can relax? -void X86AsmBackend::RelaxInstruction(const MCInstFragment *IF, - MCInst &Res) const { +void X86AsmBackend::RelaxInstruction(const MCInst &Inst, MCInst &Res) const { // The only relaxations X86 does is from a 1byte pcrel to a 4byte pcrel. - unsigned RelaxedOp = getRelaxedOpcode(IF->getInst().getOpcode()); + unsigned RelaxedOp = getRelaxedOpcode(Inst.getOpcode()); - if (RelaxedOp == IF->getInst().getOpcode()) { + if (RelaxedOp == Inst.getOpcode()) { SmallString<256> Tmp; raw_svector_ostream OS(Tmp); - IF->getInst().dump_pretty(OS); + Inst.dump_pretty(OS); OS << "\n"; report_fatal_error("unexpected instruction to relax: " + OS.str()); } - Res = IF->getInst(); + Res = Inst; Res.setOpcode(RelaxedOp); } From stoklund at 2pi.dk Wed May 26 13:27:42 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 26 May 2010 11:27:42 -0700 Subject: [llvm-commits] [llvm] r104704 - in /llvm/trunk: include/llvm/Target/Target.td lib/Target/ARM/ARMRegisterInfo.td lib/Target/Blackfin/BlackfinRegisterInfo.td lib/Target/MBlaze/MBlazeRegisterInfo.td lib/Target/MSP430/MSP430RegisterInfo.td lib/Target In-Reply-To: References: <5602E18C-2FC2-4D0C-8879-73B78FA7844A@2pi.dk> Message-ID: On May 26, 2010, at 11:05 AM, Anton Korobeynikov wrote: >> Is it wrong that we have ssub_0 to ssub_3? It sounds like ssub_2 and ssub_3 are not legal? > Well, this is pretty good question :) For some operations we need to > restrict to some part of register file (all that _VFP2 / _8 > regclasses). And thus we have to model the whole hierarchy of subregs. At least, it is a lot easier now :-) The coalescer needs to be able to compose subreg indices. Suppose an instruction uses parts of a DPR_VFP2 register: FOO %reg1100:ssub_1 And now %reg1100 is coalesced with the second part of a Q register: %reg1100 = COPY %reg1200:dsub_1 The FOO instruction must be updated to: FOO %reg1200:dsub_1:ssub_1 Which is really: FOO %reg1200:ssub_3 We need a target hook to compose ssub_3 = dsub_1 + ssub_1, and I need to require names for all inherited subregisters to implement that. Right now, the ARM register bank is not fully named: Warning: Register QQ0 inherited subregisters without an index: S4 = qsub_1, ssub_0 S5 = qsub_1, ssub_1 S6 = qsub_1, ssub_2 S7 = qsub_1, ssub_3 Warning: Register QQQQ0 inherited subregisters without an index: S10 = qqsub_1, ssub_2 S11 = qqsub_1, ssub_3 S8 = qqsub_1, ssub_0 S9 = qqsub_1, ssub_1 So I am probably going to add ssub_4 through ssub_15. From gohman at apple.com Wed May 26 13:34:12 2010 From: gohman at apple.com (Dan Gohman) Date: Wed, 26 May 2010 18:34:12 -0000 Subject: [llvm-commits] [llvm] r104716 - /llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Message-ID: <20100526183412.4817B312800A@llvm.org> Author: djg Date: Wed May 26 13:34:12 2010 New Revision: 104716 URL: http://llvm.org/viewvc/llvm-project?rev=104716&view=rev Log: Delete an unused function. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=104716&r1=104715&r2=104716&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Wed May 26 13:34:12 2010 @@ -1105,8 +1105,6 @@ return scheduleDAG->DAG->GetOrdering(SU->getNode()); } - unsigned size() const { return Queue.size(); } - bool empty() const { return Queue.empty(); } void push(SUnit *U) { From gohman at apple.com Wed May 26 13:37:48 2010 From: gohman at apple.com (Dan Gohman) Date: Wed, 26 May 2010 18:37:48 -0000 Subject: [llvm-commits] [llvm] r104717 - /llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h Message-ID: <20100526183748.BC923312800A@llvm.org> Author: djg Date: Wed May 26 13:37:48 2010 New Revision: 104717 URL: http://llvm.org/viewvc/llvm-project?rev=104717&view=rev Log: Fix indentation. Modified: llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h Modified: llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h?rev=104717&r1=104716&r2=104717&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h (original) +++ llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h Wed May 26 13:37:48 2010 @@ -43,8 +43,8 @@ /// Queue - The queue. PriorityQueue, latency_sort> Queue; -public: - LatencyPriorityQueue() : Queue(latency_sort(this)) { + public: + LatencyPriorityQueue() : Queue(latency_sort(this)) { } void initNodes(std::vector &sunits) { From gohman at apple.com Wed May 26 13:52:00 2010 From: gohman at apple.com (Dan Gohman) Date: Wed, 26 May 2010 18:52:00 -0000 Subject: [llvm-commits] [llvm] r104718 - in /llvm/trunk: include/llvm/CodeGen/LatencyPriorityQueue.h lib/CodeGen/LatencyPriorityQueue.cpp lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Message-ID: <20100526185200.5DC82312800A@llvm.org> Author: djg Date: Wed May 26 13:52:00 2010 New Revision: 104718 URL: http://llvm.org/viewvc/llvm-project?rev=104718&view=rev Log: Eliminate the use of PriorityQueue and just use a std::vector, implementing pop with a linear search for a "best" element. The priority queue was a neat idea, but in practice the comparison functions depend on dynamic information. Modified: llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h?rev=104718&r1=104717&r2=104718&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h (original) +++ llvm/trunk/include/llvm/CodeGen/LatencyPriorityQueue.h Wed May 26 13:52:00 2010 @@ -17,7 +17,6 @@ #define LATENCY_PRIORITY_QUEUE_H #include "llvm/CodeGen/ScheduleDAG.h" -#include "llvm/ADT/PriorityQueue.h" namespace llvm { class LatencyPriorityQueue; @@ -41,10 +40,11 @@ std::vector NumNodesSolelyBlocking; /// Queue - The queue. - PriorityQueue, latency_sort> Queue; + std::vector Queue; + latency_sort Picker; public: - LatencyPriorityQueue() : Queue(latency_sort(this)) { + LatencyPriorityQueue() : Picker(this) { } void initNodes(std::vector &sunits) { @@ -77,17 +77,9 @@ virtual void push(SUnit *U); - SUnit *pop() { - if (empty()) return NULL; - SUnit *V = Queue.top(); - Queue.pop(); - return V; - } + virtual SUnit *pop(); - void remove(SUnit *SU) { - assert(!Queue.empty() && "Not in queue!"); - Queue.erase_one(SU); - } + virtual void remove(SUnit *SU); // ScheduledNode - As nodes are scheduled, we look to see if there are any // successor nodes that have a single unscheduled predecessor. If so, that Modified: llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp?rev=104718&r1=104717&r2=104718&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp (original) +++ llvm/trunk/lib/CodeGen/LatencyPriorityQueue.cpp Wed May 26 13:52:00 2010 @@ -79,7 +79,7 @@ } NumNodesSolelyBlocking[SU->NodeNum] = NumNodesBlocking; - Queue.push(SU); + Queue.push_back(SU); } @@ -114,3 +114,25 @@ // NumNodesSolelyBlocking value. push(OnlyAvailablePred); } + +SUnit *LatencyPriorityQueue::pop() { + if (empty()) return NULL; + std::vector::iterator Best = Queue.begin(); + for (std::vector::iterator I = next(Queue.begin()), + E = Queue.end(); I != E; ++I) + if (Picker(*Best, *I)) + Best = I; + SUnit *V = *Best; + if (Best != prior(Queue.end())) + std::swap(*Best, Queue.back()); + Queue.pop_back(); + return V; +} + +void LatencyPriorityQueue::remove(SUnit *SU) { + assert(!Queue.empty() && "Queue is empty!"); + std::vector::iterator I = std::find(Queue.begin(), Queue.end(), SU); + if (I != prior(Queue.end())) + std::swap(*I, Queue.back()); + Queue.pop_back(); +} Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=104718&r1=104717&r2=104718&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Wed May 26 13:52:00 2010 @@ -24,7 +24,6 @@ #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" -#include "llvm/ADT/PriorityQueue.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/STLExtras.h" @@ -1027,7 +1026,8 @@ namespace { template class RegReductionPriorityQueue : public SchedulingPriorityQueue { - PriorityQueue, SF> Queue; + std::vector Queue; + SF Picker; unsigned CurQueueId; protected: @@ -1044,7 +1044,7 @@ public: RegReductionPriorityQueue(const TargetInstrInfo *tii, const TargetRegisterInfo *tri) - : Queue(SF(this)), CurQueueId(0), + : Picker(this), CurQueueId(0), TII(tii), TRI(tri), scheduleDAG(NULL) {} void initNodes(std::vector &sunits) { @@ -1110,13 +1110,20 @@ void push(SUnit *U) { assert(!U->NodeQueueId && "Node in the queue already"); U->NodeQueueId = ++CurQueueId; - Queue.push(U); + Queue.push_back(U); } SUnit *pop() { if (empty()) return NULL; - SUnit *V = Queue.top(); - Queue.pop(); + std::vector::iterator Best = Queue.begin(); + for (std::vector::iterator I = next(Queue.begin()), + E = Queue.end(); I != E; ++I) + if (Picker(*Best, *I)) + Best = I; + SUnit *V = *Best; + if (Best != prior(Queue.end())) + std::swap(*Best, Queue.back()); + Queue.pop_back(); V->NodeQueueId = 0; return V; } @@ -1124,7 +1131,11 @@ void remove(SUnit *SU) { assert(!Queue.empty() && "Queue is empty!"); assert(SU->NodeQueueId != 0 && "Not in queue!"); - Queue.erase_one(SU); + std::vector::iterator I = std::find(Queue.begin(), Queue.end(), + SU); + if (I != prior(Queue.end())) + std::swap(*I, Queue.back()); + Queue.pop_back(); SU->NodeQueueId = 0; } From dpatel at apple.com Wed May 26 14:37:24 2010 From: dpatel at apple.com (Devang Patel) Date: Wed, 26 May 2010 19:37:24 -0000 Subject: [llvm-commits] [llvm] r104720 - in /llvm/trunk/lib/CodeGen/AsmPrinter: DwarfDebug.cpp DwarfDebug.h Message-ID: <20100526193724.ED1D2312800A@llvm.org> Author: dpatel Date: Wed May 26 14:37:24 2010 New Revision: 104720 URL: http://llvm.org/viewvc/llvm-project?rev=104720&view=rev Log: Identify instructions, that needs a label to mark debug info entity, in advance. This simplifies beginScope(). Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=104720&r1=104719&r2=104720&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Wed May 26 14:37:24 2010 @@ -2274,50 +2274,38 @@ /// beginScope - Process beginning of a scope. void DwarfDebug::beginScope(const MachineInstr *MI) { + if (InsnNeedsLabel.count(MI) == 0) { + LabelsBeforeInsn[MI] = PrevLabel; + return; + } + // Check location. DebugLoc DL = MI->getDebugLoc(); - if (DL.isUnknown() && !UnknownLocations) { - if (MI->isDebugValue() && PrevLabel) - LabelsBeforeInsn[MI] = PrevLabel; + if (!DL.isUnknown()) { + const MDNode *Scope = DL.getScope(Asm->MF->getFunction()->getContext()); + PrevLabel = recordSourceLine(DL.getLine(), DL.getCol(), Scope); + PrevInstLoc = DL; + LabelsBeforeInsn[MI] = PrevLabel; return; } - - bool LocalVar = false; + + // If location is unknown then Use last known location for this DBG_VALUE + // instruction. if (MI->isDebugValue()) { - assert (MI->getNumOperands() > 1 && "Invalid machine instruction!"); - DIVariable DV(MI->getOperand(MI->getNumOperands() - 1).getMetadata()); - if (!DV.Verify()) return; - if (DV.getTag() != dwarf::DW_TAG_arg_variable - && !isDbgValueInUndefinedReg(MI)) - LocalVar = true; - } - - MCSymbol *Label = NULL; - if (DL == PrevInstLoc) - Label = PrevLabel; - // Do not emit line number entry for arguments. - else if (!MI->isDebugValue() || LocalVar) { - const MDNode *Scope = 0; - if (DL.isUnknown() == false) { - Scope = DL.getScope(Asm->MF->getFunction()->getContext()); - // FIXME: Should only verify each scope once! - if (!DIScope(Scope).Verify()) - return; - } - // else ... - // This instruction has no debug location. If the preceding instruction - // did, emit debug location information to indicate that the debug - // location is now unknown. - - Label = recordSourceLine(DL.getLine(), DL.getCol(), Scope); - PrevInstLoc = DL; - PrevLabel = Label; + const MDNode *Scope = + PrevInstLoc.getScope(Asm->MF->getFunction()->getContext()); + PrevLabel = recordSourceLine(PrevInstLoc.getLine(), PrevInstLoc.getCol(), Scope); + LabelsBeforeInsn[MI] = PrevLabel; + return; + } + + if (UnknownLocations) { + PrevLabel = recordSourceLine(0, 0, 0); + LabelsBeforeInsn[MI] = PrevLabel; + return; } - // If this instruction begins a scope then note down corresponding label - // even if previous label is reused. - if (Label && (InsnsBeginScopeSet.count(MI) != 0 || MI->isDebugValue())) - LabelsBeforeInsn[MI] = Label; + assert (0 && "Instruction is not processed!"); } /// endScope - Process end of a scope. @@ -2627,6 +2615,40 @@ } recordSourceLine(Line, Col, Scope); + + DebugLoc PrevLoc; + for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); + I != E; ++I) + for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end(); + II != IE; ++II) { + const MachineInstr *MI = II; + DebugLoc DL = MI->getDebugLoc(); + if (MI->isDebugValue()) { + // DBG_VALUE needs a label if the variable is local variable or + // an argument whose location is changing. + assert (MI->getNumOperands() > 1 && "Invalid machine instruction!"); + DIVariable DV(MI->getOperand(MI->getNumOperands() - 1).getMetadata()); + if (!DV.Verify()) continue; + if (DV.getTag() != dwarf::DW_TAG_arg_variable) + InsnNeedsLabel.insert(MI); + else if (!ProcessedArgs.insert(DV)) + InsnNeedsLabel.insert(MI); + } else { + // If location is unknown then instruction needs a location only if + // UnknownLocations flag is set. + if (DL.isUnknown()) { + if (UnknownLocations && !PrevLoc.isUnknown()) + InsnNeedsLabel.insert(MI); + } else if (DL != PrevLoc) + // Otherwise, instruction needs a location only if it is new location. + InsnNeedsLabel.insert(MI); + } + + if (!DL.isUnknown() || UnknownLocations) + PrevLoc = DL; + } + + PrevLabel = FunctionBeginSym; } /// endFunction - Gather and emit post-function debug information. @@ -2673,6 +2695,8 @@ // Clear debug info CurrentFnDbgScope = NULL; + InsnNeedsLabel.clear(); + ProcessedArgs.clear(); DbgVariableToFrameIndexMap.clear(); VarToAbstractVarMap.clear(); DbgVariableToDbgInstMap.clear(); Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=104720&r1=104719&r2=104720&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Wed May 26 14:37:24 2010 @@ -227,6 +227,13 @@ /// instruction. DenseMap LabelsAfterInsn; + /// insnNeedsLabel - Collection of instructions that need a label to mark + /// a debuggging information entity. + SmallPtrSet InsnNeedsLabel; + + /// ProcessedArgs - Collection of arguments already processed. + SmallPtrSet ProcessedArgs; + SmallVector DebugRangeSymbols; /// Previous instruction's location information. This is used to determine From isanbard at gmail.com Wed May 26 14:46:13 2010 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 26 May 2010 19:46:13 -0000 Subject: [llvm-commits] [llvm] r104722 - in /llvm/trunk: include/llvm/CodeGen/MachineFunction.h lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp lib/CodeGen/StackSlotColoring.cpp Message-ID: <20100526194613.27A54312800A@llvm.org> Author: void Date: Wed May 26 14:46:12 2010 New Revision: 104722 URL: http://llvm.org/viewvc/llvm-project?rev=104722&view=rev Log: Move the check for "calls setjmp" to SelectionDAGISel so that it can be used by more than just the stack slot coloring algorithm. Modified: llvm/trunk/include/llvm/CodeGen/MachineFunction.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Modified: llvm/trunk/include/llvm/CodeGen/MachineFunction.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineFunction.h?rev=104722&r1=104721&r2=104722&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineFunction.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineFunction.h Wed May 26 14:46:12 2010 @@ -114,9 +114,14 @@ /// unsigned FunctionNumber; - /// The alignment of the function. + /// Alignment - The alignment of the function. unsigned Alignment; + /// CallsSetJmp - True if the function calls setjmp or sigsetjmp. This is used + /// to limit optimizations which cannot reason about the control flow of + /// setjmp. + bool CallsSetJmp; + MachineFunction(const MachineFunction &); // DO NOT IMPLEMENT void operator=(const MachineFunction&); // DO NOT IMPLEMENT public: @@ -181,6 +186,17 @@ void EnsureAlignment(unsigned A) { if (Alignment < A) Alignment = A; } + + /// callsSetJmp - Returns true if the function calls setjmp or sigsetjmp. + bool callsSetJmp() const { + return CallsSetJmp; + } + + /// setCallsSetJmp - Set a flag that indicates if there's a call to setjmp or + /// sigsetjmp. + void setCallsSetJmp(bool B) { + CallsSetJmp = B; + } /// getInfo - Keep track of various per-function pieces of information for /// backends that would like to do so. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=104722&r1=104721&r2=104722&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed May 26 14:46:12 2010 @@ -25,6 +25,7 @@ #include "llvm/Intrinsics.h" #include "llvm/IntrinsicInst.h" #include "llvm/LLVMContext.h" +#include "llvm/Module.h" #include "llvm/CodeGen/FastISel.h" #include "llvm/CodeGen/GCStrategy.h" #include "llvm/CodeGen/GCMetadata.h" @@ -191,6 +192,34 @@ MachineFunctionPass::getAnalysisUsage(AU); } +/// FunctionCallsSetJmp - Return true if the function has a call to setjmp or +/// sigsetjmp. This is used to limit code-gen optimizations on the machine +/// function. +static bool FunctionCallsSetJmp(const Function *F) { + const Module *M = F->getParent(); + const Function *SetJmp = M->getFunction("setjmp"); + const Function *SigSetJmp = M->getFunction("sigsetjmp"); + + if (!SetJmp && !SigSetJmp) + return false; + + if (SetJmp && !SetJmp->use_empty()) + for (Value::const_use_iterator + I = SetJmp->use_begin(), E = SetJmp->use_end(); I != E; ++I) + if (const CallInst *CI = dyn_cast(I)) + if (CI->getParent()->getParent() == F) + return true; + + if (SigSetJmp && !SigSetJmp->use_empty()) + for (Value::const_use_iterator + I = SigSetJmp->use_begin(), E = SigSetJmp->use_end(); I != E; ++I) + if (const CallInst *CI = dyn_cast(I)) + if (CI->getParent()->getParent() == F) + return true; + + return false; +} + bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) { // Do some sanity-checking on the command-line options. assert((!EnableFastISelVerbose || EnableFastISel) && @@ -253,6 +282,9 @@ done:; } + // Determine if there is a call to setjmp in the machine function. + MF->setCallsSetJmp(FunctionCallsSetJmp(&Fn)); + // Release function-specific state. SDB and CurDAG are already cleared // at this point. FuncInfo->clear(); Modified: llvm/trunk/lib/CodeGen/StackSlotColoring.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackSlotColoring.cpp?rev=104722&r1=104721&r2=104722&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StackSlotColoring.cpp (original) +++ llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Wed May 26 14:46:12 2010 @@ -162,34 +162,6 @@ }; } -/// CheckForSetJmpCall - Return true if there's a call to setjmp/sigsetjmp in -/// this function. -bool StackSlotColoring::CheckForSetJmpCall(const MachineFunction &MF) const { - const Function *F = MF.getFunction(); - const Module *M = F->getParent(); - const Function *SetJmp = M->getFunction("setjmp"); - const Function *SigSetJmp = M->getFunction("sigsetjmp"); - - if (!SetJmp && !SigSetJmp) - return false; - - if (SetJmp && !SetJmp->use_empty()) - for (Value::const_use_iterator - I = SetJmp->use_begin(), E = SetJmp->use_end(); I != E; ++I) - if (const CallInst *CI = dyn_cast(I)) - if (CI->getParent()->getParent() == F) - return true; - - if (SigSetJmp && !SigSetJmp->use_empty()) - for (Value::const_use_iterator - I = SigSetJmp->use_begin(), E = SigSetJmp->use_end(); I != E; ++I) - if (const CallInst *CI = dyn_cast(I)) - if (CI->getParent()->getParent() == F) - return true; - - return false; -} - /// ScanForSpillSlotRefs - Scan all the machine instructions for spill slot /// references and update spill slot weights. void StackSlotColoring::ScanForSpillSlotRefs(MachineFunction &MF) { @@ -757,10 +729,7 @@ // coloring. The stack could be modified before the longjmp is executed, // resulting in the wrong value being used afterwards. (See // .) - // - // FIXME: This goes beyond the setjmp/sigsetjmp functions. Ideally, we should - // check for the GCC "returns twice" attribute. - if (CheckForSetJmpCall(MF)) + if (MF.callsSetJmp()) return false; // Gather spill slot references From baldrick at free.fr Wed May 26 14:46:59 2010 From: baldrick at free.fr (Duncan Sands) Date: Wed, 26 May 2010 19:46:59 -0000 Subject: [llvm-commits] [dragonegg] r104723 - /dragonegg/trunk/llvm-backend.cpp Message-ID: <20100526194659.3913F312800A@llvm.org> Author: baldrick Date: Wed May 26 14:46:59 2010 New Revision: 104723 URL: http://llvm.org/viewvc/llvm-project?rev=104723&view=rev Log: Turn off ODR linkage for C++ because it breaks the 32 bit dragonegg self-host build. It looks like it causes LLVM to be miscompiled, which then shows up as problems later when the miscompiled LLVM is used to compile dragonegg. Modified: dragonegg/trunk/llvm-backend.cpp Modified: dragonegg/trunk/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-backend.cpp?rev=104723&r1=104722&r2=104723&view=diff ============================================================================== --- dragonegg/trunk/llvm-backend.cpp (original) +++ dragonegg/trunk/llvm-backend.cpp Wed May 26 14:46:59 2010 @@ -542,7 +542,7 @@ } else if (LanguageName == "GNU C") { flag_vararg_requires_arguments = true; // "T foo() {}" -> "T foo(void) {}" } else if (LanguageName == "GNU C++") { - flag_odr = true; // C++ obeys the one-definition-rule +// flag_odr = true; // C++ obeys the one-definition-rule } else if (LanguageName == "GNU Fortran") { } else if (LanguageName == "GNU GIMPLE") { // LTO gold plugin } else if (LanguageName == "GNU Java") { From bob.wilson at apple.com Wed May 26 14:52:55 2010 From: bob.wilson at apple.com (Bob Wilson) Date: Wed, 26 May 2010 19:52:55 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r104726 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <20100526195255.7C745312800A@llvm.org> Author: bwilson Date: Wed May 26 14:52:55 2010 New Revision: 104726 URL: http://llvm.org/viewvc/llvm-project?rev=104726&view=rev Log: Set the sideeffect flag on an inline asm when replacing an output constraint for a register variable with the specific register to which that variable has been pinned. Otherwise, the asm may appear to be unused and may be removed as dead code. Testcase to follow. Radar 8026855. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=104726&r1=104725&r2=104726&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Wed May 26 14:52:55 2010 @@ -4670,6 +4670,7 @@ std::vector CallArgTypes; std::string NewAsmStr = ConvertInlineAsmStr(exp, NumOutputs+NumInputs); std::string ConstraintStr; + bool HasSideEffects = ASM_VOLATILE_P(exp) || !ASM_OUTPUTS(exp); // StoreCallResultAddr - The pointer to store the result of the call through. SmallVector StoreCallResultAddrs; @@ -4718,6 +4719,8 @@ NewConstraint[RegNameLen+2] = '}'; NewConstraint[RegNameLen+3] = 0; SimplifiedConstraint = NewConstraint; + // This output will now be implicit; set the sideffect flag on the asm. + HasSideEffects = true; // We should no longer consider mem constraints. AllowsMem = false; } else { @@ -4952,8 +4955,7 @@ } Value *Asm = InlineAsm::get(FTy, NewAsmStr, ConstraintStr, - ASM_VOLATILE_P(exp) || !ASM_OUTPUTS(exp), - ASM_ASM_BLOCK(exp)); + HasSideEffects, ASM_ASM_BLOCK(exp)); CallInst *CV = Builder.CreateCall(Asm, CallOps.begin(), CallOps.end(), CallResultTypes.empty() ? "" : "asmtmp"); CV->setDoesNotThrow(); From gkistanova at gmail.com Wed May 26 14:57:13 2010 From: gkistanova at gmail.com (Galina Kistanova) Date: Wed, 26 May 2010 12:57:13 -0700 Subject: [llvm-commits] [PATCH] 2 stage llvm-gcc builder for buildbot In-Reply-To: References: Message-ID: Hello everyonel, Just wondering are these changes committable? Thanks Galina On Mon, May 24, 2010 at 7:21 PM, Galina Kistanova wrote: > Hello everyone, > > Please find attached 2 patches. They add a new build script and a new > builder for cross built self-hosted llvm and llvm-gcc. > > The build script firstly builds a cross llvm-gcc > (--build=x86_64-apple-darwin10 --host=x86_64-apple-darwin10 > --target=i686-pc-mingw32), then it cross builds a self-hosted llvm-gcc > (--build=x86_64-apple-darwin10 --host=i686-pc-mingw32 > --target=i686-pc-mingw32) with just built cross compiler. > > Please review. > > Thanks > > Galina > From enderby at apple.com Wed May 26 15:10:45 2010 From: enderby at apple.com (Kevin Enderby) Date: Wed, 26 May 2010 20:10:45 -0000 Subject: [llvm-commits] [llvm] r104731 - in /llvm/trunk: lib/Target/X86/X86InstrInfo.td lib/Target/X86/X86RegisterInfo.cpp test/MC/AsmParser/X86/x86_32-new-encoder.s Message-ID: <20100526201045.7AB60312800A@llvm.org> Author: enderby Date: Wed May 26 15:10:45 2010 New Revision: 104731 URL: http://llvm.org/viewvc/llvm-project?rev=104731&view=rev Log: Fix the x86 move to/from segment register instructions. Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=104731&r1=104730&r2=104731&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Wed May 26 15:10:45 2010 @@ -1028,13 +1028,21 @@ // Moves to and from segment registers def MOV16rs : I<0x8C, MRMDestReg, (outs GR16:$dst), (ins SEGMENT_REG:$src), - "mov{w}\t{$src, $dst|$dst, $src}", []>; + "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize; +def MOV32rs : I<0x8C, MRMDestReg, (outs GR32:$dst), (ins SEGMENT_REG:$src), + "mov{l}\t{$src, $dst|$dst, $src}", []>; def MOV16ms : I<0x8C, MRMDestMem, (outs i16mem:$dst), (ins SEGMENT_REG:$src), - "mov{w}\t{$src, $dst|$dst, $src}", []>; + "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize; +def MOV32ms : I<0x8C, MRMDestMem, (outs i32mem:$dst), (ins SEGMENT_REG:$src), + "mov{l}\t{$src, $dst|$dst, $src}", []>; def MOV16sr : I<0x8E, MRMSrcReg, (outs SEGMENT_REG:$dst), (ins GR16:$src), - "mov{w}\t{$src, $dst|$dst, $src}", []>; + "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize; +def MOV32sr : I<0x8E, MRMSrcReg, (outs SEGMENT_REG:$dst), (ins GR32:$src), + "mov{l}\t{$src, $dst|$dst, $src}", []>; def MOV16sm : I<0x8E, MRMSrcMem, (outs SEGMENT_REG:$dst), (ins i16mem:$src), - "mov{w}\t{$src, $dst|$dst, $src}", []>; + "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize; +def MOV32sm : I<0x8E, MRMSrcMem, (outs SEGMENT_REG:$dst), (ins i32mem:$src), + "mov{l}\t{$src, $dst|$dst, $src}", []>; def MOV8rr_REV : I<0x8A, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src), "mov{b}\t{$src, $dst|$dst, $src}", []>; Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp?rev=104731&r1=104730&r2=104731&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Wed May 26 15:10:45 2010 @@ -144,6 +144,19 @@ case X86::XMM7: case X86::XMM15: case X86::MM7: return 7; + case X86::ES: + return 0; + case X86::CS: + return 1; + case X86::SS: + return 2; + case X86::DS: + return 3; + case X86::FS: + return 4; + case X86::GS: + return 5; + default: assert(isVirtualRegister(RegNo) && "Unknown physical register!"); llvm_unreachable("Register allocator hasn't allocated reg correctly yet!"); Modified: llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s?rev=104731&r1=104730&r2=104731&view=diff ============================================================================== --- llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s (original) +++ llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s Wed May 26 15:10:45 2010 @@ -302,3 +302,32 @@ // CHECK: fdiv %st(0) // CHECK: encoding: [0xd8,0xf0] fdiv %st(0), %st + +// radr://8017519 +// CHECK: movl %cs, %eax +// CHECK: encoding: [0x8c,0xc8] + movl %cs, %eax + +// CHECK: movw %cs, %ax +// CHECK: encoding: [0x66,0x8c,0xc8] + movw %cs, %ax + +// CHECK: movl %cs, (%eax) +// CHECK: encoding: [0x8c,0x08] + movl %cs, (%eax) + +// CHECK: movw %cs, (%eax) +// CHECK: encoding: [0x66,0x8c,0x08] + movw %cs, (%eax) + +// CHECK: movl %eax, %cs +// CHECK: encoding: [0x8e,0xc8] + movl %eax, %cs + +// CHECK: movl (%eax), %cs +// CHECK: encoding: [0x8e,0x08] + movl (%eax), %cs + +// CHECK: movw (%eax), %cs +// CHECK: encoding: [0x66,0x8e,0x08] + movw (%eax), %cs From dpatel at apple.com Wed May 26 15:18:51 2010 From: dpatel at apple.com (Devang Patel) Date: Wed, 26 May 2010 20:18:51 -0000 Subject: [llvm-commits] [llvm] r104732 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp test/CodeGen/X86/2010-05-26-DotDebugLoc.ll Message-ID: <20100526201851.316CD312800A@llvm.org> Author: dpatel Date: Wed May 26 15:18:50 2010 New Revision: 104732 URL: http://llvm.org/viewvc/llvm-project?rev=104732&view=rev Log: Update debug info when live-in reg is copied into a vreg. Added: llvm/trunk/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=104732&r1=104731&r2=104732&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed May 26 15:18:50 2010 @@ -250,6 +250,13 @@ MachineBasicBlock *EntryMBB = MF->begin(); RegInfo->EmitLiveInCopies(EntryMBB, TRI, TII); + DenseMap LiveInMap; + if (!FuncInfo->ArgDbgValues.empty()) + for (MachineRegisterInfo::livein_iterator LI = RegInfo->livein_begin(), + E = RegInfo->livein_end(); LI != E; ++LI) + if (LI->second) + LiveInMap.insert(std::make_pair(LI->first, LI->second)); + // Insert DBG_VALUE instructions for function arguments to the entry block. for (unsigned i = 0, e = FuncInfo->ArgDbgValues.size(); i != e; ++i) { MachineInstr *MI = FuncInfo->ArgDbgValues[e-i-1]; @@ -262,6 +269,21 @@ // FIXME: VR def may not be in entry block. Def->getParent()->insert(llvm::next(InsertPos), MI); } + + // If Reg is live-in then update debug info to track its copy in a vreg. + DenseMap::iterator LDI = LiveInMap.find(Reg); + if (LDI != LiveInMap.end()) { + MachineInstr *Def = RegInfo->getVRegDef(LDI->second); + MachineBasicBlock::iterator InsertPos = Def; + const MDNode *Variable = + MI->getOperand(MI->getNumOperands()-1).getMetadata(); + unsigned Offset = MI->getOperand(1).getImm(); + // Def is never a terminator here, so it is ok to increment InsertPos. + BuildMI(*EntryMBB, ++InsertPos, MI->getDebugLoc(), + TII.get(TargetOpcode::DBG_VALUE)) + .addReg(LDI->second, RegState::Debug) + .addImm(Offset).addMetadata(Variable); + } } // Determine if there are any calls in this machine function. Added: llvm/trunk/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll?rev=104732&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll (added) +++ llvm/trunk/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll Wed May 26 15:18:50 2010 @@ -0,0 +1,66 @@ +; RUN: llc -O2 < %s | FileCheck %s +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-apple-darwin" + +%struct.a = type { i32, %struct.a* } + + at llvm.used = appending global [1 x i8*] [i8* bitcast (i8* (%struct.a*)* @bar to i8*)], section "llvm.metadata" ; <[1 x i8*]*> [#uses=0] + +define i8* @bar(%struct.a* %myvar) nounwind optsize noinline ssp { +entry: + tail call void @llvm.dbg.value(metadata !{%struct.a* %myvar}, i64 0, metadata !8) + %0 = getelementptr inbounds %struct.a* %myvar, i64 0, i32 0, !dbg !28 ; [#uses=1] + %1 = load i32* %0, align 8, !dbg !28 ; [#uses=1] + tail call void @foo(i32 %1) nounwind optsize noinline ssp, !dbg !28 + %2 = bitcast %struct.a* %myvar to i8*, !dbg !30 ; [#uses=1] + ret i8* %2, !dbg !30 +} + +declare void @foo(i32) nounwind optsize noinline ssp + +declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone + +!llvm.dbg.gv = !{!0} +!llvm.dbg.lv = !{!4, !8, !18, !25, !26} + +!0 = metadata !{i32 524340, i32 0, metadata !1, metadata !"ret", metadata !"ret", metadata !"", metadata !1, i32 7, metadata !3, i1 false, i1 true, null} ; [ DW_TAG_variable ] +!1 = metadata !{i32 524329, metadata !"foo.c", metadata !"/tmp/", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 524305, i32 0, i32 1, metadata !"foo.c", metadata !"/tmp/", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 524324, metadata !1, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!4 = metadata !{i32 524545, metadata !5, metadata !"x", metadata !1, i32 12, metadata !3} ; [ DW_TAG_arg_variable ] +!5 = metadata !{i32 524334, i32 0, metadata !1, metadata !"foo", metadata !"foo", metadata !"foo", metadata !1, i32 13, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true} ; [ DW_TAG_subprogram ] +!6 = metadata !{i32 524309, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !7, i32 0, null} ; [ DW_TAG_subroutine_type ] +!7 = metadata !{null, metadata !3} +!8 = metadata !{i32 524545, metadata !9, metadata !"myvar", metadata !1, i32 17, metadata !13} ; [ DW_TAG_arg_variable ] +!9 = metadata !{i32 524334, i32 0, metadata !1, metadata !"bar", metadata !"bar", metadata !"bar", metadata !1, i32 17, metadata !10, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true} ; [ DW_TAG_subprogram ] +!10 = metadata !{i32 524309, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !11, i32 0, null} ; [ DW_TAG_subroutine_type ] +!11 = metadata !{metadata !12, metadata !13} +!12 = metadata !{i32 524303, metadata !1, metadata !"", metadata !1, i32 0, i64 64, i64 64, i64 0, i32 0, null} ; [ DW_TAG_pointer_type ] +!13 = metadata !{i32 524303, metadata !1, metadata !"", metadata !1, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !14} ; [ DW_TAG_pointer_type ] +!14 = metadata !{i32 524307, metadata !1, metadata !"a", metadata !1, i32 2, i64 128, i64 64, i64 0, i32 0, null, metadata !15, i32 0, null} ; [ DW_TAG_structure_type ] +!15 = metadata !{metadata !16, metadata !17} +!16 = metadata !{i32 524301, metadata !14, metadata !"c", metadata !1, i32 3, i64 32, i64 32, i64 0, i32 0, metadata !3} ; [ DW_TAG_member ] +!17 = metadata !{i32 524301, metadata !14, metadata !"d", metadata !1, i32 4, i64 64, i64 64, i64 64, i32 0, metadata !13} ; [ DW_TAG_member ] +!18 = metadata !{i32 524545, metadata !19, metadata !"argc", metadata !1, i32 22, metadata !3} ; [ DW_TAG_arg_variable ] +!19 = metadata !{i32 524334, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"main", metadata !1, i32 22, metadata !20, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true} ; [ DW_TAG_subprogram ] +!20 = metadata !{i32 524309, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !21, i32 0, null} ; [ DW_TAG_subroutine_type ] +!21 = metadata !{metadata !3, metadata !3, metadata !22} +!22 = metadata !{i32 524303, metadata !1, metadata !"", metadata !1, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !23} ; [ DW_TAG_pointer_type ] +!23 = metadata !{i32 524303, metadata !1, metadata !"", metadata !1, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !24} ; [ DW_TAG_pointer_type ] +!24 = metadata !{i32 524324, metadata !1, metadata !"char", metadata !1, i32 0, i64 8, i64 8, i64 0, i32 0, i32 6} ; [ DW_TAG_base_type ] +!25 = metadata !{i32 524545, metadata !19, metadata !"argv", metadata !1, i32 22, metadata !22} ; [ DW_TAG_arg_variable ] +!26 = metadata !{i32 524544, metadata !27, metadata !"e", metadata !1, i32 23, metadata !14} ; [ DW_TAG_auto_variable ] +!27 = metadata !{i32 524299, metadata !19, i32 22, i32 0} ; [ DW_TAG_lexical_block ] +!28 = metadata !{i32 18, i32 0, metadata !29, null} +!29 = metadata !{i32 524299, metadata !9, i32 17, i32 0} ; [ DW_TAG_lexical_block ] +!30 = metadata !{i32 19, i32 0, metadata !29, null} + +; CHECK: Ldebug_loc1 +; CHECK-NEXT: .quad Lfunc_begin0 +; CHECK-NEXT: .quad Ltmp3 +; CHECK-NEXT: .short 1 +; CHECK-NEXT: .byte 85 +; CHECK-NEXT: .quad Ltmp3 +; CHECK-NEXT: .quad Lfunc_end +; CHECK-NEXT: .short 1 +; CHECK-NEXT: .byte 83 From grosbach at apple.com Wed May 26 15:22:18 2010 From: grosbach at apple.com (Jim Grosbach) Date: Wed, 26 May 2010 20:22:18 -0000 Subject: [llvm-commits] [llvm] r104734 - in /llvm/trunk: include/llvm/CodeGen/ISDOpcodes.h include/llvm/Intrinsics.td lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMISelLowering.h lib/Target/ARM/ARMInstrInfo.td Message-ID: <20100526202219.11868312800A@llvm.org> Author: grosbach Date: Wed May 26 15:22:18 2010 New Revision: 104734 URL: http://llvm.org/viewvc/llvm-project?rev=104734&view=rev Log: Adjust eh.sjlj.setjmp to properly have a chain and to have an opcode entry in ISD::. No functional change. Modified: llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h llvm/trunk/include/llvm/Intrinsics.td llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.h llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Modified: llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h?rev=104734&r1=104733&r2=104734&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h (original) +++ llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h Wed May 26 15:22:18 2010 @@ -95,6 +95,11 @@ // execution to HANDLER. Many platform-related details also :) EH_RETURN, + // OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) + // This corresponds to the eh.sjlj.setjmp intrinsic. + // It takes an input chain and a pointer to the jump buffer as inputs + // and returns an outchain. + EH_SJLJ_SETJMP, // OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) // This corresponds to the eh.sjlj.longjmp intrinsic. Modified: llvm/trunk/include/llvm/Intrinsics.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=104734&r1=104733&r2=104734&view=diff ============================================================================== --- llvm/trunk/include/llvm/Intrinsics.td (original) +++ llvm/trunk/include/llvm/Intrinsics.td Wed May 26 15:22:18 2010 @@ -306,12 +306,12 @@ def int_eh_dwarf_cfa : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty]>; let Properties = [IntrNoMem] in { - def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>, - GCCBuiltin<"__builtin_setjmp">; def int_eh_sjlj_lsda : Intrinsic<[llvm_ptr_ty]>; def int_eh_sjlj_callsite: Intrinsic<[], [llvm_i32_ty]>; } -def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty], [IntrWriteArgMem]>, +def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>, + GCCBuiltin<"__builtin_setjmp">; +def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty]>, GCCBuiltin<"__builtin_longjmp">; //===---------------- Generic Variable Attribute Intrinsics----------------===// Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=104734&r1=104733&r2=104734&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Wed May 26 15:22:18 2010 @@ -5627,6 +5627,8 @@ case ISD::LSDAADDR: return "LSDAADDR"; case ISD::EHSELECTION: return "EHSELECTION"; case ISD::EH_RETURN: return "EH_RETURN"; + case ISD::EH_SJLJ_SETJMP: return "EH_SJLJ_SETJMP"; + case ISD::EH_SJLJ_LONGJMP: return "EH_SJLJ_LONGJMP"; case ISD::ConstantPool: return "ConstantPool"; case ISD::ExternalSymbol: return "ExternalSymbol"; case ISD::BlockAddress: return "BlockAddress"; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=104734&r1=104733&r2=104734&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Wed May 26 15:22:18 2010 @@ -4038,8 +4038,14 @@ MMI.setCurrentCallSite(CI->getZExtValue()); return 0; } + case Intrinsic::eh_sjlj_setjmp: { + setValue(&I, DAG.getNode(ISD::EH_SJLJ_SETJMP, dl, MVT::i32, getRoot(), + getValue(I.getOperand(1)))); + return 0; + } case Intrinsic::eh_sjlj_longjmp: { - DAG.setRoot(DAG.getNode(ISD::EH_SJLJ_LONGJMP, dl, MVT::Other, getRoot(), + DAG.setRoot(DAG.getNode(ISD::EH_SJLJ_LONGJMP, dl, MVT::Other, + getRoot(), getValue(I.getOperand(1)))); return 0; } Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=104734&r1=104733&r2=104734&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Wed May 26 15:22:18 2010 @@ -412,6 +412,7 @@ // We want to custom lower some of our intrinsics. setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); + setOperationAction(ISD::EH_SJLJ_SETJMP, MVT::i32, Custom); setOperationAction(ISD::EH_SJLJ_LONGJMP, MVT::Other, Custom); setOperationAction(ISD::SETCC, MVT::i32, Expand); @@ -1549,6 +1550,16 @@ } SDValue +ARMTargetLowering::LowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const { + DebugLoc dl = Op.getDebugLoc(); + SDValue Val = Subtarget->isThumb() ? + DAG.getCopyFromReg(DAG.getEntryNode(), dl, ARM::SP, MVT::i32) : + DAG.getConstant(0, MVT::i32); + return DAG.getNode(ARMISD::EH_SJLJ_SETJMP, dl, MVT::i32, Op.getOperand(0), + Op.getOperand(1), Val); +} + +SDValue ARMTargetLowering::LowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const { DebugLoc dl = Op.getDebugLoc(); return DAG.getNode(ARMISD::EH_SJLJ_LONGJMP, dl, MVT::Other, Op.getOperand(0), @@ -1594,12 +1605,6 @@ } return Result; } - case Intrinsic::eh_sjlj_setjmp: - SDValue Val = Subtarget->isThumb() ? - DAG.getCopyFromReg(DAG.getEntryNode(), dl, ARM::SP, MVT::i32) : - DAG.getConstant(0, MVT::i32); - return DAG.getNode(ARMISD::EH_SJLJ_SETJMP, dl, MVT::i32, Op.getOperand(1), - Val); } } @@ -3183,6 +3188,7 @@ case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG); case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); case ISD::GLOBAL_OFFSET_TABLE: return LowerGLOBAL_OFFSET_TABLE(Op, DAG); + case ISD::EH_SJLJ_SETJMP: return LowerEH_SJLJ_SETJMP(Op, DAG); case ISD::EH_SJLJ_LONGJMP: return LowerEH_SJLJ_LONGJMP(Op, DAG); case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG, Subtarget); Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=104734&r1=104733&r2=104734&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Wed May 26 15:22:18 2010 @@ -287,6 +287,7 @@ DebugLoc dl, SelectionDAG &DAG, const CCValAssign &VA, ISD::ArgFlagsTy Flags) const; + SDValue LowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const; SDValue LowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const; SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *Subtarget) const; Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=104734&r1=104733&r2=104734&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Wed May 26 15:22:18 2010 @@ -101,7 +101,8 @@ def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInFlag ]>; def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>; -def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", SDT_ARMEH_SJLJ_Setjmp>; +def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", + SDT_ARMEH_SJLJ_Setjmp, [SDNPHasChain]>; def ARMeh_sjlj_longjmp: SDNode<"ARMISD::EH_SJLJ_LONGJMP", SDT_ARMEH_SJLJ_Longjmp, [SDNPHasChain]>; From daniel at zuster.org Wed May 26 15:37:00 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 26 May 2010 20:37:00 -0000 Subject: [llvm-commits] [llvm] r104735 - /llvm/trunk/lib/MC/MCMachOStreamer.cpp Message-ID: <20100526203700.D9128312800A@llvm.org> Author: ddunbar Date: Wed May 26 15:37:00 2010 New Revision: 104735 URL: http://llvm.org/viewvc/llvm-project?rev=104735&view=rev Log: MC/Mach-O: Factor out EmitInstTo{Fragment,Data} for emitting MCInst's as MCInstFragments or appending onto an MCDataFragment. Modified: llvm/trunk/lib/MC/MCMachOStreamer.cpp Modified: llvm/trunk/lib/MC/MCMachOStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCMachOStreamer.cpp?rev=104735&r1=104734&r2=104735&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCMachOStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCMachOStreamer.cpp Wed May 26 15:37:00 2010 @@ -60,6 +60,9 @@ return DF; } + void EmitInstToFragment(const MCInst &Inst); + void EmitInstToData(const MCInst &Inst); + public: MCMachOStreamer(MCContext &Context, TargetAsmBackend &TAB, raw_ostream &_OS, MCCodeEmitter *_Emitter) @@ -140,14 +143,14 @@ unsigned MaxBytesToEmit = 0); virtual void EmitValueToOffset(const MCExpr *Offset, unsigned char Value = 0); - + virtual void EmitFileDirective(StringRef Filename) { report_fatal_error("unsupported directive: '.file'"); } virtual void EmitDwarfFileDirective(unsigned FileNo, StringRef Filename) { report_fatal_error("unsupported directive: '.file'"); } - + virtual void EmitInstruction(const MCInst &Inst); virtual void Finish(); @@ -158,7 +161,7 @@ void MCMachOStreamer::SwitchSection(const MCSection *Section) { assert(Section && "Cannot switch to a null section!"); - + // If already in this section, then this is a noop. if (Section == CurSection) return; @@ -200,7 +203,7 @@ // FIXME: Cleanup this code, these bits should be emitted based on semantic // properties, not on the order of definition, etc. SD.setFlags(SD.getFlags() & ~SF_ReferenceTypeMask); - + Symbol->setSection(*CurSection); } @@ -308,7 +311,7 @@ void MCMachOStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { // Encode the 'desc' value into the lowest implementation defined bits. - assert(DescValue == (DescValue & SF_DescFlagsMask) && + assert(DescValue == (DescValue & SF_DescFlagsMask) && "Invalid .desc value!"); Assembler.getOrCreateSymbolData(*Symbol).setFlags(DescValue&SF_DescFlagsMask); } @@ -417,16 +420,26 @@ F->setAtom(CurrentAtomMap.lookup(CurSectionData)); } -void MCMachOStreamer::EmitInstruction(const MCInst &Inst) { - // Scan for values. - for (unsigned i = Inst.getNumOperands(); i--; ) - if (Inst.getOperand(i).isExpr()) - AddValueSymbols(Inst.getOperand(i).getExpr()); +void MCMachOStreamer::EmitInstToFragment(const MCInst &Inst) { + MCInstFragment *IF = new MCInstFragment(Inst, CurSectionData); + IF->setAtom(CurrentAtomMap.lookup(CurSectionData)); - CurSectionData->setHasInstructions(true); + // Add the fixups and data. + // + // FIXME: Revisit this design decision when relaxation is done, we may be + // able to get away with not storing any extra data in the MCInst. + SmallVector Fixups; + SmallString<256> Code; + raw_svector_ostream VecOS(Code); + Assembler.getEmitter().EncodeInstruction(Inst, VecOS, Fixups); + VecOS.flush(); + + IF->getCode() = Code; + IF->getFixups() = Fixups; +} - // FIXME-PERF: Common case is that we don't need to relax, encode directly - // onto the data fragments buffers. +void MCMachOStreamer::EmitInstToData(const MCInst &Inst) { + MCDataFragment *DF = getOrCreateDataFragment(); SmallVector Fixups; SmallString<256> Code; @@ -434,6 +447,22 @@ Assembler.getEmitter().EncodeInstruction(Inst, VecOS, Fixups); VecOS.flush(); + // Add the fixups and data. + for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { + Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size()); + DF->addFixup(Fixups[i]); + } + DF->getContents().append(Code.begin(), Code.end()); +} + +void MCMachOStreamer::EmitInstruction(const MCInst &Inst) { + // Scan for values. + for (unsigned i = Inst.getNumOperands(); i--; ) + if (Inst.getOperand(i).isExpr()) + AddValueSymbols(Inst.getOperand(i).getExpr()); + + CurSectionData->setHasInstructions(true); + // See if we might need to relax this instruction, if so it needs its own // fragment. // @@ -447,27 +476,10 @@ // total knowledge about undefined symbols at that point). Even now, though, // we can do a decent job, especially on Darwin where scattering means that we // are going to often know that we can never fully resolve a fixup. - if (Assembler.getBackend().MayNeedRelaxation(Inst)) { - MCInstFragment *IF = new MCInstFragment(Inst, CurSectionData); - IF->setAtom(CurrentAtomMap.lookup(CurSectionData)); - - // Add the fixups and data. - // - // FIXME: Revisit this design decision when relaxation is done, we may be - // able to get away with not storing any extra data in the MCInst. - IF->getCode() = Code; - IF->getFixups() = Fixups; - - return; - } - - // Add the fixups and data. - MCDataFragment *DF = getOrCreateDataFragment(); - for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { - Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size()); - DF->addFixup(Fixups[i]); - } - DF->getContents().append(Code.begin(), Code.end()); + if (Assembler.getBackend().MayNeedRelaxation(Inst)) + EmitInstToFragment(Inst); + else + EmitInstToData(Inst); } void MCMachOStreamer::Finish() { From daniel at zuster.org Wed May 26 15:37:03 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 26 May 2010 20:37:03 -0000 Subject: [llvm-commits] [llvm] r104736 - in /llvm/trunk/lib/MC: MCAssembler.cpp MCMachOStreamer.cpp Message-ID: <20100526203703.3F0573128018@llvm.org> Author: ddunbar Date: Wed May 26 15:37:03 2010 New Revision: 104736 URL: http://llvm.org/viewvc/llvm-project?rev=104736&view=rev Log: MC: When running with -mc-relax-all, we can eagerly relax instructions and avoid creating unnecessary MCInstFragments. Modified: llvm/trunk/lib/MC/MCAssembler.cpp llvm/trunk/lib/MC/MCMachOStreamer.cpp Modified: llvm/trunk/lib/MC/MCAssembler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=104736&r1=104735&r2=104736&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCAssembler.cpp (original) +++ llvm/trunk/lib/MC/MCAssembler.cpp Wed May 26 15:37:03 2010 @@ -845,11 +845,8 @@ for (unsigned i = 0, e = Fixups.size(); i != e; ++i) IF->getFixups().push_back(Fixups[i]); - // Update the layout, and remember that we relaxed. If we are relaxing - // everything, we can skip this step since nothing will depend on updating - // the values. - if (!getRelaxAll()) - Layout.UpdateForSlide(IF, SlideAmount); + // Update the layout, and remember that we relaxed. + Layout.UpdateForSlide(IF, SlideAmount); WasRelaxed = true; } } Modified: llvm/trunk/lib/MC/MCMachOStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCMachOStreamer.cpp?rev=104736&r1=104735&r2=104736&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCMachOStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCMachOStreamer.cpp Wed May 26 15:37:03 2010 @@ -463,23 +463,25 @@ CurSectionData->setHasInstructions(true); - // See if we might need to relax this instruction, if so it needs its own - // fragment. - // - // FIXME-PERF: Support target hook to do a fast path that avoids the encoder, - // when we can immediately tell that we will get something which might need - // relaxation (and compute its size). - // - // FIXME-PERF: We should also be smart about immediately relaxing instructions - // which we can already show will never possibly fit (we can also do a very - // good job of this before we do the first relaxation pass, because we have - // total knowledge about undefined symbols at that point). Even now, though, - // we can do a decent job, especially on Darwin where scattering means that we - // are going to often know that we can never fully resolve a fixup. - if (Assembler.getBackend().MayNeedRelaxation(Inst)) - EmitInstToFragment(Inst); - else + // If this instruction doesn't need relaxation, just emit it as data. + if (!Assembler.getBackend().MayNeedRelaxation(Inst)) { EmitInstToData(Inst); + return; + } + + // Otherwise, if we are relaxing everything, relax the instruction as much as + // possible and emit it as data. + if (Assembler.getRelaxAll()) { + MCInst Relaxed; + Assembler.getBackend().RelaxInstruction(Inst, Relaxed); + while (Assembler.getBackend().MayNeedRelaxation(Relaxed)) + Assembler.getBackend().RelaxInstruction(Relaxed, Relaxed); + EmitInstToData(Relaxed); + return; + } + + // Otherwise emit to a separate fragment. + EmitInstToFragment(Inst); } void MCMachOStreamer::Finish() { From isanbard at gmail.com Wed May 26 15:39:00 2010 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 26 May 2010 20:39:00 -0000 Subject: [llvm-commits] [llvm] r104737 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <20100526203900.6D697312800A@llvm.org> Author: void Date: Wed May 26 15:39:00 2010 New Revision: 104737 URL: http://llvm.org/viewvc/llvm-project?rev=104737&view=rev Log: Add "setjmp_syscall", "savectx", "qsetjmp", "vfork", "getcontext" to the list of usual suspects that could "return twice". Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=104737&r1=104736&r2=104737&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed May 26 15:39:00 2010 @@ -193,31 +193,34 @@ } /// FunctionCallsSetJmp - Return true if the function has a call to setjmp or -/// sigsetjmp. This is used to limit code-gen optimizations on the machine -/// function. +/// other function that gcc recognizes as "returning twice". This is used to +/// limit code-gen optimizations on the machine function. static bool FunctionCallsSetJmp(const Function *F) { const Module *M = F->getParent(); - const Function *SetJmp = M->getFunction("setjmp"); - const Function *SigSetJmp = M->getFunction("sigsetjmp"); - - if (!SetJmp && !SigSetJmp) - return false; - - if (SetJmp && !SetJmp->use_empty()) - for (Value::const_use_iterator - I = SetJmp->use_begin(), E = SetJmp->use_end(); I != E; ++I) - if (const CallInst *CI = dyn_cast(I)) - if (CI->getParent()->getParent() == F) - return true; - - if (SigSetJmp && !SigSetJmp->use_empty()) - for (Value::const_use_iterator - I = SigSetJmp->use_begin(), E = SigSetJmp->use_end(); I != E; ++I) - if (const CallInst *CI = dyn_cast(I)) - if (CI->getParent()->getParent() == F) - return true; + static const char *ReturnsTwiceFns[] = { + "setjmp", + "sigsetjmp", + "setjmp_syscall", + "savectx", + "qsetjmp", + "vfork", + "getcontext" + }; +#define NUM_RETURNS_TWICE_FNS sizeof(ReturnsTwiceFns) / sizeof(const char *) + + for (unsigned I = 0; I < NUM_RETURNS_TWICE_FNS; ++I) + if (const Function *Callee = M->getFunction(ReturnsTwiceFns[I])) { + if (!Callee->use_empty()) + for (Value::const_use_iterator + I = Callee->use_begin(), E = Callee->use_end(); + I != E; ++I) + if (const CallInst *CI = dyn_cast(I)) + if (CI->getParent()->getParent() == F) + return true; + } return false; +#undef NUM_RETURNS_TWICE_FNS } bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) { From evan.cheng at apple.com Wed May 26 15:48:02 2010 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 26 May 2010 13:48:02 -0700 Subject: [llvm-commits] [llvm] r104737 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp In-Reply-To: <20100526203900.6D697312800A@llvm.org> References: <20100526203900.6D697312800A@llvm.org> Message-ID: <2A330469-BF29-4E25-A6BD-933B290390BF@apple.com> Definitely not vfork. That's unnecessary. gcc is mistaken, we shouldn't follow it. Also, getcontext is such a generic name. It's a really bad idea to look for it. Evan On May 26, 2010, at 1:39 PM, Bill Wendling wrote: > Author: void > Date: Wed May 26 15:39:00 2010 > New Revision: 104737 > > URL: http://llvm.org/viewvc/llvm-project?rev=104737&view=rev > Log: > Add "setjmp_syscall", "savectx", "qsetjmp", "vfork", "getcontext" to the list of > usual suspects that could "return twice". > > Modified: > llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=104737&r1=104736&r2=104737&view=diff > ============================================================================== > --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed May 26 15:39:00 2010 > @@ -193,31 +193,34 @@ > } > > /// FunctionCallsSetJmp - Return true if the function has a call to setjmp or > -/// sigsetjmp. This is used to limit code-gen optimizations on the machine > -/// function. > +/// other function that gcc recognizes as "returning twice". This is used to > +/// limit code-gen optimizations on the machine function. > static bool FunctionCallsSetJmp(const Function *F) { > const Module *M = F->getParent(); > - const Function *SetJmp = M->getFunction("setjmp"); > - const Function *SigSetJmp = M->getFunction("sigsetjmp"); > - > - if (!SetJmp && !SigSetJmp) > - return false; > - > - if (SetJmp && !SetJmp->use_empty()) > - for (Value::const_use_iterator > - I = SetJmp->use_begin(), E = SetJmp->use_end(); I != E; ++I) > - if (const CallInst *CI = dyn_cast(I)) > - if (CI->getParent()->getParent() == F) > - return true; > - > - if (SigSetJmp && !SigSetJmp->use_empty()) > - for (Value::const_use_iterator > - I = SigSetJmp->use_begin(), E = SigSetJmp->use_end(); I != E; ++I) > - if (const CallInst *CI = dyn_cast(I)) > - if (CI->getParent()->getParent() == F) > - return true; > + static const char *ReturnsTwiceFns[] = { > + "setjmp", > + "sigsetjmp", > + "setjmp_syscall", > + "savectx", > + "qsetjmp", > + "vfork", > + "getcontext" > + }; > +#define NUM_RETURNS_TWICE_FNS sizeof(ReturnsTwiceFns) / sizeof(const char *) > + > + for (unsigned I = 0; I < NUM_RETURNS_TWICE_FNS; ++I) > + if (const Function *Callee = M->getFunction(ReturnsTwiceFns[I])) { > + if (!Callee->use_empty()) > + for (Value::const_use_iterator > + I = Callee->use_begin(), E = Callee->use_end(); > + I != E; ++I) > + if (const CallInst *CI = dyn_cast(I)) > + if (CI->getParent()->getParent() == F) > + return true; > + } > > return false; > +#undef NUM_RETURNS_TWICE_FNS > } > > bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) { > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From isanbard at gmail.com Wed May 26 16:03:42 2010 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 26 May 2010 14:03:42 -0700 Subject: [llvm-commits] [llvm] r104737 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp In-Reply-To: <2A330469-BF29-4E25-A6BD-933B290390BF@apple.com> References: <20100526203900.6D697312800A@llvm.org> <2A330469-BF29-4E25-A6BD-933B290390BF@apple.com> Message-ID: Should I remve savectx as well? -bw On May 26, 2010, at 1:48 PM, Evan Cheng wrote: > Definitely not vfork. That's unnecessary. gcc is mistaken, we shouldn't follow it. Also, getcontext is such a generic name. It's a really bad idea to look for it. > > Evan > > On May 26, 2010, at 1:39 PM, Bill Wendling wrote: > >> Author: void >> Date: Wed May 26 15:39:00 2010 >> New Revision: 104737 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=104737&view=rev >> Log: >> Add "setjmp_syscall", "savectx", "qsetjmp", "vfork", "getcontext" to the list of >> usual suspects that could "return twice". >> >> Modified: >> llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp >> >> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=104737&r1=104736&r2=104737&view=diff >> ============================================================================== >> --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) >> +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed May 26 15:39:00 2010 >> @@ -193,31 +193,34 @@ >> } >> >> /// FunctionCallsSetJmp - Return true if the function has a call to setjmp or >> -/// sigsetjmp. This is used to limit code-gen optimizations on the machine >> -/// function. >> +/// other function that gcc recognizes as "returning twice". This is used to >> +/// limit code-gen optimizations on the machine function. >> static bool FunctionCallsSetJmp(const Function *F) { >> const Module *M = F->getParent(); >> - const Function *SetJmp = M->getFunction("setjmp"); >> - const Function *SigSetJmp = M->getFunction("sigsetjmp"); >> - >> - if (!SetJmp && !SigSetJmp) >> - return false; >> - >> - if (SetJmp && !SetJmp->use_empty()) >> - for (Value::const_use_iterator >> - I = SetJmp->use_begin(), E = SetJmp->use_end(); I != E; ++I) >> - if (const CallInst *CI = dyn_cast(I)) >> - if (CI->getParent()->getParent() == F) >> - return true; >> - >> - if (SigSetJmp && !SigSetJmp->use_empty()) >> - for (Value::const_use_iterator >> - I = SigSetJmp->use_begin(), E = SigSetJmp->use_end(); I != E; ++I) >> - if (const CallInst *CI = dyn_cast(I)) >> - if (CI->getParent()->getParent() == F) >> - return true; >> + static const char *ReturnsTwiceFns[] = { >> + "setjmp", >> + "sigsetjmp", >> + "setjmp_syscall", >> + "savectx", >> + "qsetjmp", >> + "vfork", >> + "getcontext" >> + }; >> +#define NUM_RETURNS_TWICE_FNS sizeof(ReturnsTwiceFns) / sizeof(const char *) >> + >> + for (unsigned I = 0; I < NUM_RETURNS_TWICE_FNS; ++I) >> + if (const Function *Callee = M->getFunction(ReturnsTwiceFns[I])) { >> + if (!Callee->use_empty()) >> + for (Value::const_use_iterator >> + I = Callee->use_begin(), E = Callee->use_end(); >> + I != E; ++I) >> + if (const CallInst *CI = dyn_cast(I)) >> + if (CI->getParent()->getParent() == F) >> + return true; >> + } >> >> return false; >> +#undef NUM_RETURNS_TWICE_FNS >> } >> >> bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) { >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From gohman at apple.com Wed May 26 16:05:04 2010 From: gohman at apple.com (Dan Gohman) Date: Wed, 26 May 2010 14:05:04 -0700 Subject: [llvm-commits] [llvm] r104737 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp In-Reply-To: <2A330469-BF29-4E25-A6BD-933B290390BF@apple.com> References: <20100526203900.6D697312800A@llvm.org> <2A330469-BF29-4E25-A6BD-933B290390BF@apple.com> Message-ID: vfork and getcontext have wildly platform-dependent semantics. Handling them conservatively is reasonable, even if some platforms don't need it. Dan On May 26, 2010, at 1:48 PM, Evan Cheng wrote: > Definitely not vfork. That's unnecessary. gcc is mistaken, we shouldn't follow it. Also, getcontext is such a generic name. It's a really bad idea to look for it. > > Evan > > On May 26, 2010, at 1:39 PM, Bill Wendling wrote: > >> Author: void >> Date: Wed May 26 15:39:00 2010 >> New Revision: 104737 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=104737&view=rev >> Log: >> Add "setjmp_syscall", "savectx", "qsetjmp", "vfork", "getcontext" to the list of >> usual suspects that could "return twice". >> >> Modified: >> llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp >> From dalej at apple.com Wed May 26 16:14:31 2010 From: dalej at apple.com (Dale Johannesen) Date: Wed, 26 May 2010 14:14:31 -0700 Subject: [llvm-commits] [llvm] r104737 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp In-Reply-To: References: <20100526203900.6D697312800A@llvm.org> <2A330469-BF29-4E25-A6BD-933B290390BF@apple.com> Message-ID: <39292977-DC9E-44B0-9885-E622125C3392@apple.com> On May 26, 2010, at 2:05 PMPDT, Dan Gohman wrote: > vfork and getcontext have wildly platform-dependent semantics. > Handling > them conservatively is reasonable, even if some platforms don't need > it. > > Dan Agreed. Also, the performance of code in the area of a vfork call is not going to be critical. > On May 26, 2010, at 1:48 PM, Evan Cheng wrote: > >> Definitely not vfork. That's unnecessary. gcc is mistaken, we >> shouldn't follow it. Also, getcontext is such a generic name. It's >> a really bad idea to look for it. From dpatel at apple.com Wed May 26 16:23:47 2010 From: dpatel at apple.com (Devang Patel) Date: Wed, 26 May 2010 21:23:47 -0000 Subject: [llvm-commits] [llvm] r104740 - /llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Message-ID: <20100526212347.18236312800A@llvm.org> Author: dpatel Date: Wed May 26 16:23:46 2010 New Revision: 104740 URL: http://llvm.org/viewvc/llvm-project?rev=104740&view=rev Log: There is no need to force an line number entry (using previous location) for a temp label at unknown location. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=104740&r1=104739&r2=104740&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Wed May 26 16:23:46 2010 @@ -2289,12 +2289,11 @@ return; } - // If location is unknown then Use last known location for this DBG_VALUE + // If location is unknown then use temp label for this DBG_VALUE // instruction. if (MI->isDebugValue()) { - const MDNode *Scope = - PrevInstLoc.getScope(Asm->MF->getFunction()->getContext()); - PrevLabel = recordSourceLine(PrevInstLoc.getLine(), PrevInstLoc.getCol(), Scope); + PrevLabel = MMI->getContext().CreateTempSymbol(); + Asm->OutStreamer.EmitLabel(PrevLabel); LabelsBeforeInsn[MI] = PrevLabel; return; } From stoklund at 2pi.dk Wed May 26 16:35:55 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 26 May 2010 21:35:55 -0000 Subject: [llvm-commits] [llvm] r104741 - /llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <20100526213555.475EE312800A@llvm.org> Author: stoklund Date: Wed May 26 16:35:55 2010 New Revision: 104741 URL: http://llvm.org/viewvc/llvm-project?rev=104741&view=rev Log: Suppress emmission of empty subreg/superreg/alias sets. Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp?rev=104741&r1=104740&r2=104741&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Wed May 26 16:35:55 2010 @@ -719,6 +719,8 @@ // to memory. for (std::map, LessRecord >::iterator I = RegisterAliases.begin(), E = RegisterAliases.end(); I != E; ++I) { + if (I->second.empty()) + continue; OS << " const unsigned " << I->first->getName() << "_AliasSet[] = { "; for (std::set::iterator ASI = I->second.begin(), E = I->second.end(); ASI != E; ++ASI) @@ -735,6 +737,8 @@ // sub-registers list to memory. for (std::map, LessRecord>::iterator I = RegisterSubRegs.begin(), E = RegisterSubRegs.end(); I != E; ++I) { + if (I->second.empty()) + continue; OS << " const unsigned " << I->first->getName() << "_SubRegsSet[] = { "; std::vector SubRegsVector; for (std::set::iterator ASI = I->second.begin(), @@ -756,6 +760,8 @@ // super-registers list to memory. for (std::map, LessRecord >::iterator I = RegisterSuperRegs.begin(), E = RegisterSuperRegs.end(); I != E; ++I) { + if (I->second.empty()) + continue; OS << " const unsigned " << I->first->getName() << "_SuperRegsSet[] = { "; std::vector SuperRegsVector; @@ -778,15 +784,15 @@ const CodeGenRegister &Reg = Regs[i]; OS << " { \""; OS << Reg.getName() << "\",\t"; - if (RegisterAliases.count(Reg.TheDef)) + if (!RegisterAliases[Reg.TheDef].empty()) OS << Reg.getName() << "_AliasSet,\t"; else OS << "Empty_AliasSet,\t"; - if (RegisterSubRegs.count(Reg.TheDef)) + if (!RegisterSubRegs[Reg.TheDef].empty()) OS << Reg.getName() << "_SubRegsSet,\t"; else OS << "Empty_SubRegsSet,\t"; - if (RegisterSuperRegs.count(Reg.TheDef)) + if (!RegisterSuperRegs[Reg.TheDef].empty()) OS << Reg.getName() << "_SuperRegsSet },\n"; else OS << "Empty_SuperRegsSet },\n"; From gohman at apple.com Wed May 26 16:46:36 2010 From: gohman at apple.com (Dan Gohman) Date: Wed, 26 May 2010 21:46:36 -0000 Subject: [llvm-commits] [llvm] r104744 - in /llvm/trunk: lib/Analysis/Lint.cpp test/Other/lint.ll Message-ID: <20100526214636.99734312800A@llvm.org> Author: djg Date: Wed May 26 16:46:36 2010 New Revision: 104744 URL: http://llvm.org/viewvc/llvm-project?rev=104744&view=rev Log: Implement checking of the tail keyword. Modified: llvm/trunk/lib/Analysis/Lint.cpp llvm/trunk/test/Other/lint.ll Modified: llvm/trunk/lib/Analysis/Lint.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/Lint.cpp?rev=104744&r1=104743&r2=104744&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/Lint.cpp (original) +++ llvm/trunk/lib/Analysis/Lint.cpp Wed May 26 16:46:36 2010 @@ -219,7 +219,15 @@ // TODO: Check sret attribute. } - // TODO: Check the "tail" keyword constraints. + if (CS.isCall() && cast(CS.getInstruction())->isTailCall()) + for (CallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end(); + AI != AE; ++AI) { + Value *Obj = (*AI)->getUnderlyingObject(); + Assert1(!isa(Obj) && !isa(Obj), + "Undefined behavior: Call with \"tail\" keyword references " + "alloca or va_arg", &I); + } + if (IntrinsicInst *II = dyn_cast(&I)) switch (II->getIntrinsicID()) { Modified: llvm/trunk/test/Other/lint.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/lint.ll?rev=104744&r1=104743&r2=104744&view=diff ============================================================================== --- llvm/trunk/test/Other/lint.ll (original) +++ llvm/trunk/test/Other/lint.ll Wed May 26 16:46:36 2010 @@ -77,8 +77,20 @@ ret void } +; CHECK: Undefined behavior: Branch to non-blockaddress define void @use_indbr() { indirectbr i8* bitcast (i32()* @foo to i8*), [label %block] block: unreachable } + +; CHECK: Undefined behavior: Call with "tail" keyword references alloca or va_arg +; CHECK: Undefined behavior: Call with "tail" keyword references alloca or va_arg +declare void @tailcallee(i8*) +define void @use_tail(i8* %valist) { + %t = alloca i8 + tail call void @tailcallee(i8* %t) + %s = va_arg i8* %valist, i8* + tail call void @tailcallee(i8* %s) + ret void +} From stoklund at 2pi.dk Wed May 26 16:47:28 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 26 May 2010 21:47:28 -0000 Subject: [llvm-commits] [llvm] r104745 - in /llvm/trunk: include/llvm/ADT/StringRef.h lib/Support/StringRef.cpp lib/Target/X86/SSEDomainFix.cpp unittests/ADT/StringRefTest.cpp utils/TableGen/CodeGenTarget.cpp utils/TableGen/Record.h Message-ID: <20100526214728.9BD1F312800A@llvm.org> Author: stoklund Date: Wed May 26 16:47:28 2010 New Revision: 104745 URL: http://llvm.org/viewvc/llvm-project?rev=104745&view=rev Log: Add StringRef::compare_numeric and use it to sort TableGen register records. This means that our Registers are now ordered R7, R8, R9, R10, R12, ... Not R1, R10, R11, R12, R2, R3, ... Modified: llvm/trunk/include/llvm/ADT/StringRef.h llvm/trunk/lib/Support/StringRef.cpp llvm/trunk/lib/Target/X86/SSEDomainFix.cpp llvm/trunk/unittests/ADT/StringRefTest.cpp llvm/trunk/utils/TableGen/CodeGenTarget.cpp llvm/trunk/utils/TableGen/Record.h Modified: llvm/trunk/include/llvm/ADT/StringRef.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/StringRef.h?rev=104745&r1=104744&r2=104745&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/StringRef.h (original) +++ llvm/trunk/include/llvm/ADT/StringRef.h Wed May 26 16:47:28 2010 @@ -128,6 +128,10 @@ /// compare_lower - Compare two strings, ignoring case. int compare_lower(StringRef RHS) const; + /// compare_numeric - Compare two strings, treating sequences of digits as + /// numbers. + int compare_numeric(StringRef RHS) const; + /// \brief Determine the edit distance between this string and another /// string. /// Modified: llvm/trunk/lib/Support/StringRef.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/StringRef.cpp?rev=104745&r1=104744&r2=104745&view=diff ============================================================================== --- llvm/trunk/lib/Support/StringRef.cpp (original) +++ llvm/trunk/lib/Support/StringRef.cpp Wed May 26 16:47:28 2010 @@ -23,6 +23,10 @@ return x; } +static bool ascii_isdigit(char x) { + return x >= '0' && x <= '9'; +} + /// compare_lower - Compare strings, ignoring case. int StringRef::compare_lower(StringRef RHS) const { for (size_t I = 0, E = min(Length, RHS.Length); I != E; ++I) { @@ -37,6 +41,30 @@ return Length < RHS.Length ? -1 : 1; } +/// compare_numeric - Compare strings, handle embedded numbers. +int StringRef::compare_numeric(StringRef RHS) const { + for (size_t I = 0, E = min(Length, RHS.Length); I != E; ++I) { + if (Data[I] == RHS.Data[I]) + continue; + if (ascii_isdigit(Data[I]) && ascii_isdigit(RHS.Data[I])) { + // The longer sequence of numbers is larger. This doesn't really handle + // prefixed zeros well. + for (size_t J = I+1; J != E+1; ++J) { + bool ld = J < Length && ascii_isdigit(Data[J]); + bool rd = J < RHS.Length && ascii_isdigit(RHS.Data[J]); + if (ld != rd) + return rd ? -1 : 1; + if (!rd) + break; + } + } + return Data[I] < RHS.Data[I] ? -1 : 1; + } + if (Length == RHS.Length) + return 0; + return Length < RHS.Length ? -1 : 1; +} + // Compute the edit distance between the two given strings. unsigned StringRef::edit_distance(llvm::StringRef Other, bool AllowReplacements) { Modified: llvm/trunk/lib/Target/X86/SSEDomainFix.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/SSEDomainFix.cpp?rev=104745&r1=104744&r2=104745&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/SSEDomainFix.cpp (original) +++ llvm/trunk/lib/Target/X86/SSEDomainFix.cpp Wed May 26 16:47:28 2010 @@ -155,9 +155,7 @@ /// Translate TRI register number to an index into our smaller tables of /// interesting registers. Return -1 for boring registers. int SSEDomainFixPass::RegIndex(unsigned reg) { - // Registers are sorted lexicographically. - // We just need them to be consecutive, ordering doesn't matter. - assert(X86::XMM9 == X86::XMM0+NumRegs-1 && "Unexpected sort"); + assert(X86::XMM15 == X86::XMM0+NumRegs-1 && "Unexpected sort"); reg -= X86::XMM0; return reg < NumRegs ? (int) reg : -1; } Modified: llvm/trunk/unittests/ADT/StringRefTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/StringRefTest.cpp?rev=104745&r1=104744&r2=104745&view=diff ============================================================================== --- llvm/trunk/unittests/ADT/StringRefTest.cpp (original) +++ llvm/trunk/unittests/ADT/StringRefTest.cpp Wed May 26 16:47:28 2010 @@ -53,6 +53,17 @@ EXPECT_EQ( 1, StringRef("aab").compare("aaa")); EXPECT_EQ(-1, StringRef("aab").compare("aabb")); EXPECT_EQ( 1, StringRef("aab").compare("aa")); + + EXPECT_EQ(-1, StringRef("aab").compare_numeric("aad")); + EXPECT_EQ( 0, StringRef("aab").compare_numeric("aab")); + EXPECT_EQ( 1, StringRef("aab").compare_numeric("aaa")); + EXPECT_EQ(-1, StringRef("aab").compare_numeric("aabb")); + EXPECT_EQ( 1, StringRef("aab").compare_numeric("aa")); + EXPECT_EQ(-1, StringRef("1").compare_numeric("10")); + EXPECT_EQ( 0, StringRef("10").compare_numeric("10")); + EXPECT_EQ( 0, StringRef("10a").compare_numeric("10a")); + EXPECT_EQ( 1, StringRef("2").compare_numeric("1")); + EXPECT_EQ( 0, StringRef("llvm_v1i64_ty").compare_numeric("llvm_v1i64_ty")); } TEST(StringRefTest, Operators) { Modified: llvm/trunk/utils/TableGen/CodeGenTarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenTarget.cpp?rev=104745&r1=104744&r2=104745&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenTarget.cpp (original) +++ llvm/trunk/utils/TableGen/CodeGenTarget.cpp Wed May 26 16:47:28 2010 @@ -159,6 +159,7 @@ std::vector Regs = Records.getAllDerivedDefinitions("Register"); if (Regs.empty()) throw std::string("No 'Register' subclasses defined!"); + std::sort(Regs.begin(), Regs.end(), LessRecord()); Registers.reserve(Regs.size()); Registers.assign(Regs.begin(), Regs.end()); @@ -175,6 +176,7 @@ void CodeGenTarget::ReadSubRegIndices() const { SubRegIndices = Records.getAllDerivedDefinitions("SubRegIndex"); + std::sort(SubRegIndices.begin(), SubRegIndices.end(), LessRecord()); } void CodeGenTarget::ReadRegisterClasses() const { Modified: llvm/trunk/utils/TableGen/Record.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/Record.h?rev=104745&r1=104744&r2=104745&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/Record.h (original) +++ llvm/trunk/utils/TableGen/Record.h Wed May 26 16:47:28 2010 @@ -1461,7 +1461,7 @@ /// struct LessRecord { bool operator()(const Record *Rec1, const Record *Rec2) const { - return Rec1->getName() < Rec2->getName(); + return StringRef(Rec1->getName()).compare_numeric(Rec2->getName()) < 0; } }; From daniel at zuster.org Wed May 26 16:48:55 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 26 May 2010 21:48:55 -0000 Subject: [llvm-commits] [llvm] r104747 - in /llvm/trunk: include/llvm/Target/TargetMachine.h lib/CodeGen/LLVMTargetMachine.cpp lib/Target/TargetMachine.cpp Message-ID: <20100526214855.7707D312800A@llvm.org> Author: ddunbar Date: Wed May 26 16:48:55 2010 New Revision: 104747 URL: http://llvm.org/viewvc/llvm-project?rev=104747&view=rev Log: MC: Add TargetMachine support for setting the value of MCRelaxAll with -filetype=obj. Modified: llvm/trunk/include/llvm/Target/TargetMachine.h llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp llvm/trunk/lib/Target/TargetMachine.cpp Modified: llvm/trunk/include/llvm/Target/TargetMachine.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetMachine.h?rev=104747&r1=104746&r2=104747&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetMachine.h (original) +++ llvm/trunk/include/llvm/Target/TargetMachine.h Wed May 26 16:48:55 2010 @@ -101,7 +101,9 @@ /// AsmInfo - Contains target specific asm information. /// const MCAsmInfo *AsmInfo; - + + unsigned MCRelaxAll : 1; + public: virtual ~TargetMachine(); @@ -158,6 +160,14 @@ /// virtual const TargetELFWriterInfo *getELFWriterInfo() const { return 0; } + /// hasMCRelaxAll - Check whether all machine code instructions should be + /// relaxed. + bool hasMCRelaxAll() const { return MCRelaxAll; } + + /// setMCRelaxAll - Set whether all machine code instructions should be + /// relaxed. + void setMCRelaxAll(bool Value) { MCRelaxAll = Value; } + /// getRelocationModel - Returns the code generation relocation model. The /// choices are static, PIC, and dynamic-no-pic, and target default. static Reloc::Model getRelocationModel(); Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp?rev=104747&r1=104746&r2=104747&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp (original) +++ llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Wed May 26 16:48:55 2010 @@ -160,8 +160,10 @@ TargetAsmBackend *TAB = getTarget().createAsmBackend(TargetTriple); if (MCE == 0 || TAB == 0) return true; - - AsmStreamer.reset(createMachOStreamer(*Context, *TAB, Out, MCE)); + + AsmStreamer.reset(getTarget().createObjectStreamer(TargetTriple, *Context, + *TAB, Out, MCE, + hasMCRelaxAll())); break; } case CGFT_Null: Modified: llvm/trunk/lib/Target/TargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetMachine.cpp?rev=104747&r1=104746&r2=104747&view=diff ============================================================================== --- llvm/trunk/lib/Target/TargetMachine.cpp (original) +++ llvm/trunk/lib/Target/TargetMachine.cpp Wed May 26 16:48:55 2010 @@ -212,7 +212,8 @@ // TargetMachine::TargetMachine(const Target &T) - : TheTarget(T), AsmInfo(0) { + : TheTarget(T), AsmInfo(0), + MCRelaxAll(false) { // Typically it will be subtargets that will adjust FloatABIType from Default // to Soft or Hard. if (UseSoftFloat) From gohman at apple.com Wed May 26 16:50:41 2010 From: gohman at apple.com (Dan Gohman) Date: Wed, 26 May 2010 21:50:41 -0000 Subject: [llvm-commits] [llvm] r104748 - /llvm/trunk/lib/Analysis/Lint.cpp Message-ID: <20100526215041.E0FCF312800A@llvm.org> Author: djg Date: Wed May 26 16:50:41 2010 New Revision: 104748 URL: http://llvm.org/viewvc/llvm-project?rev=104748&view=rev Log: Remove a TODO which isn't practical. Modified: llvm/trunk/lib/Analysis/Lint.cpp Modified: llvm/trunk/lib/Analysis/Lint.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/Lint.cpp?rev=104748&r1=104747&r2=104748&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/Lint.cpp (original) +++ llvm/trunk/lib/Analysis/Lint.cpp Wed May 26 16:50:41 2010 @@ -193,7 +193,6 @@ Instruction &I = *CS.getInstruction(); Value *Callee = CS.getCalledValue(); - // TODO: Check function alignment? visitMemoryReference(I, Callee, 0, 0, MemRef::Callee); if (Function *F = dyn_cast(Callee->stripPointerCasts())) { From isanbard at gmail.com Wed May 26 16:53:50 2010 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 26 May 2010 21:53:50 -0000 Subject: [llvm-commits] [llvm] r104749 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <20100526215350.EB184312800A@llvm.org> Author: void Date: Wed May 26 16:53:50 2010 New Revision: 104749 URL: http://llvm.org/viewvc/llvm-project?rev=104749&view=rev Log: Add FIXME comment to remove this. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=104749&r1=104748&r2=104749&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed May 26 16:53:50 2010 @@ -195,6 +195,8 @@ /// FunctionCallsSetJmp - Return true if the function has a call to setjmp or /// other function that gcc recognizes as "returning twice". This is used to /// limit code-gen optimizations on the machine function. +/// +/// FIXME: Remove after is fixed. static bool FunctionCallsSetJmp(const Function *F) { const Module *M = F->getParent(); static const char *ReturnsTwiceFns[] = { From gohman at apple.com Wed May 26 16:56:15 2010 From: gohman at apple.com (Dan Gohman) Date: Wed, 26 May 2010 21:56:15 -0000 Subject: [llvm-commits] [llvm] r104750 - /llvm/trunk/docs/LangRef.html Message-ID: <20100526215616.0F437312800A@llvm.org> Author: djg Date: Wed May 26 16:56:15 2010 New Revision: 104750 URL: http://llvm.org/viewvc/llvm-project?rev=104750&view=rev Log: Fix a missing quote. Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=104750&r1=104749&r2=104750&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Wed May 26 16:56:15 2010 @@ -224,7 +224,7 @@
  • 'llvm.stackrestore' Intrinsic
  • 'llvm.prefetch' Intrinsic
  • 'llvm.pcmarker' Intrinsic
  • -
  • llvm.readcyclecounter' Intrinsic
  • +
  • 'llvm.readcyclecounter' Intrinsic
  • Standard C Library Intrinsics From espindola at google.com Wed May 26 16:58:09 2010 From: espindola at google.com (Rafael Espindola) Date: Wed, 26 May 2010 17:58:09 -0400 Subject: [llvm-commits] [patch][llvm-gcc] Fix calls to fabs Message-ID: The attached patch fixes the calls to fabs to correctly specify the calling convention. Before we would get call double @fabs(double %2) nounwind readnone With the patch we get call arm_aapcscc double @fabs(double %2) nounwind readnone Cheers, -- Rafael ?vila de Esp?ndola -------------- next part -------------- A non-text attachment was scrubbed... Name: fabs.patch Type: text/x-diff Size: 1434 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100526/89b1a362/attachment.bin From echristo at apple.com Wed May 26 17:00:17 2010 From: echristo at apple.com (Eric Christopher) Date: Wed, 26 May 2010 15:00:17 -0700 Subject: [llvm-commits] [patch][llvm-gcc] Fix calls to fabs In-Reply-To: References: Message-ID: On May 26, 2010, at 2:58 PM, Rafael Espindola wrote: > Yes please. Thanks! -eric From gohman at apple.com Wed May 26 17:00:10 2010 From: gohman at apple.com (Dan Gohman) Date: Wed, 26 May 2010 22:00:10 -0000 Subject: [llvm-commits] [llvm] r104752 - /llvm/trunk/lib/Analysis/Lint.cpp Message-ID: <20100526220011.01E463128018@llvm.org> Author: djg Date: Wed May 26 17:00:10 2010 New Revision: 104752 URL: http://llvm.org/viewvc/llvm-project?rev=104752&view=rev Log: Stackrestore is not a load. Modified: llvm/trunk/lib/Analysis/Lint.cpp Modified: llvm/trunk/lib/Analysis/Lint.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/Lint.cpp?rev=104752&r1=104751&r2=104752&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/Lint.cpp (original) +++ llvm/trunk/lib/Analysis/Lint.cpp Wed May 26 17:00:10 2010 @@ -285,11 +285,6 @@ visitMemoryReference(I, CS.getArgument(0), 0, 0, MemRef::Read | MemRef::Write); break; - - case Intrinsic::stackrestore: - visitMemoryReference(I, CS.getArgument(0), 0, 0, - MemRef::Read); - break; } } From rafael.espindola at gmail.com Wed May 26 17:05:04 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Wed, 26 May 2010 22:05:04 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r104753 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <20100526220504.6C546312800A@llvm.org> Author: rafael Date: Wed May 26 17:05:04 2010 New Revision: 104753 URL: http://llvm.org/viewvc/llvm-project?rev=104753&view=rev Log: Set the calling convention when calling fabs. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=104753&r1=104752&r2=104753&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Wed May 26 17:05:04 2010 @@ -3550,20 +3550,38 @@ // Turn FP abs into fabs/fabsf. const char *Name = 0; + tree ArgType; switch (Op->getType()->getTypeID()) { default: assert(0 && "Unknown FP type!"); - case Type::FloatTyID: Name = "fabsf"; break; - case Type::DoubleTyID: Name = "fabs"; break; + case Type::FloatTyID: + Name = "fabsf"; + ArgType = float_type_node; + break; + case Type::DoubleTyID: + Name = "fabs"; + ArgType = double_type_node; + break; case Type::X86_FP80TyID: case Type::PPC_FP128TyID: - case Type::FP128TyID: Name = "fabsl"; break; + case Type::FP128TyID: + Name = "fabsl"; + ArgType = long_double_type_node; + break; } Value *V = TheModule->getOrInsertFunction(Name, Op->getType(), Op->getType(), NULL); + // Determine the calling convention. + CallingConv::ID CallingConvention = CallingConv::C; +#ifdef TARGET_ADJUST_LLVM_CC + tree FunctionType = build_function_type_list(ArgType, ArgType ,NULL); + TARGET_ADJUST_LLVM_CC(CallingConvention, FunctionType); +#endif + CallInst *Call = Builder.CreateCall(V, Op); Call->setDoesNotThrow(); Call->setDoesNotAccessMemory(); + Call->setCallingConv(CallingConvention); return Call; } From stoklund at 2pi.dk Wed May 26 17:15:03 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 26 May 2010 22:15:03 -0000 Subject: [llvm-commits] [llvm] r104754 - /llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td Message-ID: <20100526221503.5AE30312800A@llvm.org> Author: stoklund Date: Wed May 26 17:15:03 2010 New Revision: 104754 URL: http://llvm.org/viewvc/llvm-project?rev=104754&view=rev Log: Give SubRegIndex names to all ARM subregisters. This will be required by TableGen shortly. Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td?rev=104754&r1=104753&r2=104754&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td Wed May 26 17:15:03 2010 @@ -26,10 +26,22 @@ // Subregister indices. let Namespace = "ARM" in { // Note: Code depends on these having consecutive numbers. -def ssub_0 : SubRegIndex; -def ssub_1 : SubRegIndex; -def ssub_2 : SubRegIndex; -def ssub_3 : SubRegIndex; +def ssub_0 : SubRegIndex; +def ssub_1 : SubRegIndex; +def ssub_2 : SubRegIndex; // In a Q reg. +def ssub_3 : SubRegIndex; +def ssub_4 : SubRegIndex; // In a QQ reg. +def ssub_5 : SubRegIndex; +def ssub_6 : SubRegIndex; +def ssub_7 : SubRegIndex; +def ssub_8 : SubRegIndex; // In a QQQQ reg. +def ssub_9 : SubRegIndex; +def ssub_10 : SubRegIndex; +def ssub_11 : SubRegIndex; +def ssub_12 : SubRegIndex; +def ssub_13 : SubRegIndex; +def ssub_14 : SubRegIndex; +def ssub_15 : SubRegIndex; def dsub_0 : SubRegIndex; def dsub_1 : SubRegIndex; @@ -146,32 +158,42 @@ // starting D register number doesn't have to be multiple of 4. e.g. // D1, D2, D3, D4 would be a legal quad. But that would make the sub-register // stuffs very messy. -let SubRegIndices = [qsub_0, qsub_1], - CompositeIndices = [(dsub_2 qsub_1, dsub_0), - (dsub_3 qsub_1, dsub_1)] in { +let SubRegIndices = [qsub_0, qsub_1] in { +let CompositeIndices = [(dsub_2 qsub_1, dsub_0), (dsub_3 qsub_1, dsub_1), + (ssub_4 qsub_1, ssub_0), (ssub_5 qsub_1, ssub_1), + (ssub_6 qsub_1, ssub_2), (ssub_7 qsub_1, ssub_3)] in { def QQ0 : ARMReg<0, "qq0", [Q0, Q1]>; def QQ1 : ARMReg<1, "qq1", [Q2, Q3]>; def QQ2 : ARMReg<2, "qq2", [Q4, Q5]>; def QQ3 : ARMReg<3, "qq3", [Q6, Q7]>; +} +let CompositeIndices = [(dsub_2 qsub_1, dsub_0), (dsub_3 qsub_1, dsub_1)] in { def QQ4 : ARMReg<4, "qq4", [Q8, Q9]>; def QQ5 : ARMReg<5, "qq5", [Q10, Q11]>; def QQ6 : ARMReg<6, "qq6", [Q12, Q13]>; def QQ7 : ARMReg<7, "qq7", [Q14, Q15]>; } +} // Pseudo 512-bit registers to represent four consecutive Q registers. -let SubRegIndices = [qqsub_0, qqsub_1], - CompositeIndices = [(qsub_2 qqsub_1, qsub_0), - (qsub_3 qqsub_1, qsub_1), - (dsub_4 qqsub_1, dsub_0), - (dsub_5 qqsub_1, dsub_1), - (dsub_6 qqsub_1, dsub_2), - (dsub_7 qqsub_1, dsub_3)] in { +let SubRegIndices = [qqsub_0, qqsub_1] in { +let CompositeIndices = [(qsub_2 qqsub_1, qsub_0), (qsub_3 qqsub_1, qsub_1), + (dsub_4 qqsub_1, dsub_0), (dsub_5 qqsub_1, dsub_1), + (dsub_6 qqsub_1, dsub_2), (dsub_7 qqsub_1, dsub_3), + (ssub_8 qqsub_1, ssub_0), (ssub_9 qqsub_1, ssub_1), + (ssub_10 qqsub_1, ssub_2), (ssub_11 qqsub_1, ssub_3), + (ssub_12 qqsub_1, ssub_4), (ssub_13 qqsub_1, ssub_5), + (ssub_14 qqsub_1, ssub_6), (ssub_15 qqsub_1, ssub_7)] in { def QQQQ0 : ARMReg<0, "qqqq0", [QQ0, QQ1]>; def QQQQ1 : ARMReg<1, "qqqq1", [QQ2, QQ3]>; +} +let CompositeIndices = [(qsub_2 qqsub_1, qsub_0), (qsub_3 qqsub_1, qsub_1), + (dsub_4 qqsub_1, dsub_0), (dsub_5 qqsub_1, dsub_1), + (dsub_6 qqsub_1, dsub_2), (dsub_7 qqsub_1, dsub_3)] in { def QQQQ2 : ARMReg<2, "qqqq2", [QQ4, QQ5]>; def QQQQ3 : ARMReg<3, "qqqq3", [QQ6, QQ7]>; } +} // Current Program Status Register. def CPSR : ARMReg<0, "cpsr">; From stoklund at 2pi.dk Wed May 26 17:15:07 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 26 May 2010 22:15:07 -0000 Subject: [llvm-commits] [llvm] r104755 - /llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <20100526221507.AA8663128018@llvm.org> Author: stoklund Date: Wed May 26 17:15:07 2010 New Revision: 104755 URL: http://llvm.org/viewvc/llvm-project?rev=104755&view=rev Log: Check that inherited subregisters all have a direct SubRegIndex. Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp?rev=104755&r1=104754&r2=104755&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Wed May 26 17:15:07 2010 @@ -186,7 +186,7 @@ if (SubRegs.size() != Indices.size()) throw "Register " + Reg->getName() + " SubRegIndices doesn't match SubRegs"; - // First insert the direct subregs. + // First insert the direct subregs and make sure they are fully indexed. for (unsigned i = 0, e = SubRegs.size(); i != e; ++i) { if (!SRM.insert(std::make_pair(Indices[i], SubRegs[i])).second) throw "SubRegIndex " + Indices[i]->getName() @@ -194,11 +194,18 @@ inferSubRegIndices(SubRegs[i], ASRM); } + // Keep track of inherited subregs and how they can be reached. + // Register -> (SubRegIndex, SubRegIndex) + typedef std::map, LessRecord> OrphanMap; + OrphanMap Orphans; + // Clone inherited subregs. Here the order is important - earlier subregs take // precedence. for (unsigned i = 0, e = SubRegs.size(); i != e; ++i) { SubRegMap &M = ASRM[SubRegs[i]]; - SRM.insert(M.begin(), M.end()); + for (SubRegMap::iterator si = M.begin(), se = M.end(); si != se; ++si) + if (!SRM.insert(*si).second) + Orphans[si->second] = std::make_pair(Indices[i], si->first); } // Finally process the composites. @@ -228,6 +235,22 @@ // Insert composite index. Allow overriding inherited indices etc. SRM[BaseIdxInit->getDef()] = R2; + + // R2 is now directly addressable, no longer an orphan. + Orphans.erase(R2); + } + + // Now, Orphans contains the inherited subregisters without a direct index. + if (!Orphans.empty()) { + errs() << "Error: Register " << getQualifiedName(Reg) + << " inherited subregisters without an index:\n"; + for (OrphanMap::iterator i = Orphans.begin(), e = Orphans.end(); i != e; + ++i) { + errs() << " " << getQualifiedName(i->first) + << " = " << i->second.first->getName() + << ", " << i->second.second->getName() << "\n"; + } + abort(); } return SRM; } From gohman at apple.com Wed May 26 17:21:25 2010 From: gohman at apple.com (Dan Gohman) Date: Wed, 26 May 2010 22:21:25 -0000 Subject: [llvm-commits] [llvm] r104756 - in /llvm/trunk: lib/Analysis/Lint.cpp test/Other/lint.ll Message-ID: <20100526222125.AC1B2312800A@llvm.org> Author: djg Date: Wed May 26 17:21:25 2010 New Revision: 104756 URL: http://llvm.org/viewvc/llvm-project?rev=104756&view=rev Log: Reinstate checking of stackrestore, with checking for both Read and Write, and add a comment explaining this. Modified: llvm/trunk/lib/Analysis/Lint.cpp llvm/trunk/test/Other/lint.ll Modified: llvm/trunk/lib/Analysis/Lint.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/Lint.cpp?rev=104756&r1=104755&r2=104756&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/Lint.cpp (original) +++ llvm/trunk/lib/Analysis/Lint.cpp Wed May 26 17:21:25 2010 @@ -285,6 +285,14 @@ visitMemoryReference(I, CS.getArgument(0), 0, 0, MemRef::Read | MemRef::Write); break; + + case Intrinsic::stackrestore: + // Stackrestore doesn't read or write memory, but it sets the + // stack pointer, which the compiler may read from or write to + // at any time, so check it for both readability and writeability. + visitMemoryReference(I, CS.getArgument(0), 0, 0, + MemRef::Read | MemRef::Write); + break; } } Modified: llvm/trunk/test/Other/lint.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/lint.ll?rev=104756&r1=104755&r2=104756&view=diff ============================================================================== --- llvm/trunk/test/Other/lint.ll (original) +++ llvm/trunk/test/Other/lint.ll Wed May 26 17:21:25 2010 @@ -2,6 +2,7 @@ target datalayout = "e-p:64:64:64" declare fastcc void @bar() +declare void @llvm.stackrestore(i8*) @CG = constant i32 7 @@ -50,6 +51,8 @@ %lb = load i32* bitcast (i8* blockaddress(@foo, %next) to i32*) ; CHECK: Call to block address call void()* bitcast (i8* blockaddress(@foo, %next) to void()*)() +; CHECK: Undefined behavior: Null pointer dereference + call void @llvm.stackrestore(i8* null) br label %next From daniel at zuster.org Wed May 26 17:21:28 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 26 May 2010 22:21:28 -0000 Subject: [llvm-commits] [llvm] r104757 - in /llvm/trunk/lib/Target/X86: X86Instr64bit.td X86InstrInfo.td Message-ID: <20100526222128.578243128018@llvm.org> Author: ddunbar Date: Wed May 26 17:21:28 2010 New Revision: 104757 URL: http://llvm.org/viewvc/llvm-project?rev=104757&view=rev Log: AsmMatcher/X86: Mark _REV instructions as "code gen only", they aren't expected to be matched. Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td llvm/trunk/lib/Target/X86/X86InstrInfo.td Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Instr64bit.td?rev=104757&r1=104756&r2=104757&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Instr64bit.td (original) +++ llvm/trunk/lib/Target/X86/X86Instr64bit.td Wed May 26 17:21:28 2010 @@ -361,8 +361,10 @@ "mov{q}\t{$src, $dst|$dst, $src}", []>; } +let isCodeGenOnly = 1 in { def MOV64rr_REV : RI<0x8B, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src), "mov{q}\t{$src, $dst|$dst, $src}", []>; +} let canFoldAsLoad = 1, isReMaterializable = 1 in def MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src), @@ -585,9 +587,11 @@ "adc{q}\t{$src2, $dst|$dst, $src2}", [(set GR64:$dst, (adde GR64:$src1, GR64:$src2))]>; +let isCodeGenOnly = 1 in { def ADC64rr_REV : RI<0x13, MRMSrcReg , (outs GR32:$dst), (ins GR64:$src1, GR64:$src2), "adc{q}\t{$src2, $dst|$dst, $src2}", []>; +} def ADC64rm : RI<0x13, MRMSrcMem , (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), @@ -625,9 +629,11 @@ [(set GR64:$dst, EFLAGS, (X86sub_flag GR64:$src1, GR64:$src2))]>; +let isCodeGenOnly = 1 in { def SUB64rr_REV : RI<0x2B, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), "sub{q}\t{$src2, $dst|$dst, $src2}", []>; +} // Register-Memory Subtraction def SUB64rm : RI<0x2B, MRMSrcMem, (outs GR64:$dst), @@ -677,9 +683,11 @@ "sbb{q}\t{$src2, $dst|$dst, $src2}", [(set GR64:$dst, (sube GR64:$src1, GR64:$src2))]>; +let isCodeGenOnly = 1 in { def SBB64rr_REV : RI<0x1B, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), "sbb{q}\t{$src2, $dst|$dst, $src2}", []>; +} def SBB64rm : RI<0x1B, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), @@ -1106,9 +1114,11 @@ "and{q}\t{$src2, $dst|$dst, $src2}", [(set GR64:$dst, EFLAGS, (X86and_flag GR64:$src1, GR64:$src2))]>; +let isCodeGenOnly = 1 in { def AND64rr_REV : RI<0x23, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), "and{q}\t{$src2, $dst|$dst, $src2}", []>; +} def AND64rm : RI<0x23, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), "and{q}\t{$src2, $dst|$dst, $src2}", @@ -1149,9 +1159,11 @@ "or{q}\t{$src2, $dst|$dst, $src2}", [(set GR64:$dst, EFLAGS, (X86or_flag GR64:$src1, GR64:$src2))]>; +let isCodeGenOnly = 1 in { def OR64rr_REV : RI<0x0B, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), "or{q}\t{$src2, $dst|$dst, $src2}", []>; +} def OR64rm : RI<0x0B, MRMSrcMem , (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), "or{q}\t{$src2, $dst|$dst, $src2}", @@ -1192,9 +1204,11 @@ "xor{q}\t{$src2, $dst|$dst, $src2}", [(set GR64:$dst, EFLAGS, (X86xor_flag GR64:$src1, GR64:$src2))]>; +let isCodeGenOnly = 1 in { def XOR64rr_REV : RI<0x33, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), "xor{q}\t{$src2, $dst|$dst, $src2}", []>; +} def XOR64rm : RI<0x33, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), "xor{q}\t{$src2, $dst|$dst, $src2}", Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=104757&r1=104756&r2=104757&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Wed May 26 17:21:28 2010 @@ -1044,12 +1044,14 @@ def MOV32sm : I<0x8E, MRMSrcMem, (outs SEGMENT_REG:$dst), (ins i32mem:$src), "mov{l}\t{$src, $dst|$dst, $src}", []>; +let isCodeGenOnly = 1 in { def MOV8rr_REV : I<0x8A, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src), "mov{b}\t{$src, $dst|$dst, $src}", []>; def MOV16rr_REV : I<0x8B, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src), "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize; def MOV32rr_REV : I<0x8B, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src), "mov{l}\t{$src, $dst|$dst, $src}", []>; +} let canFoldAsLoad = 1, isReMaterializable = 1 in { def MOV8rm : I<0x8A, MRMSrcMem, (outs GR8 :$dst), (ins i8mem :$src), @@ -1800,6 +1802,7 @@ // AND instructions with the destination register in REG and the source register // in R/M. Included for the disassembler. +let isCodeGenOnly = 1 in { def AND8rr_REV : I<0x22, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src1, GR8:$src2), "and{b}\t{$src2, $dst|$dst, $src2}", []>; def AND16rr_REV : I<0x23, MRMSrcReg, (outs GR16:$dst), @@ -1808,6 +1811,7 @@ def AND32rr_REV : I<0x23, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), "and{l}\t{$src2, $dst|$dst, $src2}", []>; +} def AND8rm : I<0x22, MRMSrcMem, (outs GR8 :$dst), (ins GR8 :$src1, i8mem :$src2), @@ -1926,6 +1930,7 @@ // OR instructions with the destination register in REG and the source register // in R/M. Included for the disassembler. +let isCodeGenOnly = 1 in { def OR8rr_REV : I<0x0A, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src1, GR8:$src2), "or{b}\t{$src2, $dst|$dst, $src2}", []>; def OR16rr_REV : I<0x0B, MRMSrcReg, (outs GR16:$dst), @@ -1934,6 +1939,7 @@ def OR32rr_REV : I<0x0B, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), "or{l}\t{$src2, $dst|$dst, $src2}", []>; +} def OR8rm : I<0x0A, MRMSrcMem, (outs GR8 :$dst), (ins GR8 :$src1, i8mem :$src2), @@ -2042,6 +2048,7 @@ // XOR instructions with the destination register in REG and the source register // in R/M. Included for the disassembler. +let isCodeGenOnly = 1 in { def XOR8rr_REV : I<0x32, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src1, GR8:$src2), "xor{b}\t{$src2, $dst|$dst, $src2}", []>; def XOR16rr_REV : I<0x33, MRMSrcReg, (outs GR16:$dst), @@ -2050,6 +2057,7 @@ def XOR32rr_REV : I<0x33, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), "xor{l}\t{$src2, $dst|$dst, $src2}", []>; +} def XOR8rm : I<0x32, MRMSrcMem, (outs GR8 :$dst), (ins GR8:$src1, i8mem :$src2), @@ -2847,6 +2855,7 @@ [(set GR32:$dst, (adde GR32:$src1, GR32:$src2))]>; } +let isCodeGenOnly = 1 in { def ADC8rr_REV : I<0x12, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src1, GR8:$src2), "adc{b}\t{$src2, $dst|$dst, $src2}", []>; def ADC16rr_REV : I<0x13, MRMSrcReg, (outs GR16:$dst), @@ -2855,6 +2864,7 @@ def ADC32rr_REV : I<0x13, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), "adc{l}\t{$src2, $dst|$dst, $src2}", []>; +} def ADC8rm : I<0x12, MRMSrcMem , (outs GR8:$dst), (ins GR8:$src1, i8mem:$src2), @@ -2942,6 +2952,7 @@ [(set GR32:$dst, EFLAGS, (X86sub_flag GR32:$src1, GR32:$src2))]>; +let isCodeGenOnly = 1 in { def SUB8rr_REV : I<0x2A, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src1, GR8:$src2), "sub{b}\t{$src2, $dst|$dst, $src2}", []>; def SUB16rr_REV : I<0x2B, MRMSrcReg, (outs GR16:$dst), @@ -2950,6 +2961,7 @@ def SUB32rr_REV : I<0x2B, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), "sub{l}\t{$src2, $dst|$dst, $src2}", []>; +} // Register-Memory Subtraction def SUB8rm : I<0x2A, MRMSrcMem, (outs GR8 :$dst), @@ -3093,6 +3105,7 @@ "sbb{l}\t{$src, %eax|%eax, $src}", []>; } +let isCodeGenOnly = 1 in { def SBB8rr_REV : I<0x1A, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src1, GR8:$src2), "sbb{b}\t{$src2, $dst|$dst, $src2}", []>; def SBB16rr_REV : I<0x1B, MRMSrcReg, (outs GR16:$dst), @@ -3101,6 +3114,7 @@ def SBB32rr_REV : I<0x1B, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), "sbb{l}\t{$src2, $dst|$dst, $src2}", []>; +} def SBB8rm : I<0x1A, MRMSrcMem, (outs GR8:$dst), (ins GR8:$src1, i8mem:$src2), "sbb{b}\t{$src2, $dst|$dst, $src2}", From gohman at apple.com Wed May 26 17:28:53 2010 From: gohman at apple.com (Dan Gohman) Date: Wed, 26 May 2010 22:28:53 -0000 Subject: [llvm-commits] [llvm] r104765 - in /llvm/trunk: include/llvm/Analysis/Lint.h lib/Analysis/Lint.cpp Message-ID: <20100526222853.B69833128026@llvm.org> Author: djg Date: Wed May 26 17:28:53 2010 New Revision: 104765 URL: http://llvm.org/viewvc/llvm-project?rev=104765&view=rev Log: Fix Lint printing warnings multiple times. Remove the ErrorStr option from lintModule, which was an artifact from being based on Verifier code. Modified: llvm/trunk/include/llvm/Analysis/Lint.h llvm/trunk/lib/Analysis/Lint.cpp Modified: llvm/trunk/include/llvm/Analysis/Lint.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/Lint.h?rev=104765&r1=104764&r2=104765&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/Lint.h (original) +++ llvm/trunk/include/llvm/Analysis/Lint.h Wed May 26 17:28:53 2010 @@ -38,8 +38,7 @@ /// This should only be used for debugging, because it plays games with /// PassManagers and stuff. void lintModule( - const Module &M, ///< The module to be checked - std::string *ErrorInfo = 0 ///< Information about failures. + const Module &M ///< The module to be checked ); // lintFunction - Check a function. Modified: llvm/trunk/lib/Analysis/Lint.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/Lint.cpp?rev=104765&r1=104764&r2=104765&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/Lint.cpp (original) +++ llvm/trunk/lib/Analysis/Lint.cpp Wed May 26 17:28:53 2010 @@ -179,6 +179,7 @@ TD = getAnalysisIfAvailable(); visit(F); dbgs() << MessagesStr.str(); + Messages.clear(); return false; } @@ -492,14 +493,10 @@ } /// lintModule - Check a module for errors, printing messages on stderr. -/// Return true if the module is corrupt. /// -void llvm::lintModule(const Module &M, std::string *ErrorInfo) { +void llvm::lintModule(const Module &M) { PassManager PM; Lint *V = new Lint(); PM.add(V); PM.run(const_cast(M)); - - if (ErrorInfo) - *ErrorInfo = V->MessagesStr.str(); } From stoklund at 2pi.dk Wed May 26 17:40:28 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 26 May 2010 22:40:28 -0000 Subject: [llvm-commits] [llvm] r104780 - /llvm/trunk/lib/Analysis/InlineCost.cpp Message-ID: <20100526224028.34892312800A@llvm.org> Author: stoklund Date: Wed May 26 17:40:28 2010 New Revision: 104780 URL: http://llvm.org/viewvc/llvm-project?rev=104780&view=rev Log: Avoid counting InlineAsm as a call - it prevents loop unrolling. PR7026 Patch by Pekka J??skel?inen! Modified: llvm/trunk/lib/Analysis/InlineCost.cpp Modified: llvm/trunk/lib/Analysis/InlineCost.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InlineCost.cpp?rev=104780&r1=104779&r2=104780&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/InlineCost.cpp (original) +++ llvm/trunk/lib/Analysis/InlineCost.cpp Wed May 26 17:40:28 2010 @@ -175,7 +175,11 @@ if (!isa(II) && !callIsSmall(CS.getCalledFunction())) { // Each argument to a call takes on average one instruction to set up. NumInsts += CS.arg_size(); - ++NumCalls; + + // We don't want inline asm to count as a call - that would prevent loop + // unrolling. The argument setup cost is still real, though. + if (!isa(CS.getCalledValue())) + ++NumCalls; } } From dpatel at apple.com Wed May 26 18:55:23 2010 From: dpatel at apple.com (Devang Patel) Date: Wed, 26 May 2010 23:55:23 -0000 Subject: [llvm-commits] [llvm] r104785 - in /llvm/trunk: lib/CodeGen/AsmPrinter/DwarfDebug.cpp test/CodeGen/X86/2010-05-26-DotDebugLoc.ll test/DebugInfo/2010-05-25-DotDebugLoc.ll Message-ID: <20100526235523.C15A9312800A@llvm.org> Author: dpatel Date: Wed May 26 18:55:23 2010 New Revision: 104785 URL: http://llvm.org/viewvc/llvm-project?rev=104785&view=rev Log: Simplify. Eliminate unneeded debug_loc entry. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp llvm/trunk/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll llvm/trunk/test/DebugInfo/2010-05-25-DotDebugLoc.ll Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=104785&r1=104784&r2=104785&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Wed May 26 18:55:23 2010 @@ -2210,9 +2210,10 @@ } // handle multiple DBG_VALUE instructions describing one variable. - RegVar->setDotDebugLocOffset(DotDebugLocEntries.size()); if (DotDebugLocEntries.empty()) - DotDebugLocEntries.push_back(DotDebugLocEntry()); + RegVar->setDotDebugLocOffset(0); + else + RegVar->setDotDebugLocOffset(DotDebugLocEntries.size()); const MachineInstr *Begin = NULL; const MachineInstr *End = NULL; for (SmallVector::iterator @@ -3481,23 +3482,22 @@ /// emitDebugLoc - Emit visible names into a debug loc section. /// void DwarfDebug::emitDebugLoc() { + if (DotDebugLocEntries.empty()) + return; + // Start the dwarf loc section. Asm->OutStreamer.SwitchSection( Asm->getObjFileLowering().getDwarfLocSection()); unsigned char Size = Asm->getTargetData().getPointerSize(); - unsigned index = 0; - bool needMarker = true; + Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_loc", 0)); + unsigned index = 1; for (SmallVector::iterator I = DotDebugLocEntries.begin(), E = DotDebugLocEntries.end(); I != E; ++I, ++index) { DotDebugLocEntry Entry = *I; - if (needMarker) { - Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_loc", index)); - needMarker = false; - } if (Entry.isEmpty()) { Asm->OutStreamer.EmitIntValue(0, Size, /*addrspace*/0); Asm->OutStreamer.EmitIntValue(0, Size, /*addrspace*/0); - needMarker = true; + Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_loc", index)); } else { Asm->OutStreamer.EmitSymbolValue(Entry.Begin, Size, 0); Asm->OutStreamer.EmitSymbolValue(Entry.End, Size, 0); Modified: llvm/trunk/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll?rev=104785&r1=104784&r2=104785&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll (original) +++ llvm/trunk/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll Wed May 26 18:55:23 2010 @@ -55,7 +55,7 @@ !29 = metadata !{i32 524299, metadata !9, i32 17, i32 0} ; [ DW_TAG_lexical_block ] !30 = metadata !{i32 19, i32 0, metadata !29, null} -; CHECK: Ldebug_loc1 +; CHECK: Ldebug_loc0: ; CHECK-NEXT: .quad Lfunc_begin0 ; CHECK-NEXT: .quad Ltmp3 ; CHECK-NEXT: .short 1 Modified: llvm/trunk/test/DebugInfo/2010-05-25-DotDebugLoc.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/2010-05-25-DotDebugLoc.ll?rev=104785&r1=104784&r2=104785&view=diff ============================================================================== --- llvm/trunk/test/DebugInfo/2010-05-25-DotDebugLoc.ll (original) +++ llvm/trunk/test/DebugInfo/2010-05-25-DotDebugLoc.ll Wed May 26 18:55:23 2010 @@ -1,5 +1,5 @@ -; RUN: llc -O2 < %s | grep debug_loc13 -; Test to check .debug_loc support. This test case emits 14 debug_loc entries. +; RUN: llc -O2 < %s | grep debug_loc12 +; Test to check .debug_loc support. This test case emits 13 debug_loc entries. %0 = type { double } From echristo at apple.com Wed May 26 19:52:31 2010 From: echristo at apple.com (Eric Christopher) Date: Thu, 27 May 2010 00:52:31 -0000 Subject: [llvm-commits] [llvm] r104793 - /llvm/trunk/lib/MC/MachObjectWriter.cpp Message-ID: <20100527005231.97288312800A@llvm.org> Author: echristo Date: Wed May 26 19:52:31 2010 New Revision: 104793 URL: http://llvm.org/viewvc/llvm-project?rev=104793&view=rev Log: Rearrange conditionals so we don't get caught with the correct type as wrong. Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=104793&r1=104792&r2=104793&view=diff ============================================================================== --- llvm/trunk/lib/MC/MachObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/MachObjectWriter.cpp Wed May 26 19:52:31 2010 @@ -612,10 +612,10 @@ Type = RIT_X86_64_GOTLoad; else Type = RIT_X86_64_GOT; - } else if (Modifier != MCSymbolRefExpr::VK_None) { - report_fatal_error("unsupported symbol modifier in relocation"); - } else if (Modifier == MCSymbolRefExpr::VK_TLVP) { + } else if (Modifier == MCSymbolRefExpr::VK_TLVP) { Type = RIT_X86_64_TLV; + } else if (Modifier != MCSymbolRefExpr::VK_None) { + report_fatal_error("unsupported symbol modifier in relocation"); } else { Type = RIT_X86_64_Signed; From echristo at apple.com Wed May 26 19:53:40 2010 From: echristo at apple.com (Eric Christopher) Date: Thu, 27 May 2010 00:53:40 -0000 Subject: [llvm-commits] [llvm] r104794 - /llvm/trunk/test/MC/MachO/tlv-reloc.s Message-ID: <20100527005340.33904312800A@llvm.org> Author: echristo Date: Wed May 26 19:53:40 2010 New Revision: 104794 URL: http://llvm.org/viewvc/llvm-project?rev=104794&view=rev Log: Add a quick test of relocations. Added: llvm/trunk/test/MC/MachO/tlv-reloc.s Added: llvm/trunk/test/MC/MachO/tlv-reloc.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MachO/tlv-reloc.s?rev=104794&view=auto ============================================================================== --- llvm/trunk/test/MC/MachO/tlv-reloc.s (added) +++ llvm/trunk/test/MC/MachO/tlv-reloc.s Wed May 26 19:53:40 2010 @@ -0,0 +1,174 @@ +// RUN: llvm-mc -triple x86_64-apple-darwin %s -filetype=obj -o - | macho-dump --dump-section-data | FileCheck %s + +.tdata +_a$tlv$init: + .long 4 + + +.tlv + .globl _a +_a: + .quad __tlv_bootstrap + .quad 0 + .quad _a$tlv$init + +.text + .globl _foo + .align 4, 0x90 + +_foo: + movq _a at TLVP(%rip), %rdi + call *(%rdi) # returns &a in %rax + ret + +// CHECK: ('cputype', 16777223) +// CHECK: ('cpusubtype', 3) +// CHECK: ('filetype', 1) +// CHECK: ('num_load_commands', 1) +// CHECK: ('load_commands_size', 416) +// CHECK: ('flag', 0) +// CHECK: ('reserved', 0) +// CHECK: ('load_commands', [ +// CHECK: # Load Command 0 +// CHECK: (('command', 25) +// CHECK: ('size', 312) +// CHECK: ('segment_name', '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +// CHECK: ('vm_addr', 0) +// CHECK: ('vm_size', 38) +// CHECK: ('file_offset', 448) +// CHECK: ('file_size', 38) +// CHECK: ('maxprot', 7) +// CHECK: ('initprot', 7) +// CHECK: ('num_sections', 3) +// CHECK: ('flags', 0) +// CHECK: ('sections', [ +// CHECK: # Section 0 +// CHECK: (('section_name', '__text\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +// CHECK: ('segment_name', '__TEXT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +// CHECK: ('address', 0) +// CHECK: ('size', 10) +// CHECK: ('offset', 448) +// CHECK: ('alignment', 4) +// CHECK: ('reloc_offset', 488) +// CHECK: ('num_reloc', 1) +// CHECK: ('flags', 0x80000400) +// CHECK: ('reserved1', 0) +// CHECK: ('reserved2', 0) +// CHECK: ('reserved3', 0) +// CHECK: ), +// CHECK: ('_relocations', [ +// CHECK: # Relocation 0 +// CHECK: (('word-0', 0x3), +// CHECK: ('word-1', 0x9d000001)), +// CHECK: ]) +// CHECK: ('_section_data', 'H\x8b=\x00\x00\x00\x00\xff\x17\xc3') +// CHECK: # Section 1 +// CHECK: (('section_name', '__thread_data\x00\x00\x00') +// CHECK: ('segment_name', '__DATA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +// CHECK: ('address', 10) +// CHECK: ('size', 4) +// CHECK: ('offset', 458) +// CHECK: ('alignment', 0) +// CHECK: ('reloc_offset', 0) +// CHECK: ('num_reloc', 0) +// CHECK: ('flags', 0x11) +// CHECK: ('reserved1', 0) +// CHECK: ('reserved2', 0) +// CHECK: ('reserved3', 0) +// CHECK: ), +// CHECK: ('_relocations', [ +// CHECK: ]) +// CHECK: ('_section_data', '\x04\x00\x00\x00') +// CHECK: # Section 2 +// CHECK: (('section_name', '__thread_vars\x00\x00\x00') +// CHECK: ('segment_name', '__DATA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +// CHECK: ('address', 14) +// CHECK: ('size', 24) +// CHECK: ('offset', 462) +// CHECK: ('alignment', 0) +// CHECK: ('reloc_offset', 496) +// CHECK: ('num_reloc', 2) +// CHECK: ('flags', 0x13) +// CHECK: ('reserved1', 0) +// CHECK: ('reserved2', 0) +// CHECK: ('reserved3', 0) +// CHECK: ), +// CHECK: ('_relocations', [ +// CHECK: # Relocation 0 +// CHECK: (('word-0', 0x10), +// CHECK: ('word-1', 0xe000000)), +// CHECK: # Relocation 1 +// CHECK: (('word-0', 0x0), +// CHECK: ('word-1', 0xe000003)), +// CHECK: ]) +// CHECK: ('_section_data', '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +// CHECK: ]) +// CHECK: ), +// CHECK: # Load Command 1 +// CHECK: (('command', 2) +// CHECK: ('size', 24) +// CHECK: ('symoff', 512) +// CHECK: ('nsyms', 4) +// CHECK: ('stroff', 576) +// CHECK: ('strsize', 40) +// CHECK: ('_string_data', '\x00_a\x00__tlv_bootstrap\x00_foo\x00_a$tlv$init\x00\x00\x00\x00') +// CHECK: ('_symbols', [ +// CHECK: # Symbol 0 +// CHECK: (('n_strx', 25) +// CHECK: ('n_type', 0xe) +// CHECK: ('n_sect', 2) +// CHECK: ('n_desc', 0) +// CHECK: ('n_value', 10) +// CHECK: ('_string', '_a$tlv$init') +// CHECK: ), +// CHECK: # Symbol 1 +// CHECK: (('n_strx', 1) +// CHECK: ('n_type', 0xf) +// CHECK: ('n_sect', 3) +// CHECK: ('n_desc', 0) +// CHECK: ('n_value', 14) +// CHECK: ('_string', '_a') +// CHECK: ), +// CHECK: # Symbol 2 +// CHECK: (('n_strx', 20) +// CHECK: ('n_type', 0xf) +// CHECK: ('n_sect', 1) +// CHECK: ('n_desc', 0) +// CHECK: ('n_value', 0) +// CHECK: ('_string', '_foo') +// CHECK: ), +// CHECK: # Symbol 3 +// CHECK: (('n_strx', 4) +// CHECK: ('n_type', 0x1) +// CHECK: ('n_sect', 0) +// CHECK: ('n_desc', 0) +// CHECK: ('n_value', 0) +// CHECK: ('_string', '__tlv_bootstrap') +// CHECK: ), +// CHECK: ]) +// CHECK: ), +// CHECK: # Load Command 2 +// CHECK: (('command', 11) +// CHECK: ('size', 80) +// CHECK: ('ilocalsym', 0) +// CHECK: ('nlocalsym', 1) +// CHECK: ('iextdefsym', 1) +// CHECK: ('nextdefsym', 2) +// CHECK: ('iundefsym', 3) +// CHECK: ('nundefsym', 1) +// CHECK: ('tocoff', 0) +// CHECK: ('ntoc', 0) +// CHECK: ('modtaboff', 0) +// CHECK: ('nmodtab', 0) +// CHECK: ('extrefsymoff', 0) +// CHECK: ('nextrefsyms', 0) +// CHECK: ('indirectsymoff', 0) +// CHECK: ('nindirectsyms', 0) +// CHECK: ('extreloff', 0) +// CHECK: ('nextrel', 0) +// CHECK: ('locreloff', 0) +// CHECK: ('nlocrel', 0) +// CHECK: ('_indirect_symbols', [ +// CHECK: ]) +// CHECK: ), +// CHECK: ]) From sliao at google.com Wed May 26 20:19:47 2010 From: sliao at google.com (Shih-wei Liao) Date: Wed, 26 May 2010 18:19:47 -0700 Subject: [llvm-commits] [llvm] r104653 - /llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp In-Reply-To: References: <20100526002505.7DBA93128034@llvm.org> <7C8551B3-8E39-484E-A2DB-C830636F141B@apple.com> Message-ID: I hope to address the valid concern. I spent time today in retrying. Unfortunately I think it's hard to find a way to generalize these instructions. BFC and BFI are really "special" ones. So I think they deserve these 5 lines of encoding in the patch. Compared with 1600 lines in ARMCodeEmitter.cpp, maybe these lines are not adding too much. My apologies for not being able to cut down to 0. On Wed, May 26, 2010 at 2:15 AM, Shih-wei Liao wrote: > I agree that it's probably too easy to add one more to the many cases in > ARMCodeEmitter.cpp. My bad. If changing ARM*.td can fix the bugs completely, > that will be the best. Anyone knows of a better patch that's doable now? > That will be great. I tried and stopped after the irregularities like > widthm1 encoding and so on. > > Probably we should overhaul the ARM*.td some time soon. Currently these 2 > if-conditions can make the ARM JIT usable first, and I agree that I should > strive for a better solution. Stay tuned. > > On Tue, May 25, 2010 at 10:07 PM, Evan Cheng wrote: > > > > Sorry I have been behind on patch reviews. I have some concerns about > these patches. We want to prevent special casing for individual > instructions. Is it not possible to add generic support for these? > > > > Evan > > > > On May 25, 2010, at 5:25 PM, Shih-wei Liao wrote: > > > > > Author: sliao > > > Date: Tue May 25 19:25:05 2010 > > > New Revision: 104653 > > > > > > URL: http://llvm.org/viewvc/llvm-project?rev=104653&view=rev > > > Log: > > > Adding the missing implementation of Bitfield's "clear" and "insert". > > > Fixing http://llvm.org/bugs/show_bug.cgi?id=7222. > > > > > > Modified: > > > llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp > > > > > > Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp > > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=104653&r1=104652&r2=104653&view=diff > > > > ============================================================================== > > > --- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original) > > > +++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Tue May 25 19:25:05 > 2010 > > > @@ -781,10 +781,6 @@ > > > unsigned ImplicitRn) > { > > > const TargetInstrDesc &TID = MI.getDesc(); > > > > > > - if (TID.Opcode == ARM::BFC) { > > > - report_fatal_error("ARMv6t2 JIT is not yet supported."); > > > - } > > > - > > > // Part of binary is determined by TableGn. > > > unsigned Binary = getBinaryCodeForInstr(MI); > > > > > > @@ -820,6 +816,15 @@ > > > Binary |= ((Hi16 >> 12) & 0xF) << 16; > > > emitWordLE(Binary); > > > return; > > > + } else if((TID.Opcode == ARM::BFC) || (TID.Opcode == ARM::BFI)) { > > > + uint32_t v = ~MI.getOperand(2).getImm(); > > > + int32_t lsb = CountTrailingZeros_32(v); > > > + int32_t msb = (32 - CountLeadingZeros_32(v)) - 1; > > > + // Insts[20-16] = msb, Insts[11-7] = lsb > > > + Binary |= (msb & 0x1F) << 16; > > > + Binary |= (lsb & 0x1F) << 7; > > > + emitWordLE(Binary); > > > + return; > > > } > > > > > > // If this is a two-address operand, skip it. e.g. MOVCCr operand 1. > > > > > > > > > _______________________________________________ > > > llvm-commits mailing list > > > llvm-commits at cs.uiuc.edu > > > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > > > -- > Thanks, > Shih-wei > -- Thanks, Shih-wei -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100526/ee136429/attachment.html From nlewycky at google.com Wed May 26 22:41:11 2010 From: nlewycky at google.com (Nick Lewycky) Date: Wed, 26 May 2010 20:41:11 -0700 Subject: [llvm-commits] [PATCH] [ARM JIT] To fix "llvm_unreachable("Unable to handle this constantpool entry!")" In-Reply-To: References: Message-ID: Hi Shih-wei, I have a few comments: +void ARMCodeEmitter::emitConstantToMemory(unsigned CPI, const Constant* C) { The rest of the code uses "const Constant *C". Please place the space before the star. In X86CodeEmitter, the + } else if (const ConstantVector *CV = dyn_cast(C)) { + for (unsigned i=0;igetNumOperands();i++) + emitConstantToMemory(CPI, CV->getOperand(i)); + } else if (const ConstantArray *CA = dyn_cast(C)) { + for (unsigned i=0;igetNumOperands();i++) + emitConstantToMemory(CPI, CA->getOperand(i)); + } else { + llvm_unreachable("Unable to handle this constantpool entry!"); + } A few things. Firstly, please use proper whitespace, make your code look like the code around you. This means "for (unsigned i = 0; i < CA->getNumOperands(); i++)". Secondly, always hoist out the end computation of a loop, which would make it "for (unsigned i = 0, e = CV->getNumOperands(); i != e; i++)". Now, you've added a lot of cases and I'm wondering whether it's time to switch away from the else-if nesting. As it is, the dyn_cast<> macros have to be tried in the order they're written in the code. Using a switch only evaluates the concrete type once, and makes the code: switch (C->getValueID()) { case GlobalVariableVal: // fall-through case GlobalAliasVal: // fall-through case FunctionVal: { GlobalValue *GV = cast(C); emitGlobalAddress ... break; } case ConstantIntVal: { ConstantInt *CI = cast(C); ... break; } ... } I also noticed that you've added potentially unbounded recursion (well, it's bounded by the depth of nesting of array types), but that doesn't look easy to fix, and it's probably not going to be a problem anyways (ie., we'd run out of ArrayType objects first). Now finally, with all that said, I'm still not sure about this patch. Is the layout of a vector in memory the same as an array in memory? You're treating them the same with no padding or alignment issues considered, just stamping the elements into memory. Someone else should look at that before this patch lands. Nick On 26 May 2010 02:27, Shih-wei Liao wrote: > See http://llvm.org/bugs/show_bug.cgi?id=7226: ARM JIT couldn't emit > constant pool entry for "ConstantVector" and "ConstantArray". > > The patch passes both "make check" and "make check-lit". Basically, > the patch added the processing of ConstantVector and ConstantArray. > The problem is gone after the patch. > -- > Thanks, > Shih-wei > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100526/534fd8b1/attachment.html From nlewycky at google.com Wed May 26 22:55:37 2010 From: nlewycky at google.com (Nick Lewycky) Date: Wed, 26 May 2010 20:55:37 -0700 Subject: [llvm-commits] [PATCH] [ARM JIT] Pseudo Instruction ARM::LEApcrel defined but not implemented In-Reply-To: References: Message-ID: + // For VFP load, the immediate offset is multiplied by 4. + unsigned Reloc = ((TID.TSFlags & ARMII::FormMask) == ARMII::VFPLdStFrm) + ? ARM::reloc_arm_vfp_cp_entry : ARM::reloc_arm_cp_entry; There's two spaces after the first = sign. Please remove one. I'm a little worried that this is cut-and-pasted from getMachineOpValue(). Feel free to fix the extra space there too, by the way. Is there a sensible way to factor this logic out? + // Materialize contant pool index address. Typo: "contant". This is similar enough in implementation to emitLEApcrelInstruction that I think it's fine to go ahead and commit it as is, then make any changes Evan or others ask for afterwards. Nick On 26 May 2010 03:19, Shih-wei Liao wrote: > See http://llvm.org/bugs/show_bug.cgi?id=7227: ARM JIT misses the > implementation of ARM::LEApcrel. > > The patch passes both "make check-lit" and "make check". > > For "make check-lit", > Expected Passes : 4101 > Expected Failures : 24 > Unsupported Tests : 1184 > make[1]: Leaving directory `/usr/local/google/upstream/llvm-obj/test' > > For "make check", > === Summary === > > # of expected passes 3842 > # of expected failures 24 > make[1]: Leaving directory `/usr/local/google/upstream/llvm-obj/test' > > Basically, the patch added the case "ARM::LEApcrel" next to the "case > ARM::LEApcrelJT". The latter was implemented, but not the former. With > the added implementation, all our input programs result in correct > execution under LLVM's ARM JIT. > -- > Thanks, > Shih-wei > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100526/667dbf05/attachment.html From wdietz2 at illinois.edu Wed May 26 17:33:10 2010 From: wdietz2 at illinois.edu (Will Dietz) Date: Wed, 26 May 2010 22:33:10 -0000 Subject: [llvm-commits] [poolalloc] r104777 - /poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp Message-ID: <20100526223310.B0DDD312800A@llvm.org> Author: wdietz2 Date: Wed May 26 17:33:10 2010 New Revision: 104777 URL: http://llvm.org/viewvc/llvm-project?rev=104777&view=rev Log: poolalloc: add parens to conditional to fix warning Modified: poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp Modified: poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp?rev=104777&r1=104776&r2=104777&view=diff ============================================================================== --- poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp (original) +++ poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp Wed May 26 17:33:10 2010 @@ -746,7 +746,7 @@ // We only need to make a pool if there is a heap object in it... DSNode *N = I; if ((N->isHeapNode()) || (BoundsChecksEnabled && (N->isArrayNode())) || - GlobalsGraphNodeMapping.count(N) && GlobalsGraphNodeMapping[N].getNode()->isHeapNode()) { + (GlobalsGraphNodeMapping.count(N) && GlobalsGraphNodeMapping[N].getNode()->isHeapNode())) { if (GlobalsGraphNodeMapping.count(N)) { // If it is a global pool, set up the pool descriptor appropriately. DSNode *GGN = GlobalsGraphNodeMapping[N].getNode(); From wdietz2 at illinois.edu Wed May 26 17:35:47 2010 From: wdietz2 at illinois.edu (Will Dietz) Date: Wed, 26 May 2010 22:35:47 -0000 Subject: [llvm-commits] [poolalloc] r104779 - /poolalloc/trunk/lib/DSA/DataStructureAA.cpp Message-ID: <20100526223547.B4515312800A@llvm.org> Author: wdietz2 Date: Wed May 26 17:35:47 2010 New Revision: 104779 URL: http://llvm.org/viewvc/llvm-project?rev=104779&view=rev Log: ds-aa: impl 'getAdjustedAnalysisPointer' to fix crash due to multiple inheritance issue Modified: poolalloc/trunk/lib/DSA/DataStructureAA.cpp Modified: poolalloc/trunk/lib/DSA/DataStructureAA.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DataStructureAA.cpp?rev=104779&r1=104778&r2=104779&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/DataStructureAA.cpp (original) +++ poolalloc/trunk/lib/DSA/DataStructureAA.cpp Wed May 26 17:35:47 2010 @@ -68,6 +68,16 @@ AU.addRequiredTransitive(); // Uses BU Datastructures } + /// getAdjustedAnalysisPointer - This method is used when a pass implements + /// an analysis interface through multiple inheritance. If needed, it + /// should override this to adjust the this pointer as needed for the + /// specified pass info. + virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) { + if (PI->isPassID(&AliasAnalysis::ID)) + return (AliasAnalysis*)this; + return this; + } + //------------------------------------------------ // Implement the AliasAnalysis API // From bob.wilson at apple.com Thu May 27 00:29:41 2010 From: bob.wilson at apple.com (Bob Wilson) Date: Thu, 27 May 2010 05:29:41 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r104804 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <20100527052941.F18D5312800A@llvm.org> Author: bwilson Date: Thu May 27 00:29:41 2010 New Revision: 104804 URL: http://llvm.org/viewvc/llvm-project?rev=104804&view=rev Log: Avoid introducing an extra '=' in the constraint for an output register. Fix a comment typo, too. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=104804&r1=104803&r2=104804&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Thu May 27 00:29:41 2010 @@ -4730,12 +4730,11 @@ if (RegNum >= 0) { RegName = LLVM_GET_REG_NAME(RegName, RegNum); unsigned RegNameLen = strlen(RegName); - char *NewConstraint = (char*)alloca(RegNameLen+4); - NewConstraint[0] = '='; - NewConstraint[1] = '{'; - memcpy(NewConstraint+2, RegName, RegNameLen); - NewConstraint[RegNameLen+2] = '}'; - NewConstraint[RegNameLen+3] = 0; + char *NewConstraint = (char*)alloca(RegNameLen+3); + NewConstraint[0] = '{'; + memcpy(NewConstraint+1, RegName, RegNameLen); + NewConstraint[RegNameLen+1] = '}'; + NewConstraint[RegNameLen+2] = 0; SimplifiedConstraint = NewConstraint; // This output will now be implicit; set the sideffect flag on the asm. HasSideEffects = true; @@ -4889,7 +4888,7 @@ if (isIndirect) ConstraintStr += '*'; - // If this output register is pinned to a machine register, use that machine + // If this input register is pinned to a machine register, use that machine // register instead of the specified constraint. if (TREE_CODE(Val) == VAR_DECL && DECL_HARD_REGISTER(Val)) { const char *RegName = extractRegisterName(Val); From bob.wilson at apple.com Thu May 27 00:30:36 2010 From: bob.wilson at apple.com (Bob Wilson) Date: Thu, 27 May 2010 05:30:36 -0000 Subject: [llvm-commits] [llvm] r104805 - /llvm/trunk/test/FrontendC/2010-05-26-AsmSideEffect.c Message-ID: <20100527053036.A5BD9312800A@llvm.org> Author: bwilson Date: Thu May 27 00:30:36 2010 New Revision: 104805 URL: http://llvm.org/viewvc/llvm-project?rev=104805&view=rev Log: Add a test for llvm-gcc svn r104726. Added: llvm/trunk/test/FrontendC/2010-05-26-AsmSideEffect.c Added: llvm/trunk/test/FrontendC/2010-05-26-AsmSideEffect.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendC/2010-05-26-AsmSideEffect.c?rev=104805&view=auto ============================================================================== --- llvm/trunk/test/FrontendC/2010-05-26-AsmSideEffect.c (added) +++ llvm/trunk/test/FrontendC/2010-05-26-AsmSideEffect.c Thu May 27 00:30:36 2010 @@ -0,0 +1,12 @@ +// RUN: %llvmgcc %s -S -emit-llvm -o - | FileCheck %s +// Radar 8026855 + +int test (void *src) { + register int w0 asm ("0"); + // CHECK: call i32 asm sideeffect + asm ("ldr %0, [%1]": "=r" (w0): "r" (src)); + // The asm to read the value of w0 has a sideeffect for a different reason + // (see 2010-05-18-asmsched.c) but that's not what this is testing for. + // CHECK: call i32 asm + return w0; +} From daniel at zuster.org Thu May 27 00:31:33 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Thu, 27 May 2010 05:31:33 -0000 Subject: [llvm-commits] [llvm] r104806 - /llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp Message-ID: <20100527053133.1CF7D312800A@llvm.org> Author: ddunbar Date: Thu May 27 00:31:32 2010 New Revision: 104806 URL: http://llvm.org/viewvc/llvm-project?rev=104806&view=rev Log: AsmMatcher: Ensure classes are totally ordered, so we can std::sort them reliably. Modified: llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp Modified: llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp?rev=104806&r1=104805&r2=104806&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp Thu May 27 00:31:32 2010 @@ -388,6 +388,9 @@ /// operator< - Compare two classes. bool operator<(const ClassInfo &RHS) const { + if (this == &RHS) + return false; + // Unrelated classes can be ordered by kind. if (!isRelatedTo(RHS)) return Kind < RHS.Kind; @@ -403,7 +406,13 @@ default: // This class preceeds the RHS if it is a proper subset of the RHS. - return this != &RHS && isSubsetOf(RHS); + if (isSubsetOf(RHS)) + return true; + if (RHS.isSubsetOf(*this)) + return false; + + // Otherwise, order by name to ensure we have a total ordering. + return ValueName < RHS.ValueName; } } }; From rjmccall at apple.com Thu May 27 03:04:55 2010 From: rjmccall at apple.com (John McCall) Date: Thu, 27 May 2010 01:04:55 -0700 Subject: [llvm-commits] [llvm] r104419 - in /llvm/trunk: include/llvm/CodeGen/ISDOpcodes.h include/llvm/Intrinsics.td lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp lib/Target/ARM/ARMBaseInstrInfo.cpp lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMISelLowering.h lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/ARMInstrThumb.td In-Reply-To: <20100522010619.02E25312800A@llvm.org> References: <20100522010619.02E25312800A@llvm.org> Message-ID: <5C945C35-D6F5-457D-932E-F1744B9439E6@apple.com> On May 21, 2010, at 6:06 PM, Jim Grosbach wrote: > Modified: llvm/trunk/include/llvm/Intrinsics.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=104419&r1=104418&r2=104419&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/Intrinsics.td (original) > +++ llvm/trunk/include/llvm/Intrinsics.td Fri May 21 20:06:18 2010 > @@ -306,11 +306,13 @@ > def int_eh_dwarf_cfa : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty]>; > > let Properties = [IntrNoMem] in { > - def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>; > - def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty]>; > + def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>, > + GCCBuiltin<"__builtin_setjmp">; > def int_eh_sjlj_lsda : Intrinsic<[llvm_ptr_ty]>; > def int_eh_sjlj_callsite: Intrinsic<[], [llvm_i32_ty]>; > } > +def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty], [IntrWriteArgMem]>, > + GCCBuiltin<"__builtin_longjmp">; > > //===---------------- Generic Variable Attribute Intrinsics----------------===// > // > Hey, Jim. This breaks the assumption that Intrinsic::getIntrinsicForGCCBuiltin() will return a function whose type is "reasonably similar" to the GCC builtin. __builtin_longjmp() has the same signature as longjmp, i.e. it takes two arguments. Clang actually relies on this assumption (), although apparently we don't test IR gen for __builtin_longjmp in our test suite. John. From ggreif at gmail.com Thu May 27 04:32:38 2010 From: ggreif at gmail.com (Gabor Greif) Date: Thu, 27 May 2010 09:32:38 -0000 Subject: [llvm-commits] [llvm] r104831 - in /llvm/trunk/test/Other: 2010-05-06-Printer.ll 2010-05-60-Printer.ll Message-ID: <20100527093238.C2E6C312800A@llvm.org> Author: ggreif Date: Thu May 27 04:32:38 2010 New Revision: 104831 URL: http://llvm.org/viewvc/llvm-project?rev=104831&view=rev Log: rename test to represent meaningful date Added: llvm/trunk/test/Other/2010-05-06-Printer.ll - copied unchanged from r104693, llvm/trunk/test/Other/2010-05-60-Printer.ll Removed: llvm/trunk/test/Other/2010-05-60-Printer.ll Removed: llvm/trunk/test/Other/2010-05-60-Printer.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/2010-05-60-Printer.ll?rev=104830&view=auto ============================================================================== --- llvm/trunk/test/Other/2010-05-60-Printer.ll (original) +++ llvm/trunk/test/Other/2010-05-60-Printer.ll (removed) @@ -1,6 +0,0 @@ -; RUN: llc -O2 -print-after-all < %s 2>&1 - -define void @tester(){ - ret void -} - From ggreif at gmail.com Thu May 27 04:48:47 2010 From: ggreif at gmail.com (Gabor Greif) Date: Thu, 27 May 2010 09:48:47 -0000 Subject: [llvm-commits] [llvm] r104832 - /llvm/trunk/include/llvm/Support/DOTGraphTraits.h Message-ID: <20100527094847.774B8312800A@llvm.org> Author: ggreif Date: Thu May 27 04:48:47 2010 New Revision: 104832 URL: http://llvm.org/viewvc/llvm-project?rev=104832&view=rev Log: typo Modified: llvm/trunk/include/llvm/Support/DOTGraphTraits.h Modified: llvm/trunk/include/llvm/Support/DOTGraphTraits.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/DOTGraphTraits.h?rev=104832&r1=104831&r2=104832&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/DOTGraphTraits.h (original) +++ llvm/trunk/include/llvm/Support/DOTGraphTraits.h Thu May 27 04:48:47 2010 @@ -59,7 +59,7 @@ return false; } - /// isNodeHidden - If thie function returns true, the given node is not + /// isNodeHidden - If the function returns true, the given node is not /// displayed in the graph. static bool isNodeHidden(const void *Node) { return false; From zonr.xchg at gmail.com Thu May 27 05:07:16 2010 From: zonr.xchg at gmail.com (Zonr Chang) Date: Thu, 27 May 2010 18:07:16 +0800 Subject: [llvm-commits] [PATCH] [ARM JIT] To fix "llvm_unreachable("Unable to handle this constantpool entry!")" In-Reply-To: References: Message-ID: Let me have a try. The attached patch combines arm-jit-ConstantVector-ConstantArray.patch and arm-jit-LEApcrel.patch provided by Shih-Wei with typo/coding fixing mentioned by Nick. The test cases used in PR7226 and PR7227 are the same. And only with this combined patch, test case can be successfully JIT'ed and executed. I simplified the test case as below: ==== BEGIN TEST CASE SNIPPET ==== int gTextureSwap; float scale[1]; int main(int argc, char** argv) { if (gTextureSwap != 0) scale[0] = .25f; else scale[0] = 4.f; return 55; } ==== END TEST CASE SNIPPET ==== The assembly showed after JIT is (by disassemble the result binary): JIT: Disassembled code: main e3060ff8 movw r0, #28664 e34100ca movt r0, #4298 e3a02000 mov r2, #0 e5900000 ldr r0, [r0] e3500000 cmp r0, #0 e3a00000 mov r0, #0 3a00001 moveq r0, #1 e3500000 cmp r0, #0 13a02004 movne r2, #4 e28f0018 add r0, pc, #24 ; require pseudo instruction LEApcrel e0800002 add r0, r0, r2 ed900a00 vldr.32 s0, [r0] e3060ff4 movw r0, #28660 e34100ca movt r0, #4298 ed800a00 vstr.32 s0, [r0] e3a00037 mov r0, #55 e12fff1e bx lr 3e800000 cdplo p0, #8, cr0, cr0, cr0, #0 ; 0x3e800000 = 0.25 40800000 addmi r0, r0, r0 ; 0x40800000 = 4.0 In this case, as mentioned in Liao's bug report, 0.25f and 4.f in the code above will become ConstantArray of 2 elements. And I'm not sure whether there's any needed implementation for ConstantVector in emitConstantToMemory(...). To avoid to deal with the alignment and padding problems arising from materializing vector type, I just leave it out (I try to find a test case that will need vector constant materialization but no any result up to now). However, here comes another question. Does anyone know what kind of "Constant" can be in emitConstantToMemory(...)? Zonr On Thu, May 27, 2010 at 11:41 AM, Nick Lewycky wrote: > Hi Shih-wei, I have a few comments: > > +void ARMCodeEmitter::emitConstantToMemory(unsigned CPI, const Constant* C) > { > > The rest of the code uses "const Constant *C". Please place the space > before the star. > > In X86CodeEmitter, the > > + } else if (const ConstantVector *CV = dyn_cast(C)) { > + for (unsigned i=0;igetNumOperands();i++) > + emitConstantToMemory(CPI, CV->getOperand(i)); > + } else if (const ConstantArray *CA = dyn_cast(C)) { > + for (unsigned i=0;igetNumOperands();i++) > + emitConstantToMemory(CPI, CA->getOperand(i)); > + } else { > + llvm_unreachable("Unable to handle this constantpool entry!"); > + } > > A few things. Firstly, please use proper whitespace, make your code look > like the code around you. This means "for (unsigned i = 0; i < > CA->getNumOperands(); i++)". Secondly, always hoist out the end computation > of a loop, which would make it "for (unsigned i = 0, e = > CV->getNumOperands(); i != e; i++)". > > Now, you've added a lot of cases and I'm wondering whether it's time to > switch away from the else-if nesting. As it is, the dyn_cast<> macros have > to be tried in the order they're written in the code. Using a switch only > evaluates the concrete type once, and makes the code: > > switch (C->getValueID()) { > case GlobalVariableVal: // fall-through > case GlobalAliasVal: // fall-through > case FunctionVal: { > GlobalValue *GV = cast(C); > emitGlobalAddress ... > break; > } > case ConstantIntVal: { > ConstantInt *CI = cast(C); > ... > break; > } > ... > } > > I also noticed that you've added potentially unbounded recursion (well, > it's bounded by the depth of nesting of array types), but that doesn't look > easy to fix, and it's probably not going to be a problem anyways (ie., we'd > run out of ArrayType objects first). > > Now finally, with all that said, I'm still not sure about this patch. Is > the layout of a vector in memory the same as an array in memory? You're > treating them the same with no padding or alignment issues considered, just > stamping the elements into memory. Someone else should look at that before > this patch lands. > > Nick > > On 26 May 2010 02:27, Shih-wei Liao wrote: > >> See http://llvm.org/bugs/show_bug.cgi?id=7226: ARM JIT couldn't emit >> constant pool entry for "ConstantVector" and "ConstantArray". >> >> The patch passes both "make check" and "make check-lit". Basically, >> the patch added the processing of ConstantVector and ConstantArray. >> The problem is gone after the patch. >> -- >> Thanks, >> Shih-wei >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> >> > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100527/5fd0122a/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: arm-jit-LEApcrel2.patch Type: application/octet-stream Size: 6365 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100527/5fd0122a/attachment.obj From benny.kra at googlemail.com Thu May 27 09:21:40 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Thu, 27 May 2010 16:21:40 +0200 Subject: [llvm-commits] [llvm] r104689 - in /llvm/trunk: include/llvm/MC/MCAssembler.h lib/MC/MCAssembler.cpp In-Reply-To: <20100526065057.9D94C3128060@llvm.org> References: <20100526065057.9D94C3128060@llvm.org> Message-ID: On 26.05.2010, at 08:50, Daniel Dunbar wrote: > Author: ddunbar > Date: Wed May 26 01:50:57 2010 > New Revision: 104689 > > URL: http://llvm.org/viewvc/llvm-project?rev=104689&view=rev > Log: > MC: Eliminate MCFragment vtable, which was unnecessary. > > Modified: > llvm/trunk/include/llvm/MC/MCAssembler.h > llvm/trunk/lib/MC/MCAssembler.cpp > > Modified: llvm/trunk/include/llvm/MC/MCAssembler.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAssembler.h?rev=104689&r1=104688&r2=104689&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/MC/MCAssembler.h (original) > +++ llvm/trunk/include/llvm/MC/MCAssembler.h Wed May 26 01:50:57 2010 > @@ -108,7 +108,6 @@ > public: > // Only for sentinel. > MCFragment(); > - virtual ~MCFragment(); Now MCFragment subclasses that contain a vector (or other members which must be destroyed) leak memory. ==16947== 128 bytes in 1 blocks are definitely lost in loss record 131 of 134 ==16947== at 0x4C229C7: operator new(unsigned long) (vg_replace_malloc.c:220) ==16947== by 0xD129CC: llvm::SmallVectorBase::grow_pod(unsigned long, unsigned long) (SmallVector.cpp:24) ==16947== by 0x62B3B7: llvm::SmallVectorTemplateBase::grow(unsigned long) (SmallVector.h:259) ==16947== by 0x6B22B6: void llvm::SmallVectorImpl::append(char*, char*) (SmallVector.h:355) ==16947== by 0xBDA03D: (anonymous namespace)::MCMachOStreamer::EmitInstToData(llvm::MCInst const&) (MCMachOStreamer.cpp:455) ==16947== by 0xBDA168: (anonymous namespace)::MCMachOStreamer::EmitInstruction(llvm::MCInst const&) (MCMachOStreamer.cpp:468) ==16947== by 0x93B363: llvm::AsmParser::ParseStatement() (AsmParser.cpp:814) ==16947== by 0x9373EE: llvm::AsmParser::Run(bool, bool) (AsmParser.cpp:121) ==16947== by 0x40B9F5: AssembleInput(char const*) (llvm-mc.cpp:325) ==16947== by 0x40BD39: main (llvm-mc.cpp:383) ==16947== ==16947== 256 bytes in 1 blocks are definitely lost in loss record 133 of 134 ==16947== at 0x4C229C7: operator new(unsigned long) (vg_replace_malloc.c:220) ==16947== by 0xBDCE2C: __gnu_cxx::new_allocator::allocate(unsigned long, void const*) (new_allocator.h:89) ==16947== by 0xBDC586: std::_Vector_base >::_M_allocate(unsigned long) (stl_vector.h:140) ==16947== by 0xBDB850: std::vector >::_M_insert_aux(__gnu_cxx::__normal_iterator > >, llvm::MCFixup const&) (vector.tcc:322) ==16947== by 0xBDABBB: std::vector >::push_back(llvm::MCFixup const&) (stl_vector.h:741) ==16947== by 0xBDA4AE: llvm::MCDataFragment::addFixup(llvm::MCFixup) (MCAssembler.h:134) ==16947== by 0xBD9FEA: (anonymous namespace)::MCMachOStreamer::EmitInstToData(llvm::MCInst const&) (MCMachOStreamer.cpp:453) ==16947== by 0xBDA168: (anonymous namespace)::MCMachOStreamer::EmitInstruction(llvm::MCInst const&) (MCMachOStreamer.cpp:468) ==16947== by 0x93B363: llvm::AsmParser::ParseStatement() (AsmParser.cpp:814) ==16947== by 0x9373EE: llvm::AsmParser::Run(bool, bool) (AsmParser.cpp:121) ==16947== by 0x40B9F5: AssembleInput(char const*) (llvm-mc.cpp:325) ==16947== by 0x40BD39: main (llvm-mc.cpp:383) From matti.niemenmaa+llvm at iki.fi Thu May 27 09:55:16 2010 From: matti.niemenmaa+llvm at iki.fi (Matti Niemenmaa) Date: Thu, 27 May 2010 17:55:16 +0300 Subject: [llvm-commits] [PATCH] InstCombine: remove malloc+free if malloc's only uses are comparisons to null In-Reply-To: <4BF7A953.8000303@iki.fi> References: <4BF02485.2050508@iki.fi> <4BF1088E.30805@free.fr> <4BF59981.90607@free.fr> <4BF7A953.8000303@iki.fi> Message-ID: On 2010-05-22 12:52, Matti Niemenmaa wrote: > On 2010-05-22 01:55, Chris Lattner wrote: >> A couple more requests :) >> >> +++ test/Transforms/InstCombine/malloc-free-delete2.ll (revision 0) >> @@ -0,0 +1,11 @@ >> +; RUN: opt< %s -instcombine -S | FileCheck %s >> +define i1 @foo() { >> +; CHECK: @foo >> +; CHECK-NEXT: ret i1 false >> + %m = call i8* @malloc(i64 1) >> + %z = icmp eq i8* %m, null >> + call void @free(i8* %m) >> + ret i1 %z >> +} >> +declare i8* @malloc(i64) >> +declare void @free(i8*) >> >> Please merge this into >> test/Transforms/InstCombine/malloc-free-delete.ll since it already >> uses filecheck, thanks! > > Done. I removed -globaldce from that as well, since it wasn't depending > on it. > >> + if (const ICmpInst *ICI = dyn_cast(*UI)) { >> + ICmpInst::Predicate Pred = ICI->getPredicate(); >> + if (Pred == ICmpInst::ICMP_EQ || Pred == ICmpInst::ICMP_NE&& >> >> Please use ICI->isEquality() >> >> + (isa(ICI->getOperand(0)) || >> + isa(ICI->getOperand(1)))) >> >> comparisons against null will put the null on the RHS of the compare, >> just check operand #1. > > Both done in the attached, thanks for the simplifications. Ping? From baldrick at free.fr Thu May 27 10:03:18 2010 From: baldrick at free.fr (Duncan Sands) Date: Thu, 27 May 2010 17:03:18 +0200 Subject: [llvm-commits] [PATCH] InstCombine: remove malloc+free if malloc's only uses are comparisons to null In-Reply-To: References: <4BF02485.2050508@iki.fi> <4BF1088E.30805@free.fr> <4BF59981.90607@free.fr> <4BF7A953.8000303@iki.fi> Message-ID: <4BFE89B6.2090904@free.fr> Hi Matti, >> Both done in the attached, thanks for the simplifications. > > Ping? I accidentally deleted your email with the patch, which is why I didn't apply it. Please send it again. Ciao, Duncan. From grosbach at apple.com Thu May 27 10:04:02 2010 From: grosbach at apple.com (Jim Grosbach) Date: Thu, 27 May 2010 15:04:02 -0000 Subject: [llvm-commits] [llvm] r104833 - /llvm/trunk/include/llvm/Intrinsics.td Message-ID: <20100527150402.3DD54312800A@llvm.org> Author: grosbach Date: Thu May 27 10:04:02 2010 New Revision: 104833 URL: http://llvm.org/viewvc/llvm-project?rev=104833&view=rev Log: remove incorrect GCCBuiltin<> usage Modified: llvm/trunk/include/llvm/Intrinsics.td Modified: llvm/trunk/include/llvm/Intrinsics.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=104833&r1=104832&r2=104833&view=diff ============================================================================== --- llvm/trunk/include/llvm/Intrinsics.td (original) +++ llvm/trunk/include/llvm/Intrinsics.td Thu May 27 10:04:02 2010 @@ -309,10 +309,8 @@ def int_eh_sjlj_lsda : Intrinsic<[llvm_ptr_ty]>; def int_eh_sjlj_callsite: Intrinsic<[], [llvm_i32_ty]>; } -def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>, - GCCBuiltin<"__builtin_setjmp">; -def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty]>, - GCCBuiltin<"__builtin_longjmp">; +def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>; +def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty]>; //===---------------- Generic Variable Attribute Intrinsics----------------===// // From grosbach at apple.com Thu May 27 10:05:59 2010 From: grosbach at apple.com (Jim Grosbach) Date: Thu, 27 May 2010 08:05:59 -0700 Subject: [llvm-commits] [llvm] r104419 - in /llvm/trunk: include/llvm/CodeGen/ISDOpcodes.h include/llvm/Intrinsics.td lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp lib/Target/ARM/ARMBaseInstrInfo.cpp lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMISelLowering.h lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/ARMInstrThumb.td In-Reply-To: <5C945C35-D6F5-457D-932E-F1744B9439E6@apple.com> References: <20100522010619.02E25312800A@llvm.org> <5C945C35-D6F5-457D-932E-F1744B9439E6@apple.com> Message-ID: On May 27, 2010, at 1:04 AM, John McCall wrote: > On May 21, 2010, at 6:06 PM, Jim Grosbach wrote: >> Modified: llvm/trunk/include/llvm/Intrinsics.td >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=104419&r1=104418&r2=104419&view=diff >> ============================================================================== >> --- llvm/trunk/include/llvm/Intrinsics.td (original) >> +++ llvm/trunk/include/llvm/Intrinsics.td Fri May 21 20:06:18 2010 >> @@ -306,11 +306,13 @@ >> def int_eh_dwarf_cfa : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty]>; >> >> let Properties = [IntrNoMem] in { >> - def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>; >> - def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty]>; >> + def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>, >> + GCCBuiltin<"__builtin_setjmp">; >> def int_eh_sjlj_lsda : Intrinsic<[llvm_ptr_ty]>; >> def int_eh_sjlj_callsite: Intrinsic<[], [llvm_i32_ty]>; >> } >> +def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty], [IntrWriteArgMem]>, >> + GCCBuiltin<"__builtin_longjmp">; >> >> //===---------------- Generic Variable Attribute Intrinsics----------------===// >> // >> > > Hey, Jim. This breaks the assumption that Intrinsic::getIntrinsicForGCCBuiltin() > will return a function whose type is "reasonably similar" to the GCC builtin. > __builtin_longjmp() has the same signature as longjmp, i.e. it takes two arguments. > > Clang actually relies on this assumption (), although > apparently we don't test IR gen for __builtin_longjmp in our test suite. > Woops. Quite right. FWIW, there's code to handle code-gen for builtin_setjmp and builtin_longjmp in clang that's currently int an "#if 0" block. It works for arm/darwin with these intrinsics enabled. eh.sjlj.setjmp has the same signature, but requires some additional front-end logic, so I'll remove the GCCBuiltin tag there, also. Fixed in r104833. Thanks for having a look! -j From matti.niemenmaa+llvm at iki.fi Thu May 27 10:16:34 2010 From: matti.niemenmaa+llvm at iki.fi (Matti Niemenmaa) Date: Thu, 27 May 2010 18:16:34 +0300 Subject: [llvm-commits] [PATCH] InstCombine: remove malloc+free if malloc's only uses are comparisons to null In-Reply-To: <4BFE89B6.2090904@free.fr> References: <4BF02485.2050508@iki.fi> <4BF1088E.30805@free.fr> <4BF59981.90607@free.fr> <4BF7A953.8000303@iki.fi> <4BFE89B6.2090904@free.fr> Message-ID: On 2010-05-27 18:03, Duncan Sands wrote: > I accidentally deleted your email with the patch, which is why > I didn't apply it. Please send it again. Attached. -------------- next part -------------- A non-text attachment was scrubbed... Name: instcombine-mallocs-only-null-compared-against.patch Type: text/x-patch Size: 7336 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100527/2b67e526/attachment.bin From baldrick at free.fr Thu May 27 10:24:45 2010 From: baldrick at free.fr (Duncan Sands) Date: Thu, 27 May 2010 17:24:45 +0200 Subject: [llvm-commits] [llvm] r104703 - /llvm/trunk/docs/ExceptionHandling.html In-Reply-To: <20100526162141.543F4312800A@llvm.org> References: <20100526162141.543F4312800A@llvm.org> Message-ID: <4BFE8EBD.7000005@free.fr> Hi Jim, > +

    Thellvm.eh.sjlj.longjmp > + intrinsic is used to implement__builtin_longjmp() for SJLJ > + style exception handling. The single parameter is a pointer to a > + buffer populated by > +llvm.eh.sjlj.setjmp. The frame pointer and stack pointer > + are restored from the buffer, then control is transfered to the > + destination address.

    I think it would be good to explain that __builtin_longjmp comes from gcc. While this is obvious for anyone who has hacked on gcc, not everyone does! Thanks, Duncan. From gohman at apple.com Thu May 27 11:03:06 2010 From: gohman at apple.com (Dan Gohman) Date: Thu, 27 May 2010 16:03:06 -0000 Subject: [llvm-commits] [test-suite] r104836 - /test-suite/trunk/SingleSource/Benchmarks/Makefile Message-ID: <20100527160306.A7743312800A@llvm.org> Author: djg Date: Thu May 27 11:03:06 2010 New Revision: 104836 URL: http://llvm.org/viewvc/llvm-project?rev=104836&view=rev Log: Re-enable Misc-C++-EH, now that clang reportedly supports it. Modified: test-suite/trunk/SingleSource/Benchmarks/Makefile Modified: test-suite/trunk/SingleSource/Benchmarks/Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/Benchmarks/Makefile?rev=104836&r1=104835&r2=104836&view=diff ============================================================================== --- test-suite/trunk/SingleSource/Benchmarks/Makefile (original) +++ test-suite/trunk/SingleSource/Benchmarks/Makefile Thu May 27 11:03:06 2010 @@ -1,11 +1,6 @@ LEVEL = ../.. - -# TODO: Misc-C++-EH is excluded from PARALLEL_DIRS because spirit.cpp -# fails with clang. - PARALLEL_DIRS=Dhrystone CoyoteBench Shootout Shootout-C++ Stanford McGill \ - Misc Misc-C++ BenchmarkGame Adobe-C++ - + Misc Misc-C++ Misc-C++-EH BenchmarkGame Adobe-C++ LDFLAGS += -lm include $(LEVEL)/SingleSource/Makefile.singlesrc From gohman at apple.com Thu May 27 11:15:28 2010 From: gohman at apple.com (Dan Gohman) Date: Thu, 27 May 2010 16:15:28 -0000 Subject: [llvm-commits] [llvm] r104840 - /llvm/trunk/ Message-ID: <20100527161528.85E72312800A@llvm.org> Author: djg Date: Thu May 27 11:15:28 2010 New Revision: 104840 URL: http://llvm.org/viewvc/llvm-project?rev=104840&view=rev Log: Delete a spurious svn:mergeinfo property. Modified: llvm/trunk/ (props changed) Propchange: llvm/trunk/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo (removed) @@ -1 +0,0 @@ -/llvm/branches/Apple/Morbo:102475 From stuart at apple.com Thu May 27 11:16:54 2010 From: stuart at apple.com (Stuart Hastings) Date: Thu, 27 May 2010 16:16:54 -0000 Subject: [llvm-commits] [llvm] r104841 - in /llvm/trunk: lib/Analysis/DebugInfo.cpp lib/CodeGen/AsmPrinter/DwarfDebug.cpp test/FrontendC++/2010-02-17-DbgArtificialArg.cpp Message-ID: <20100527161654.AFC4D312800A@llvm.org> Author: stuart Date: Thu May 27 11:16:54 2010 New Revision: 104841 URL: http://llvm.org/viewvc/llvm-project?rev=104841&view=rev Log: Support for nested functions/classes in debug output. Radar 7424645. Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp llvm/trunk/test/FrontendC++/2010-02-17-DbgArtificialArg.cpp Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DebugInfo.cpp?rev=104841&r1=104840&r2=104841&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/DebugInfo.cpp (original) +++ llvm/trunk/lib/Analysis/DebugInfo.cpp Thu May 27 11:16:54 2010 @@ -1110,18 +1110,6 @@ return DILocation(MDNode::get(VMContext, &Elts[0], 4)); } -/// CreateLocation - Creates a debug info location. -DILocation DIFactory::CreateLocation(unsigned LineNo, unsigned ColumnNo, - DIScope S, MDNode *OrigLoc) { - Value *Elts[] = { - ConstantInt::get(Type::getInt32Ty(VMContext), LineNo), - ConstantInt::get(Type::getInt32Ty(VMContext), ColumnNo), - S, - OrigLoc - }; - return DILocation(MDNode::get(VMContext, &Elts[0], 4)); -} - //===----------------------------------------------------------------------===// // DIFactory: Routines for inserting code into a function //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=104841&r1=104840&r2=104841&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Thu May 27 11:16:54 2010 @@ -866,6 +866,10 @@ } else if (Context.isNameSpace()) { DIE *ContextDIE = getOrCreateNameSpace(DINameSpace(Context)); ContextDIE->addChild(Die); + } else if (Context.isSubprogram()) { + DIE *ContextDIE = createSubprogramDIE(DISubprogram(Context), + /*MakeDecl=*/false); + ContextDIE->addChild(Die); } else if (DIE *ContextDIE = getCompileUnit(Context)->getDIE(Context)) ContextDIE->addChild(Die); else @@ -1055,6 +1059,10 @@ if (DIDescriptor(ContainingType).isCompositeType()) addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, getOrCreateTypeDIE(DIType(ContainingType))); + else { + DIDescriptor Context = CTy.getContext(); + addToContextOwner(&Buffer, Context); + } break; } default: @@ -1329,6 +1337,9 @@ // DW_TAG_inlined_subroutine may refer to this DIE. SPCU->insertDIE(SP, SPDie); + // Add to context owner. + addToContextOwner(SPDie, SP.getContext()); + return SPDie; } Modified: llvm/trunk/test/FrontendC++/2010-02-17-DbgArtificialArg.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendC%2B%2B/2010-02-17-DbgArtificialArg.cpp?rev=104841&r1=104840&r2=104841&view=diff ============================================================================== --- llvm/trunk/test/FrontendC++/2010-02-17-DbgArtificialArg.cpp (original) +++ llvm/trunk/test/FrontendC++/2010-02-17-DbgArtificialArg.cpp Thu May 27 11:16:54 2010 @@ -1,4 +1,4 @@ -// RUN: %llvmgcc -g -S %s -o - | grep DW_TAG_pointer_type | grep "i32 524303, metadata .., metadata ..., metadata .., i32 ., i64 .., i64 .., i64 0, i32 64, metadata ..." +// RUN: %llvmgcc -g -S %s -o - | FileCheck %s // Here, second to last argument "i32 64" indicates that artificial type is set. // Test to artificial attribute attahed to "this" pointer type. // Radar 7655792 and 7655002 @@ -10,5 +10,7 @@ int foo() { A a; + // Matching "i32 64, metadata !} ; [ DW_TAG_pointer_type ]" + // CHECK: i32 64, metadata {{![0-9]+\} ; \[ DW_TAG_pointer_type \]}} return a.fn1(1); } From stuart at apple.com Thu May 27 11:16:58 2010 From: stuart at apple.com (Stuart Hastings) Date: Thu, 27 May 2010 16:16:58 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r104842 - in /llvm-gcc-4.2/trunk/gcc: llvm-backend.cpp llvm-convert.cpp llvm-debug.cpp llvm-debug.h llvm-internal.h Message-ID: <20100527161658.DB27A3128018@llvm.org> Author: stuart Date: Thu May 27 11:16:58 2010 New Revision: 104842 URL: http://llvm.org/viewvc/llvm-project?rev=104842&view=rev Log: Support for nested functions/classes in debug output. Radar 7424645. Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp llvm-gcc-4.2/trunk/gcc/llvm-debug.h llvm-gcc-4.2/trunk/gcc/llvm-internal.h Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=104842&r1=104841&r2=104842&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Thu May 27 11:16:58 2010 @@ -531,6 +531,8 @@ if (debug_info_level > DINFO_LEVEL_NONE) TheDebugInfo = new DebugInfo(TheModule); + else + TheDebugInfo = 0; } /// performLateBackendInitialization - Set backend options that may only be @@ -1023,7 +1025,7 @@ // Convert the AST to raw/ugly LLVM code. Function *Fn; { - TreeToLLVM Emitter(fndecl); + TreeToLLVM *Emitter = new TreeToLLVM(fndecl); enum symbol_visibility vis = DECL_VISIBILITY (fndecl); if (vis != VISIBILITY_DEFAULT) @@ -1031,7 +1033,8 @@ // visibility that's not supported by the target. targetm.asm_out.visibility(fndecl, vis); - Fn = Emitter.EmitFunction(); + Fn = TheTreeToLLVM->EmitFunction(); + Emitter->~TreeToLLVM(); } #if 0 Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=104842&r1=104841&r2=104842&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Thu May 27 11:16:58 2010 @@ -148,7 +148,7 @@ //===----------------------------------------------------------------------===// /// TheTreeToLLVM - Keep track of the current function being compiled. -static TreeToLLVM *TheTreeToLLVM = 0; +TreeToLLVM *TheTreeToLLVM = 0; const TargetData &getTargetData() { return *TheTarget->getTargetData(); @@ -157,7 +157,7 @@ /// EmitDebugInfo - Return true if debug info is to be emitted for current /// function. bool TreeToLLVM::EmitDebugInfo() { - if (TheDebugInfo && !DECL_IGNORED_P(getFUNCTION_DECL())) + if (TheDebugInfo && getFUNCTION_DECL() && !DECL_IGNORED_P(getFUNCTION_DECL())) return true; return false; } @@ -425,13 +425,13 @@ return (Val = false); } -// Walk the GCC BLOCK() tree. Set BLOCK_NUMBER() to the depth of each -// block; this is necessary for lexical block debug info. Visit all -// the BLOCK_VARS(), and add them to the set s. Since the -// unexpanded_var_list seems to be a superset of all the scoped -// variables in every lexical BLOCK(), this facilitates allocating the -// scoped variables in their blocks, and the rest at the outermost -// scope of the function. +// Depth-first walk of the GCC BLOCK() tree. Set BLOCK_NUMBER() to +// the depth of each block; this is necessary for lexical block debug +// info. Visit all the BLOCK_VARS(), and add them to the set s. +// Since the unexpanded_var_list seems to be a superset of all the +// scoped variables in every lexical BLOCK(), this facilitates +// allocating the scoped variables in their blocks, and the rest at +// the outermost scope of the function. void TreeToLLVM::setLexicalBlockDepths(tree t, treeset &s, unsigned level) { tree bstep, step; switch (TREE_CODE(t)) { @@ -616,7 +616,7 @@ SeenBlocks.clear(); if (EmitDebugInfo()) - TheDebugInfo->EmitFunctionStart(FnDecl, Fn, Builder.GetInsertBlock()); + TheDebugInfo->EmitFunctionStart(FnDecl); // Loop over all of the arguments to the function, setting Argument names and // creating argument alloca's for the PARM_DECLs in case their address is @@ -631,7 +631,7 @@ ABIConverter.HandleReturnType(TREE_TYPE(TREE_TYPE(FnDecl)), FnDecl, DECL_BUILT_IN(FnDecl)); // Remember this for use by FinishFunctionBody. - TheTreeToLLVM->ReturnOffset = Client.Offset; + ReturnOffset = Client.Offset; // Prepend the static chain (if any) to the list of arguments. tree Args = static_chain ? static_chain : DECL_ARGUMENTS(FnDecl); Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp?rev=104842&r1=104841&r2=104842&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Thu May 27 11:16:58 2010 @@ -263,6 +263,8 @@ "expected 'desired' to be a GCC BLOCK or FUNCTION_DECL"); assert ((TREE_CODE(grand) == BLOCK || TREE_CODE(grand) == FUNCTION_DECL) && "expected 'grand' to be a GCC BLOCK or FUNCTION_DECL"); + // Call myself to recursively walk back to the grandparent BLOCK; + // I'll push the RegionStack[] at every level on the way back here: if (grand != desired) push_regions(BLOCK_SUPERCONTEXT(desired), grand); // FIXME: push_regions is currently never called with desired == @@ -277,39 +279,40 @@ // regions to arrive at 'desired'. This was inspired (cribbed from) // by GCC's cfglayout.c:change_scope(). void DebugInfo::change_regions(tree desired, tree grand) { - tree current_lexical_block = getCurrentLexicalBlock(); + tree current_lexical_block; // FIXME: change_regions is currently never called with desired == // grand, but it should be fixed so nothing weird happens if they're // equal. - while (current_lexical_block != grand) { + for( current_lexical_block = getCurrentLexicalBlock(); + current_lexical_block != grand; + current_lexical_block = BLOCK_SUPERCONTEXT(current_lexical_block)) { assert(BLOCK_SUPERCONTEXT(getCurrentLexicalBlock()) && "lost BLOCK context!"); - current_lexical_block = BLOCK_SUPERCONTEXT(current_lexical_block); RegionStack.pop_back(); } DebugInfo::push_regions(desired, grand); - setCurrentLexicalBlock(desired); + setCurrentLexicalBlock(current_lexical_block); } -/// EmitFunctionStart - Constructs the debug code for entering a function. -void DebugInfo::EmitFunctionStart(tree FnDecl, Function *Fn, - BasicBlock *CurBB) { - setCurrentLexicalBlock(FnDecl); - +/// CreateSubprogramFromFnDecl - Constructs the debug code for +/// entering a function - "llvm.dbg.func.start." +DISubprogram DebugInfo::CreateSubprogramFromFnDecl(tree FnDecl) { + DISubprogram SPDecl; + bool SPDeclIsSet = false; + // True if we're currently generating LLVM for this function. + bool definition = llvm_set_decl_p(FnDecl); DIType FNType = getOrCreateType(TREE_TYPE(FnDecl)); std::map::iterator I = SPCache.find(FnDecl); if (I != SPCache.end()) { - DISubprogram SPDecl(cast(I->second)); - DISubprogram SP = - DebugFactory.CreateSubprogramDefinition(SPDecl); - SPDecl->replaceAllUsesWith(SP); - - // Push function on region stack. - RegionStack.push_back(WeakVH(SP)); - RegionMap[FnDecl] = WeakVH(SP); - return; - } + SPDecl = DISubprogram(cast(I->second)); + SPDeclIsSet = true; + // If we've already created the defining instance, OR this + // invocation won't create the defining instance, return what we + // already have. + if (SPDecl.isDefinition() || !definition) + return SPDecl; + } bool ArtificialFnWithAbstractOrigin = false; // If this artificial function has abstract origin then put this function @@ -323,11 +326,19 @@ getOrCreateFile(main_input_filename) : findRegion (DECL_CONTEXT(FnDecl)); + // The region/scope returned above can be arbitrarily deep. + // Sometimes GCC reports the true nested scoping of a function, but + // GCC usually places functions at module scope, ignoring their real + // context. Here we arbitrarily declare "__foo_block_invoke_3" + // functions at module scope for GDB sanity. + if (BLOCK_SYNTHESIZED_FUNC(FnDecl)) + SPContext = findRegion(NULL_TREE); + // Creating context may have triggered creation of this SP descriptor. So // check the cache again. I = SPCache.find(FnDecl); - if (I != SPCache.end()) { - DISubprogram SPDecl(cast(I->second)); + if (!SPDeclIsSet && I != SPCache.end()) { + SPDecl = DISubprogram(cast(I->second)); DISubprogram SP = DebugFactory.CreateSubprogramDefinition(SPDecl); SPDecl->replaceAllUsesWith(SP); @@ -335,14 +346,14 @@ // Push function on region stack. RegionStack.push_back(WeakVH(SP)); RegionMap[FnDecl] = WeakVH(SP); - return; + return SP; } // Gather location information. expanded_location Loc = GetNodeLocation(FnDecl, false); StringRef LinkageName = getLinkageName(FnDecl); - unsigned lineno = CurLineNo; + unsigned lineno = LOCATION_LINE(Loc); if (isCopyOrDestroyHelper(FnDecl)) lineno = 0; @@ -357,23 +368,37 @@ } StringRef FnName = getFunctionName(FnDecl); - + // If the Function * hasn't been created yet, use a bogus value for + // the debug internal linkage bit. + bool hasInternalLinkage = true; + if (GET_DECL_LLVM_INDEX(FnDecl)) { + Function *Fn = castDECL_LLVM(FnDecl); + hasInternalLinkage = Fn->hasInternalLinkage(); + } DISubprogram SP = DebugFactory.CreateSubprogram(SPContext, FnName, FnName, LinkageName, getOrCreateFile(Loc.file), lineno, FNType, - Fn->hasInternalLinkage(), - true /*definition*/, + hasInternalLinkage, + definition, Virtuality, VIndex, ContainingType, DECL_ARTIFICIAL (FnDecl), optimize); SPCache[FnDecl] = WeakVH(SP); + RegionMap[FnDecl] = WeakVH(SP); + if (SPDeclIsSet && SPDecl != SP) + SPDecl->replaceAllUsesWith(SP); + return SP; +} +/// EmitFunctionStart - Constructs the debug code for entering a function. +void DebugInfo::EmitFunctionStart(tree FnDecl) { + setCurrentLexicalBlock(FnDecl); + DISubprogram SP = CreateSubprogramFromFnDecl(FnDecl); // Push function on region stack. RegionStack.push_back(WeakVH(SP)); - RegionMap[FnDecl] = WeakVH(SP); } /// getOrCreateNameSpace - Get name space descriptor for the tree node. @@ -406,20 +431,61 @@ DIType Ty = getOrCreateType(Node); return DIDescriptor(Ty); } else if (DECL_P (Node)) { - if (TREE_CODE (Node) == NAMESPACE_DECL) { + switch (TREE_CODE(Node)) { + default: + /// What kind of DECL is this? + return findRegion (DECL_CONTEXT (Node)); + case NAMESPACE_DECL: { DIDescriptor NSContext = findRegion(DECL_CONTEXT(Node)); DINameSpace NS = getOrCreateNameSpace(Node, NSContext); return DIDescriptor(NS); } - return findRegion (DECL_CONTEXT (Node)); + case FUNCTION_DECL: { + DISubprogram SP = CreateSubprogramFromFnDecl(Node); + return SP; + } + } } else if (TREE_CODE(Node) == BLOCK) { // TREE_BLOCK is GCC's lexical block. - // Recursively create all necessary contexts: - DIDescriptor context = findRegion(BLOCK_SUPERCONTEXT(Node)); - DILexicalBlock lexical_block = - DebugFactory.CreateLexicalBlock(context, CurLineNo); - RegionMap[Node] = WeakVH(lexical_block); - return DIDescriptor(lexical_block); + tree nonempty_block, nonempty_supercontext=NULL_TREE; + // Find the nearest non-empty (has variables) BLOCK. This is what + // we'll declare, assumming we don't omit it entirely. + for (nonempty_block = Node; + TREE_CODE(nonempty_block) == BLOCK && !BLOCK_VARS(nonempty_block); + nonempty_block = BLOCK_SUPERCONTEXT(nonempty_block)) + ; + // Find a parent BLOCK that declares variables, and isn't the + // FUNCTION_DECL. If such a parent BLOCK exists, we'll omit it + // and declare its variables at the function scope. + if (TREE_CODE(nonempty_block) == BLOCK) + for (nonempty_supercontext = BLOCK_SUPERCONTEXT(nonempty_block); + TREE_CODE(nonempty_supercontext) == BLOCK && + !BLOCK_VARS(nonempty_supercontext); + nonempty_supercontext = BLOCK_SUPERCONTEXT(nonempty_supercontext)) + ; + // If the nearest non-empty context is the FUNCTION_DECL, that's + // our region; declare it. Otherwise, carefully avoid declaring + // the outermost lexical block. If this block hangs directly + // underneath the FUNCTION_DECL and has no siblings, we skip it; + // return the FUNCTION_DECL scope instead. Child BLOCKS will be + // emitted normally. While technically incorrect, this is what + // GCC does and GDB expects. + if (nonempty_supercontext) { + // O.K., this nonempty_block isn't the topmost BLOCK; declare it. + DIDescriptor context = findRegion(BLOCK_SUPERCONTEXT(nonempty_block)); + DILexicalBlock lexical_block = + DebugFactory.CreateLexicalBlock(context, CurLineNo); + RegionMap[Node] = WeakVH(lexical_block); + return DIDescriptor(lexical_block); + } + tree function_decl; + // Find the enclosing FUNCTION_DECL. + for (function_decl = nonempty_block; + TREE_CODE(function_decl) == BLOCK; + function_decl = BLOCK_SUPERCONTEXT(function_decl)) + ; + DISubprogram SP = CreateSubprogramFromFnDecl(function_decl); + return SP; } // Otherwise main compile unit covers everything. @@ -651,7 +717,7 @@ sprintf(FwdTypeName, "fwd.type.%d", FwdTypeCount++); llvm::DIType FwdType = DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_subroutine_type, - getOrCreateFile(main_input_filename), + findRegion(TYPE_CONTEXT(type)), FwdTypeName, getOrCreateFile(main_input_filename), 0, 0, 0, 0, 0, @@ -738,7 +804,7 @@ StringRef PName = FromTy.getName(); DIType PTy = - DebugFactory.CreateDerivedType(Tag, findRegion(TYPE_CONTEXT(type)), + DebugFactory.CreateDerivedType(Tag, findRegion(TYPE_CONTEXT(type)), Tag == DW_TAG_pointer_type ? StringRef() : PName, getOrCreateFile(main_input_filename), Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.h?rev=104842&r1=104841&r2=104842&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-debug.h (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-debug.h Thu May 27 11:16:58 2010 @@ -118,9 +118,13 @@ // by GCC's cfglayout.c:change_scope(). void change_regions(tree_node *desired, tree_node *grand); - /// EmitFunctionStart - Constructs the debug code for entering a function - + /// CreateSubprogramFromFnDecl - Constructs the debug code for entering a function - /// "llvm.dbg.func.start." - void EmitFunctionStart(tree_node *FnDecl, Function *Fn, BasicBlock *CurBB); + DISubprogram CreateSubprogramFromFnDecl(tree_node *FnDecl); + + /// EmitFunctionStart - Constructs the debug code for entering a function - + /// "llvm.dbg.func.start", and pushes it onto the RegionStack. + void EmitFunctionStart(tree_node *FnDecl); /// EmitFunctionEnd - Constructs the debug code for exiting a declarative /// region - "llvm.dbg.region.end." Modified: llvm-gcc-4.2/trunk/gcc/llvm-internal.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-internal.h?rev=104842&r1=104841&r2=104842&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Thu May 27 11:16:58 2010 @@ -75,7 +75,7 @@ extern llvm::Module *TheModule; /// TheDebugInfo - This object is responsible for gather all debug information. -/// If it's value is NULL then no debug information should be gathered. +/// If its value is NULL then no debug information should be gathered. extern llvm::DebugInfo *TheDebugInfo; /// TheTarget - The current target being compiled for. @@ -281,6 +281,7 @@ BasicBlock *ReturnBB; BasicBlock *UnwindBB; unsigned ReturnOffset; + // Lexical BLOCKS that we have previously seen and processed. treeset SeenBlocks; @@ -397,6 +398,10 @@ // allocation would change with -g, and users dislike that. void switchLexicalBlock(tree_node *exp); + /// StartFunctionBody - Start the emission of 'FnDecl', outputing all + /// declarations for parameters and setting things up. + void StartFunctionBody(); + private: // Helper functions. // Walk over the lexical BLOCK() tree of the given FUNCTION_DECL; @@ -405,10 +410,6 @@ // the given set. void setLexicalBlockDepths(tree_node *t, treeset &s, unsigned level); - /// StartFunctionBody - Start the emission of 'fndecl', outputing all - /// declarations for parameters and setting things up. - void StartFunctionBody(); - /// FinishFunctionBody - Once the body of the function has been emitted, this /// cleans up and returns the result function. Function *FinishFunctionBody(); @@ -608,6 +609,9 @@ Constant *EmitLV_LABEL_DECL(tree_node *exp); }; +/// TheTreeToLLVM - Keep track of the current function being compiled. +extern TreeToLLVM *TheTreeToLLVM; + /// TreeConstantToLLVM - An instance of this class is created and used to /// convert tree constant values to LLVM. This is primarily for things like /// global variable initializers. From gohman at apple.com Thu May 27 11:19:40 2010 From: gohman at apple.com (Dan Gohman) Date: Thu, 27 May 2010 16:19:40 -0000 Subject: [llvm-commits] [test-suite] r104843 - /test-suite/trunk/MultiSource/Benchmarks/Bullet/ Message-ID: <20100527161940.B7C6B312800A@llvm.org> Author: djg Date: Thu May 27 11:19:40 2010 New Revision: 104843 URL: http://llvm.org/viewvc/llvm-project?rev=104843&view=rev Log: Add an svn:ignore. Modified: test-suite/trunk/MultiSource/Benchmarks/Bullet/ (props changed) Propchange: test-suite/trunk/MultiSource/Benchmarks/Bullet/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Thu May 27 11:19:40 2010 @@ -0,0 +1 @@ +Output From gohman at apple.com Thu May 27 11:21:26 2010 From: gohman at apple.com (Dan Gohman) Date: Thu, 27 May 2010 16:21:26 -0000 Subject: [llvm-commits] [test-suite] r104844 - /test-suite/trunk/SingleSource/Benchmarks/Adobe-C++/ Message-ID: <20100527162126.63BE3312800A@llvm.org> Author: djg Date: Thu May 27 11:21:26 2010 New Revision: 104844 URL: http://llvm.org/viewvc/llvm-project?rev=104844&view=rev Log: Delete a spurious svn:mergeinfo property. Modified: test-suite/trunk/SingleSource/Benchmarks/Adobe-C++/ (props changed) Propchange: test-suite/trunk/SingleSource/Benchmarks/Adobe-C++/ ------------------------------------------------------------------------------ (empty) From gohman at apple.com Thu May 27 11:25:05 2010 From: gohman at apple.com (Dan Gohman) Date: Thu, 27 May 2010 16:25:05 -0000 Subject: [llvm-commits] [llvm] r104845 - /llvm/trunk/utils/TableGen/FastISelEmitter.cpp Message-ID: <20100527162505.ABC89312800A@llvm.org> Author: djg Date: Thu May 27 11:25:05 2010 New Revision: 104845 URL: http://llvm.org/viewvc/llvm-project?rev=104845&view=rev Log: Minor code simplification. Modified: llvm/trunk/utils/TableGen/FastISelEmitter.cpp Modified: llvm/trunk/utils/TableGen/FastISelEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/FastISelEmitter.cpp?rev=104845&r1=104844&r2=104845&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/FastISelEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/FastISelEmitter.cpp Thu May 27 11:25:05 2010 @@ -54,15 +54,15 @@ bool initialize(TreePatternNode *InstPatNode, const CodeGenTarget &Target, MVT::SimpleValueType VT) { - if (!InstPatNode->isLeaf() && - InstPatNode->getOperator()->getName() == "imm") { - Operands.push_back("i"); - return true; - } - if (!InstPatNode->isLeaf() && - InstPatNode->getOperator()->getName() == "fpimm") { - Operands.push_back("f"); - return true; + if (!InstPatNode->isLeaf()) { + if (InstPatNode->getOperator()->getName() == "imm") { + Operands.push_back("i"); + return true; + } + if (InstPatNode->getOperator()->getName() == "fpimm") { + Operands.push_back("f"); + return true; + } } const CodeGenRegisterClass *DstRC = 0; From dpatel at apple.com Thu May 27 11:47:30 2010 From: dpatel at apple.com (Devang Patel) Date: Thu, 27 May 2010 16:47:30 -0000 Subject: [llvm-commits] [llvm] r104848 - in /llvm/trunk: lib/CodeGen/AsmPrinter/DwarfDebug.cpp test/DebugInfo/2010-05-28-Crash.ll Message-ID: <20100527164730.3B51D312800A@llvm.org> Author: dpatel Date: Thu May 27 11:47:30 2010 New Revision: 104848 URL: http://llvm.org/viewvc/llvm-project?rev=104848&view=rev Log: inlined function's arguments need a label to mark the start point because they are not directly attached to current function. Added: llvm/trunk/test/DebugInfo/2010-05-28-Crash.ll Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=104848&r1=104847&r2=104848&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Thu May 27 11:47:30 2010 @@ -2635,13 +2635,16 @@ const MachineInstr *MI = II; DebugLoc DL = MI->getDebugLoc(); if (MI->isDebugValue()) { - // DBG_VALUE needs a label if the variable is local variable or - // an argument whose location is changing. assert (MI->getNumOperands() > 1 && "Invalid machine instruction!"); DIVariable DV(MI->getOperand(MI->getNumOperands() - 1).getMetadata()); if (!DV.Verify()) continue; + // If DBG_VALUE is for a local variable then it needs a label. if (DV.getTag() != dwarf::DW_TAG_arg_variable) InsnNeedsLabel.insert(MI); + // DBG_VALUE for inlined functions argument needs a label. + else if (!DISubprogram(DV.getContext()).describes(MF->getFunction())) + InsnNeedsLabel.insert(MI); + // DBG_VALUE indicating argument location change needs a label. else if (!ProcessedArgs.insert(DV)) InsnNeedsLabel.insert(MI); } else { Added: llvm/trunk/test/DebugInfo/2010-05-28-Crash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/2010-05-28-Crash.ll?rev=104848&view=auto ============================================================================== --- llvm/trunk/test/DebugInfo/2010-05-28-Crash.ll (added) +++ llvm/trunk/test/DebugInfo/2010-05-28-Crash.ll Thu May 27 11:47:30 2010 @@ -0,0 +1,49 @@ +; RUN: llc < %s | FileCheck %s +; Test to check separate label for inlined function argument. +define void @bar(double %x) nounwind { +entry: + %__x_addr.i = alloca double ; [#uses=2] + %retval.i = alloca i32 ; [#uses=2] + %0 = alloca i32 ; [#uses=2] + %x_addr = alloca double ; [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + call void @llvm.dbg.declare(metadata !{double* %x_addr}, metadata !0), !dbg !7 + store double %x, double* %x_addr + %1 = load double* %x_addr, align 8, !dbg !8 ; [#uses=1] + call void @llvm.dbg.declare(metadata !{double* %__x_addr.i}, metadata !10), !dbg !15 + store double %1, double* %__x_addr.i + %2 = load double* %__x_addr.i, align 8, !dbg !15 ; [#uses=1] + %3 = fptosi double %2 to i32, !dbg !15 ; [#uses=1] + store i32 %3, i32* %0, align 4, !dbg !15 + %4 = load i32* %0, align 4, !dbg !15 ; [#uses=1] + store i32 %4, i32* %retval.i, align 4, !dbg !15 + %retval1.i = load i32* %retval.i, !dbg !15 ; [#uses=0] + br label %return, !dbg !16 + +return: ; preds = %entry + ret void, !dbg !16 +} + +declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone + +!0 = metadata !{i32 524545, metadata !1, metadata !"x", metadata !2, i32 7, metadata !6} ; [ DW_TAG_arg_variable ] +!1 = metadata !{i32 524334, i32 0, metadata !2, metadata !"bar", metadata !"bar", metadata !"bar", metadata !2, i32 7, metadata !4, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false} ; [ DW_TAG_subprogram ] +!2 = metadata !{i32 524329, metadata !"2010-01-18-Inlined-Debug.c", metadata !"/Users/buildslave/zorg/buildbot/smooshlab/slave/build.llvm-gcc-powerpc-darwin9/llvm.src/test/FrontendC", metadata !3} ; [ DW_TAG_file_type ] +!3 = metadata !{i32 524305, i32 0, i32 1, metadata !"2010-01-18-Inlined-Debug.c", metadata !"/Users/buildslave/zorg/buildbot/smooshlab/slave/build.llvm-gcc-powerpc-darwin9/llvm.src/test/FrontendC", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] +!4 = metadata !{i32 524309, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !5, i32 0, null} ; [ DW_TAG_subroutine_type ] +!5 = metadata !{null, metadata !6} +!6 = metadata !{i32 524324, metadata !2, metadata !"double", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ] +!7 = metadata !{i32 7, i32 0, metadata !1, null} +!8 = metadata !{i32 8, i32 0, metadata !9, null} +!9 = metadata !{i32 524299, metadata !1, i32 7, i32 0} ; [ DW_TAG_lexical_block ] +!10 = metadata !{i32 524545, metadata !11, metadata !"__x", metadata !2, i32 5, metadata !6} ; [ DW_TAG_arg_variable ] +!11 = metadata !{i32 524334, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"foo", metadata !2, i32 5, metadata !12, i1 true, i1 true, i32 0, i32 0, null, i1 false, i1 false} ; [ DW_TAG_subprogram ] +!12 = metadata !{i32 524309, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !13, i32 0, null} ; [ DW_TAG_subroutine_type ] +!13 = metadata !{metadata !14, metadata !6} +!14 = metadata !{i32 524324, metadata !2, metadata !"int", metadata !2, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!15 = metadata !{i32 5, i32 0, metadata !11, metadata !8} +!16 = metadata !{i32 9, i32 0, metadata !9, null} + +;CHECK: ##DEBUG_VALUE: bar:x +;CHECK-NEXT:Ltmp1: +;CHECK-NEXT ##DEBUG_VALUE: foo:__x From dimitry at andric.com Thu May 27 04:58:48 2010 From: dimitry at andric.com (Dimitry Andric) Date: Thu, 27 May 2010 11:58:48 +0200 Subject: [llvm-commits] [llvm] r104831 - in /llvm/trunk/test/Other: 2010-05-06-Printer.ll 2010-05-60-Printer.ll In-Reply-To: <20100527093238.C2E6C312800A@llvm.org> References: <20100527093238.C2E6C312800A@llvm.org> Message-ID: <4BFE4258.7040206@andric.com> On 2010-05-27 11:32, Gabor Greif wrote: > Author: ggreif > Date: Thu May 27 04:32:38 2010 > New Revision: 104831 > > URL: http://llvm.org/viewvc/llvm-project?rev=104831&view=rev > Log: > rename test to represent meaningful date ... > -; RUN: llc -O2 -print-after-all < %s 2>&1 Btw, this test also leaves a test/Other/&1 file, at least on my FreeBSD test system. Is that a lit issue, or could this ll script be modified to fix it? From gohman at apple.com Thu May 27 12:12:23 2010 From: gohman at apple.com (Dan Gohman) Date: Thu, 27 May 2010 17:12:23 -0000 Subject: [llvm-commits] [llvm] r104851 - /llvm/trunk/lib/System/Path.cpp Message-ID: <20100527171223.40603312800A@llvm.org> Author: djg Date: Thu May 27 12:12:23 2010 New Revision: 104851 URL: http://llvm.org/viewvc/llvm-project?rev=104851&view=rev Log: Don't bother checking canRead() before calling getMagicNumber(); getMagicNumber() does its own error checking. Modified: llvm/trunk/lib/System/Path.cpp Modified: llvm/trunk/lib/System/Path.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/System/Path.cpp?rev=104851&r1=104850&r2=104851&view=diff ============================================================================== --- llvm/trunk/lib/System/Path.cpp (original) +++ llvm/trunk/lib/System/Path.cpp Thu May 27 12:12:23 2010 @@ -136,26 +136,23 @@ bool Path::isArchive() const { - if (canRead()) - return hasMagicNumber("!\012"); - return false; + return hasMagicNumber("!\012"); } bool Path::isDynamicLibrary() const { - if (canRead()) { - std::string Magic; - if (getMagicNumber(Magic, 64)) - switch (IdentifyFileType(Magic.c_str(), - static_cast(Magic.length()))) { - default: return false; - case Mach_O_FixedVirtualMemorySharedLib_FileType: - case Mach_O_DynamicallyLinkedSharedLib_FileType: - case Mach_O_DynamicallyLinkedSharedLibStub_FileType: - case ELF_SharedObject_FileType: - case COFF_FileType: return true; - } - } + std::string Magic; + if (getMagicNumber(Magic, 64)) + switch (IdentifyFileType(Magic.c_str(), + static_cast(Magic.length()))) { + default: return false; + case Mach_O_FixedVirtualMemorySharedLib_FileType: + case Mach_O_DynamicallyLinkedSharedLib_FileType: + case Mach_O_DynamicallyLinkedSharedLibStub_FileType: + case ELF_SharedObject_FileType: + case COFF_FileType: return true; + } + return false; } From gohman at apple.com Thu May 27 12:14:10 2010 From: gohman at apple.com (Dan Gohman) Date: Thu, 27 May 2010 17:14:10 -0000 Subject: [llvm-commits] [llvm] r104852 - /llvm/trunk/lib/System/Unix/Path.inc Message-ID: <20100527171410.A5A36312800A@llvm.org> Author: djg Date: Thu May 27 12:14:10 2010 New Revision: 104852 URL: http://llvm.org/viewvc/llvm-project?rev=104852&view=rev Log: Don't bother clearing the Magic string when the magic number can't be read, since it isn't cleared on other error paths. Modified: llvm/trunk/lib/System/Unix/Path.inc Modified: llvm/trunk/lib/System/Unix/Path.inc URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/System/Unix/Path.inc?rev=104852&r1=104851&r2=104852&view=diff ============================================================================== --- llvm/trunk/lib/System/Unix/Path.inc (original) +++ llvm/trunk/lib/System/Unix/Path.inc Thu May 27 12:14:10 2010 @@ -421,10 +421,8 @@ return false; ssize_t bytes_read = ::read(fd, Buf, len); ::close(fd); - if (ssize_t(len) != bytes_read) { - Magic.clear(); + if (ssize_t(len) != bytes_read) return false; - } Magic.assign(Buf, len); return true; } From gohman at apple.com Thu May 27 12:18:38 2010 From: gohman at apple.com (Dan Gohman) Date: Thu, 27 May 2010 17:18:38 -0000 Subject: [llvm-commits] [llvm] r104853 - /llvm/trunk/lib/Linker/LinkItems.cpp Message-ID: <20100527171838.98B6D312800A@llvm.org> Author: djg Date: Thu May 27 12:18:38 2010 New Revision: 104853 URL: http://llvm.org/viewvc/llvm-project?rev=104853&view=rev Log: Use the return value of getMagicNumber instead of using a separate canRead() call. Modified: llvm/trunk/lib/Linker/LinkItems.cpp Modified: llvm/trunk/lib/Linker/LinkItems.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkItems.cpp?rev=104853&r1=104852&r2=104853&view=diff ============================================================================== --- llvm/trunk/lib/Linker/LinkItems.cpp (original) +++ llvm/trunk/lib/Linker/LinkItems.cpp Thu May 27 12:18:38 2010 @@ -174,13 +174,11 @@ return error("Cannot link stdin: " + Error); } - // Make sure we can at least read the file - if (!File.canRead()) + // Determine what variety of file it is. + std::string Magic; + if (!File.getMagicNumber(Magic, 64)) return error("Cannot find linker input '" + File.str() + "'"); - // If its an archive, try to link it in - std::string Magic; - File.getMagicNumber(Magic, 64); switch (sys::IdentifyFileType(Magic.c_str(), 64)) { default: llvm_unreachable("Bad file type identification"); case sys::Unknown_FileType: From gohman at apple.com Thu May 27 12:31:51 2010 From: gohman at apple.com (Dan Gohman) Date: Thu, 27 May 2010 17:31:51 -0000 Subject: [llvm-commits] [llvm] r104855 - in /llvm/trunk: include/llvm/Support/MemoryBuffer.h lib/Linker/LinkItems.cpp lib/Support/MemoryBuffer.cpp lib/VMCore/Core.cpp Message-ID: <20100527173151.A8E87312800A@llvm.org> Author: djg Date: Thu May 27 12:31:51 2010 New Revision: 104855 URL: http://llvm.org/viewvc/llvm-project?rev=104855&view=rev Log: Add basic error checking to MemoryBuffer::getSTDIN. Modified: llvm/trunk/include/llvm/Support/MemoryBuffer.h llvm/trunk/lib/Linker/LinkItems.cpp llvm/trunk/lib/Support/MemoryBuffer.cpp llvm/trunk/lib/VMCore/Core.cpp Modified: llvm/trunk/include/llvm/Support/MemoryBuffer.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/MemoryBuffer.h?rev=104855&r1=104854&r2=104855&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/MemoryBuffer.h (original) +++ llvm/trunk/include/llvm/Support/MemoryBuffer.h Thu May 27 12:31:51 2010 @@ -89,7 +89,8 @@ StringRef BufferName = ""); /// getSTDIN - Read all of stdin into a file buffer, and return it. - static MemoryBuffer *getSTDIN(); + /// If an error occurs, this returns null and fills in *ErrStr with a reason. + static MemoryBuffer *getSTDIN(std::string *ErrStr = 0); /// getFileOrSTDIN - Open the specified file as a MemoryBuffer, or open stdin Modified: llvm/trunk/lib/Linker/LinkItems.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkItems.cpp?rev=104855&r1=104854&r2=104855&view=diff ============================================================================== --- llvm/trunk/lib/Linker/LinkItems.cpp (original) +++ llvm/trunk/lib/Linker/LinkItems.cpp Thu May 27 12:31:51 2010 @@ -160,16 +160,17 @@ // Check for a file of name "-", which means "read standard input" if (File.str() == "-") { std::auto_ptr M; - MemoryBuffer *Buffer = MemoryBuffer::getSTDIN(); - if (!Buffer->getBufferSize()) { - delete Buffer; - Error = "standard input is empty"; - } else { - M.reset(ParseBitcodeFile(Buffer, Context, &Error)); - delete Buffer; - if (M.get()) - if (!LinkInModule(M.get(), &Error)) - return false; + if (MemoryBuffer *Buffer = MemoryBuffer::getSTDIN(&Error)) { + if (!Buffer->getBufferSize()) { + delete Buffer; + Error = "standard input is empty"; + } else { + M.reset(ParseBitcodeFile(Buffer, Context, &Error)); + delete Buffer; + if (M.get()) + if (!LinkInModule(M.get(), &Error)) + return false; + } } return error("Cannot link stdin: " + Error); } Modified: llvm/trunk/lib/Support/MemoryBuffer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/MemoryBuffer.cpp?rev=104855&r1=104854&r2=104855&view=diff ============================================================================== --- llvm/trunk/lib/Support/MemoryBuffer.cpp (original) +++ llvm/trunk/lib/Support/MemoryBuffer.cpp Thu May 27 12:31:51 2010 @@ -137,7 +137,7 @@ int64_t FileSize, struct stat *FileInfo) { if (Filename == "-") - return getSTDIN(); + return getSTDIN(ErrStr); return getFile(Filename, ErrStr, FileSize, FileInfo); } @@ -263,7 +263,7 @@ }; } -MemoryBuffer *MemoryBuffer::getSTDIN() { +MemoryBuffer *MemoryBuffer::getSTDIN(std::string *ErrStr) { char Buffer[4096*4]; std::vector FileData; @@ -279,6 +279,11 @@ FileData.insert(FileData.end(), Buffer, Buffer+ReadBytes); } while (ReadBytes == sizeof(Buffer)); + if (!feof(stdin)) { + if (ErrStr) *ErrStr = "error reading from stdin"; + return 0; + } + FileData.push_back(0); // &FileData[Size] is invalid. So is &*FileData.end(). size_t Size = FileData.size(); MemoryBuffer *B = new STDINBufferFile(); Modified: llvm/trunk/lib/VMCore/Core.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Core.cpp?rev=104855&r1=104854&r2=104855&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Core.cpp (original) +++ llvm/trunk/lib/VMCore/Core.cpp Thu May 27 12:31:51 2010 @@ -2205,15 +2205,14 @@ LLVMBool LLVMCreateMemoryBufferWithSTDIN(LLVMMemoryBufferRef *OutMemBuf, char **OutMessage) { - MemoryBuffer *MB = MemoryBuffer::getSTDIN(); - if (!MB->getBufferSize()) { - delete MB; - *OutMessage = strdup("stdin is empty."); - return 1; + std::string Error; + if (MemoryBuffer *MB = MemoryBuffer::getSTDIN(&Error)) { + *OutMemBuf = wrap(MB); + return 0; } - *OutMemBuf = wrap(MB); - return 0; + *OutMessage = strdup(Error.c_str()); + return 1; } void LLVMDisposeMemoryBuffer(LLVMMemoryBufferRef MemBuf) { From daniel at zuster.org Thu May 27 12:48:06 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Thu, 27 May 2010 17:48:06 -0000 Subject: [llvm-commits] [zorg] r104857 - in /zorg/trunk/lnt/lnt: lnttool/__init__.py tests/nt.py Message-ID: <20100527174806.77BF4312800A@llvm.org> Author: ddunbar Date: Thu May 27 12:48:06 2010 New Revision: 104857 URL: http://llvm.org/viewvc/llvm-project?rev=104857&view=rev Log: LNT/runtest nt: Add --disable-fp-elim and --disable-lto options. Modified: zorg/trunk/lnt/lnt/lnttool/__init__.py zorg/trunk/lnt/lnt/tests/nt.py Modified: zorg/trunk/lnt/lnt/lnttool/__init__.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/lnttool/__init__.py?rev=104857&r1=104856&r2=104857&view=diff ============================================================================== --- zorg/trunk/lnt/lnt/lnttool/__init__.py (original) +++ zorg/trunk/lnt/lnt/lnttool/__init__.py Thu May 27 12:48:06 2010 @@ -184,3 +184,6 @@ cmd = sys.argv[1] commands[cmd](cmd, sys.argv[2:]) + +if __name__ == '__main__': + main() Modified: zorg/trunk/lnt/lnt/tests/nt.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/tests/nt.py?rev=104857&r1=104856&r2=104857&view=diff ============================================================================== --- zorg/trunk/lnt/lnt/tests/nt.py (original) +++ zorg/trunk/lnt/lnt/tests/nt.py Thu May 27 12:48:06 2010 @@ -37,6 +37,8 @@ if opts.relocation_model is not None: target_llcflags.append('-relocation-model') target_llcflags.append(opts.relocation_model) + if opts.disable_fp_elim: + target_llcflags.append('-disable-fp-elim') # Set the make variables to use. make_variables = { @@ -60,6 +62,8 @@ make_variables['DISABLE_JIT'] = '1' if not opts.test_llc: make_variables['DISABLE_LLC'] = '1' + if not opts.test_lto: + make_variables['DISABLE_LTO'] = '1' if opts.test_llcbeta: make_variables['ENABLE_LLCBETA'] = '1' if opts.test_small: @@ -432,6 +436,9 @@ help=("Set -relocation-model in TARGET_LLCFLAGS " "[%default]"), type="str", default=None, metavar="MODEL") + group.add_option("", "--disable-fp-elim", dest="disable_fp_elim", + help=("Set -disable-fp-elim in TARGET_LLCFLAGS"), + action="store_true", default=False) group.add_option("", "--cflag", dest="cflags", help="Additional flags to set in TARGET_FLAGS", @@ -461,6 +468,9 @@ group.add_option("", "--enable-llcbeta", dest="test_llcbeta", help="Enable LLCBETA tests", action="store_true", default=False) + group.add_option("", "--disable-lto", dest="test_lto", + help="Disable use of link-time optimization", + action="store_false", default=True) group.add_option("", "--small", dest="test_small", help="Use smaller test inputs and disable large tests", From dpatel at apple.com Thu May 27 12:51:08 2010 From: dpatel at apple.com (Devang Patel) Date: Thu, 27 May 2010 17:51:08 -0000 Subject: [llvm-commits] [llvm] r104858 - /llvm/trunk/test/DebugInfo/2010-05-28-Crash.ll Message-ID: <20100527175108.3BE96312800A@llvm.org> Author: dpatel Date: Thu May 27 12:51:08 2010 New Revision: 104858 URL: http://llvm.org/viewvc/llvm-project?rev=104858&view=rev Log: Temp. labels number may not match for all configurations. Modified: llvm/trunk/test/DebugInfo/2010-05-28-Crash.ll Modified: llvm/trunk/test/DebugInfo/2010-05-28-Crash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/2010-05-28-Crash.ll?rev=104858&r1=104857&r2=104858&view=diff ============================================================================== --- llvm/trunk/test/DebugInfo/2010-05-28-Crash.ll (original) +++ llvm/trunk/test/DebugInfo/2010-05-28-Crash.ll Thu May 27 12:51:08 2010 @@ -45,5 +45,5 @@ !16 = metadata !{i32 9, i32 0, metadata !9, null} ;CHECK: ##DEBUG_VALUE: bar:x -;CHECK-NEXT:Ltmp1: +;CHECK-NEXT:Ltmp ;CHECK-NEXT ##DEBUG_VALUE: foo:__x From bruno.cardoso at gmail.com Thu May 27 13:17:40 2010 From: bruno.cardoso at gmail.com (Bruno Cardoso Lopes) Date: Thu, 27 May 2010 18:17:40 -0000 Subject: [llvm-commits] [llvm] r104860 - /llvm/trunk/lib/Target/X86/X86InstrSSE.td Message-ID: <20100527181740.CDD99312800A@llvm.org> Author: bruno Date: Thu May 27 13:17:40 2010 New Revision: 104860 URL: http://llvm.org/viewvc/llvm-project?rev=104860&view=rev Log: Merge basic binops SSE 1 & 2 instruction classes. This is a step towards refactoring common code between SSE versions. Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=104860&r1=104859&r2=104860&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Thu May 27 13:17:40 2010 @@ -642,7 +642,8 @@ } } -/// basic_sse1_fp_binop_rm - SSE1 binops come in both scalar and vector forms. +/// basic_sse12_fp_binop_rm - SSE 1 & 2 binops come in both scalar and +/// vector forms. /// /// In addition, we also have a special variant of the scalar form here to /// represent the associated intrinsic operation. This form is unlike the @@ -653,9 +654,8 @@ /// six "instructions". /// let Constraints = "$src1 = $dst" in { -multiclass basic_sse1_fp_binop_rm opc, string OpcodeStr, - SDNode OpNode, Intrinsic F32Int, - bit Commutable = 0> { +multiclass basic_sse12_fp_binop_rm opc, string OpcodeStr, + SDNode OpNode, bit Commutable = 0> { // Scalar operation, reg+reg. def SSrr : SSI { + let isCommutable = Commutable; + } + // Scalar operation, reg+mem. def SSrm : SSI; + def SDrm : SDI; + // Vector operation, reg+reg. def PSrr : PSI { + let isCommutable = Commutable; + } + // Vector operation, reg+mem. def PSrm : PSI; + def PDrm : PDI; + // Intrinsic operation, reg+reg. def SSrr_Int : SSI; + !strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"), + [(set VR128:$dst, (!nameconcat("int_x86_sse_", + !strconcat(OpcodeStr, "_ss")) VR128:$src1, + VR128:$src2))]>; + // int_x86_sse_xxx_ss + + def SDrr_Int : SDI("int_x86_sse2_", + !strconcat(OpcodeStr, "_sd")) VR128:$src1, + VR128:$src2))]>; + // int_x86_sse2_xxx_sd // Intrinsic operation, reg+mem. def SSrm_Int : SSI("int_x86_sse_", + !strconcat(OpcodeStr, "_ss")) VR128:$src1, sse_load_f32:$src2))]>; + // int_x86_sse_xxx_ss + + def SDrm_Int : SDI("int_x86_sse2_", + !strconcat(OpcodeStr, "_sd")) VR128:$src1, + sse_load_f64:$src2))]>; + // int_x86_sse2_xxx_sd } } // Arithmetic instructions -defm ADD : basic_sse1_fp_binop_rm<0x58, "add", fadd, int_x86_sse_add_ss, 1>; -defm MUL : basic_sse1_fp_binop_rm<0x59, "mul", fmul, int_x86_sse_mul_ss, 1>; -defm SUB : basic_sse1_fp_binop_rm<0x5C, "sub", fsub, int_x86_sse_sub_ss>; -defm DIV : basic_sse1_fp_binop_rm<0x5E, "div", fdiv, int_x86_sse_div_ss>; +defm ADD : basic_sse12_fp_binop_rm<0x58, "add", fadd, 1>; +defm MUL : basic_sse12_fp_binop_rm<0x59, "mul", fmul, 1>; +defm SUB : basic_sse12_fp_binop_rm<0x5C, "sub", fsub>; +defm DIV : basic_sse12_fp_binop_rm<0x5E, "div", fdiv>; -/// sse1_fp_binop_rm - Other SSE1 binops +/// sse12_fp_binop_rm - Other SSE 1 & 2 binops /// -/// This multiclass is like basic_sse1_fp_binop_rm, with the addition of +/// This multiclass is like basic_sse12_fp_binop_rm, with the addition of /// instructions for a full-vector intrinsic form. Operations that map /// onto C operators don't use this form since they just use the plain /// vector form instead of having a separate vector intrinsic form. @@ -714,11 +758,8 @@ /// This provides a total of eight "instructions". /// let Constraints = "$src1 = $dst" in { -multiclass sse1_fp_binop_rm opc, string OpcodeStr, - SDNode OpNode, - Intrinsic F32Int, - Intrinsic V4F32Int, - bit Commutable = 0> { +multiclass sse12_fp_binop_rm opc, string OpcodeStr, + SDNode OpNode, bit Commutable = 0> { // Scalar operation, reg+reg. def SSrr : SSI { + let isCommutable = Commutable; + } + // Scalar operation, reg+mem. def SSrm : SSI; + def SDrm : SDI; + // Vector operation, reg+reg. def PSrr : PSI { + let isCommutable = Commutable; + } + // Vector operation, reg+mem. def PSrm : PSI; + def PDrm : PDI; + // Intrinsic operation, reg+reg. def SSrr_Int : SSI { + !strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"), + [(set VR128:$dst, (!nameconcat("int_x86_sse_", + !strconcat(OpcodeStr, "_ss")) VR128:$src1, + VR128:$src2))]> { + // int_x86_sse_xxx_ss + let isCommutable = Commutable; + } + + def SDrr_Int : SDI("int_x86_sse2_", + !strconcat(OpcodeStr, "_sd")) VR128:$src1, + VR128:$src2))]> { + // int_x86_sse2_xxx_sd let isCommutable = Commutable; } // Intrinsic operation, reg+mem. def SSrm_Int : SSI("int_x86_sse_", + !strconcat(OpcodeStr, "_ss")) VR128:$src1, sse_load_f32:$src2))]>; + // int_x86_sse_xxx_ss + + def SDrm_Int : SDI("int_x86_sse2_", + !strconcat(OpcodeStr, "_sd")) VR128:$src1, + sse_load_f64:$src2))]>; + // int_x86_sse2_xxx_sd // Vector intrinsic operation, reg+reg. def PSrr_Int : PSI { + !strconcat(OpcodeStr, "ps\t{$src2, $dst|$dst, $src2}"), + [(set VR128:$dst, (!nameconcat("int_x86_sse_", + !strconcat(OpcodeStr, "_ps")) VR128:$src1, + VR128:$src2))]> { + // int_x86_sse_xxx_ps + let isCommutable = Commutable; + } + + def PDrr_Int : PDI("int_x86_sse2_", + !strconcat(OpcodeStr, "_pd")) VR128:$src1, + VR128:$src2))]> { + // int_x86_sse2_xxx_pd let isCommutable = Commutable; } // Vector intrinsic operation, reg+mem. def PSrm_Int : PSI; + !strconcat(OpcodeStr, "ps\t{$src2, $dst|$dst, $src2}"), + [(set VR128:$dst, (!nameconcat("int_x86_sse_", + !strconcat(OpcodeStr, "_ps")) VR128:$src1, + (memopv4f32 addr:$src2)))]>; + // int_x86_sse_xxx_ps + + def PDrm_Int : PDI("int_x86_sse2_", + !strconcat(OpcodeStr, "_pd")) VR128:$src1, + (memopv2f64 addr:$src2)))]>; + // int_x86_sse2_xxx_pd } } -defm MAX : sse1_fp_binop_rm<0x5F, "max", X86fmax, - int_x86_sse_max_ss, int_x86_sse_max_ps>; -defm MIN : sse1_fp_binop_rm<0x5D, "min", X86fmin, - int_x86_sse_min_ss, int_x86_sse_min_ps>; +defm MAX : sse12_fp_binop_rm<0x5F, "max", X86fmax>; +defm MIN : sse12_fp_binop_rm<0x5D, "min", X86fmin>; //===----------------------------------------------------------------------===// // SSE packed FP Instructions @@ -1444,148 +1553,6 @@ } } -/// basic_sse2_fp_binop_rm - SSE2 binops come in both scalar and vector forms. -/// -/// In addition, we also have a special variant of the scalar form here to -/// represent the associated intrinsic operation. This form is unlike the -/// plain scalar form, in that it takes an entire vector (instead of a scalar) -/// and leaves the top elements unmodified (therefore these cannot be commuted). -/// -/// These three forms can each be reg+reg or reg+mem, so there are a total of -/// six "instructions". -/// -let Constraints = "$src1 = $dst" in { -multiclass basic_sse2_fp_binop_rm opc, string OpcodeStr, - SDNode OpNode, Intrinsic F64Int, - bit Commutable = 0> { - // Scalar operation, reg+reg. - def SDrr : SDI { - let isCommutable = Commutable; - } - - // Scalar operation, reg+mem. - def SDrm : SDI; - - // Vector operation, reg+reg. - def PDrr : PDI { - let isCommutable = Commutable; - } - - // Vector operation, reg+mem. - def PDrm : PDI; - - // Intrinsic operation, reg+reg. - def SDrr_Int : SDI; - - // Intrinsic operation, reg+mem. - def SDrm_Int : SDI; -} -} - -// Arithmetic instructions -defm ADD : basic_sse2_fp_binop_rm<0x58, "add", fadd, int_x86_sse2_add_sd, 1>; -defm MUL : basic_sse2_fp_binop_rm<0x59, "mul", fmul, int_x86_sse2_mul_sd, 1>; -defm SUB : basic_sse2_fp_binop_rm<0x5C, "sub", fsub, int_x86_sse2_sub_sd>; -defm DIV : basic_sse2_fp_binop_rm<0x5E, "div", fdiv, int_x86_sse2_div_sd>; - -/// sse2_fp_binop_rm - Other SSE2 binops -/// -/// This multiclass is like basic_sse2_fp_binop_rm, with the addition of -/// instructions for a full-vector intrinsic form. Operations that map -/// onto C operators don't use this form since they just use the plain -/// vector form instead of having a separate vector intrinsic form. -/// -/// This provides a total of eight "instructions". -/// -let Constraints = "$src1 = $dst" in { -multiclass sse2_fp_binop_rm opc, string OpcodeStr, - SDNode OpNode, - Intrinsic F64Int, - Intrinsic V2F64Int, - bit Commutable = 0> { - - // Scalar operation, reg+reg. - def SDrr : SDI { - let isCommutable = Commutable; - } - - // Scalar operation, reg+mem. - def SDrm : SDI; - - // Vector operation, reg+reg. - def PDrr : PDI { - let isCommutable = Commutable; - } - - // Vector operation, reg+mem. - def PDrm : PDI; - - // Intrinsic operation, reg+reg. - def SDrr_Int : SDI { - let isCommutable = Commutable; - } - - // Intrinsic operation, reg+mem. - def SDrm_Int : SDI; - - // Vector intrinsic operation, reg+reg. - def PDrr_Int : PDI { - let isCommutable = Commutable; - } - - // Vector intrinsic operation, reg+mem. - def PDrm_Int : PDI; -} -} - -defm MAX : sse2_fp_binop_rm<0x5F, "max", X86fmax, - int_x86_sse2_max_sd, int_x86_sse2_max_pd>; -defm MIN : sse2_fp_binop_rm<0x5D, "min", X86fmin, - int_x86_sse2_min_sd, int_x86_sse2_min_pd>; - //===---------------------------------------------------------------------===// // SSE packed FP Instructions From grosbach at apple.com Thu May 27 13:23:48 2010 From: grosbach at apple.com (Jim Grosbach) Date: Thu, 27 May 2010 18:23:48 -0000 Subject: [llvm-commits] [llvm] r104862 - in /llvm/trunk: include/llvm/CodeGen/ISDOpcodes.h lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMISelLowering.h Message-ID: <20100527182348.A67F3312800A@llvm.org> Author: grosbach Date: Thu May 27 13:23:48 2010 New Revision: 104862 URL: http://llvm.org/viewvc/llvm-project?rev=104862&view=rev Log: add ISD::STACKADDR to get the current stack pointer. Will be used by sjlj EH to update the jmpbuf in the presence of VLAs. Modified: llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.h Modified: llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h?rev=104862&r1=104861&r2=104862&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h (original) +++ llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h Thu May 27 13:23:48 2010 @@ -72,6 +72,9 @@ // parent's frame or return address, and so on. FRAMEADDR, RETURNADDR, + // STACKADDR - The current stack pointer address. + STACKADDR, + // FRAME_TO_ARGS_OFFSET - This node represents offset from frame pointer to // first (possible) on-stack argument. This is needed for correct stack // adjustment during unwind. Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=104862&r1=104861&r2=104862&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Thu May 27 13:23:48 2010 @@ -2183,6 +2183,13 @@ return FrameAddr; } +SDValue ARMTargetLowering::LowerSTACKADDR(SDValue Op, SelectionDAG &DAG) const { + EVT VT = Op.getValueType(); + DebugLoc dl = Op.getDebugLoc(); // FIXME probably not meaningful + SDValue StackAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, ARM::SP, VT); + return StackAddr; +} + /// ExpandBIT_CONVERT - If the target supports VFP, this function is called to /// expand a bit convert where either the source or destination type is i64 to /// use a VMOVDRR or VMOVRRD node. This should not be done when the non-i64 @@ -3187,6 +3194,7 @@ case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG); case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG); case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); + case ISD::STACKADDR: return LowerSTACKADDR(Op, DAG); case ISD::GLOBAL_OFFSET_TABLE: return LowerGLOBAL_OFFSET_TABLE(Op, DAG); case ISD::EH_SJLJ_SETJMP: return LowerEH_SJLJ_SETJMP(Op, DAG); case ISD::EH_SJLJ_LONGJMP: return LowerEH_SJLJ_LONGJMP(Op, DAG); Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=104862&r1=104861&r2=104862&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Thu May 27 13:23:48 2010 @@ -305,6 +305,7 @@ SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const; SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const; SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerSTACKADDR(SDValue Op, SelectionDAG &DAG) const; SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const; SDValue LowerShiftRightParts(SDValue Op, SelectionDAG &DAG) const; SDValue LowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const; From gohman at apple.com Thu May 27 13:43:40 2010 From: gohman at apple.com (Dan Gohman) Date: Thu, 27 May 2010 18:43:40 -0000 Subject: [llvm-commits] [llvm] r104866 - in /llvm/trunk/lib/Target/X86: X86FastISel.cpp X86ISelLowering.cpp X86Subtarget.cpp X86Subtarget.h Message-ID: <20100527184341.092A7312800A@llvm.org> Author: djg Date: Thu May 27 13:43:40 2010 New Revision: 104866 URL: http://llvm.org/viewvc/llvm-project?rev=104866&view=rev Log: FastISel doesn't yet handle callee-pop functions. To support this, move IsCalleePop from X86ISelLowering to X86Subtarget. Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86Subtarget.cpp llvm/trunk/lib/Target/X86/X86Subtarget.h Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=104866&r1=104865&r2=104866&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original) +++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Thu May 27 13:43:40 2010 @@ -1314,6 +1314,10 @@ if (FTy->isVarArg()) return false; + // Fast-isel doesn't know about callee-pop yet. + if (Subtarget->IsCalleePop(FTy->isVarArg(), CC)) + return false; + // Handle *simple* calls for now. const Type *RetTy = CS.getType(); EVT RetVT; Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=104866&r1=104865&r2=104866&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Thu May 27 13:43:40 2010 @@ -1383,29 +1383,6 @@ return Ins[0].Flags.isSRet(); } -/// IsCalleePop - Determines whether the callee is required to pop its -/// own arguments. Callee pop is necessary to support tail calls. -bool X86TargetLowering::IsCalleePop(bool IsVarArg, - CallingConv::ID CallingConv) const { - if (IsVarArg) - return false; - - switch (CallingConv) { - default: - return false; - case CallingConv::X86_StdCall: - return !Subtarget->is64Bit(); - case CallingConv::X86_FastCall: - return !Subtarget->is64Bit(); - case CallingConv::X86_ThisCall: - return !Subtarget->is64Bit(); - case CallingConv::Fast: - return GuaranteedTailCallOpt; - case CallingConv::GHC: - return GuaranteedTailCallOpt; - } -} - /// CCAssignFnForNode - Selects the correct CCAssignFn for a the /// given CallingConvention value. CCAssignFn *X86TargetLowering::CCAssignFnForNode(CallingConv::ID CC) const { @@ -1722,7 +1699,7 @@ } // Some CCs need callee pop. - if (IsCalleePop(isVarArg, CallConv)) { + if (Subtarget->IsCalleePop(isVarArg, CallConv)) { FuncInfo->setBytesToPopOnReturn(StackSize); // Callee pops everything. } else { FuncInfo->setBytesToPopOnReturn(0); // Callee pops nothing. @@ -2173,7 +2150,7 @@ // Create the CALLSEQ_END node. unsigned NumBytesForCalleeToPush; - if (IsCalleePop(isVarArg, CallConv)) + if (Subtarget->IsCalleePop(isVarArg, CallConv)) NumBytesForCalleeToPush = NumBytes; // Callee pops everything else if (!Is64Bit && !IsTailCallConvention(CallConv) && IsStructRet) // If this is a call to a struct-return function, the callee Modified: llvm/trunk/lib/Target/X86/X86Subtarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.cpp?rev=104866&r1=104865&r2=104866&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Subtarget.cpp (original) +++ llvm/trunk/lib/Target/X86/X86Subtarget.cpp Thu May 27 13:43:40 2010 @@ -372,3 +372,26 @@ if (StackAlignment) stackAlignment = StackAlignment; } + +/// IsCalleePop - Determines whether the callee is required to pop its +/// own arguments. Callee pop is necessary to support tail calls. +bool X86Subtarget::IsCalleePop(bool IsVarArg, + CallingConv::ID CallingConv) const { + if (IsVarArg) + return false; + + switch (CallingConv) { + default: + return false; + case CallingConv::X86_StdCall: + return !is64Bit(); + case CallingConv::X86_FastCall: + return !is64Bit(); + case CallingConv::X86_ThisCall: + return !is64Bit(); + case CallingConv::Fast: + return GuaranteedTailCallOpt; + case CallingConv::GHC: + return GuaranteedTailCallOpt; + } +} Modified: llvm/trunk/lib/Target/X86/X86Subtarget.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.h?rev=104866&r1=104865&r2=104866&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Subtarget.h (original) +++ llvm/trunk/lib/Target/X86/X86Subtarget.h Thu May 27 13:43:40 2010 @@ -15,6 +15,7 @@ #define X86SUBTARGET_H #include "llvm/Target/TargetSubtarget.h" +#include "llvm/CallingConv.h" #include namespace llvm { @@ -237,6 +238,9 @@ /// indicating the number of scheduling cycles of backscheduling that /// should be attempted. unsigned getSpecialAddressLatency() const; + + /// IsCalleePop - Test whether a function should pop its own arguments. + bool IsCalleePop(bool isVarArg, CallingConv::ID CallConv) const; }; } // End llvm namespace From grosbach at apple.com Thu May 27 13:52:11 2010 From: grosbach at apple.com (Jim Grosbach) Date: Thu, 27 May 2010 18:52:11 -0000 Subject: [llvm-commits] [llvm] r104869 - in /llvm/trunk: include/llvm/Intrinsics.td lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Message-ID: <20100527185211.D862D312800A@llvm.org> Author: grosbach Date: Thu May 27 13:52:11 2010 New Revision: 104869 URL: http://llvm.org/viewvc/llvm-project?rev=104869&view=rev Log: hook ISD::STACKADDR to an intrinsic Modified: llvm/trunk/include/llvm/Intrinsics.td llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Modified: llvm/trunk/include/llvm/Intrinsics.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=104869&r1=104868&r2=104869&view=diff ============================================================================== --- llvm/trunk/include/llvm/Intrinsics.td (original) +++ llvm/trunk/include/llvm/Intrinsics.td Thu May 27 13:52:11 2010 @@ -197,12 +197,13 @@ def int_returnaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>; def int_frameaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>; -// Note: we treat stacksave/stackrestore as writemem because we don't otherwise -// model their dependencies on allocas. +// Note: we treat stacksave/stackrestore and stackaddr as writemem because we +// don't otherwise model their dependencies on allocas. def int_stacksave : Intrinsic<[llvm_ptr_ty]>, GCCBuiltin<"__builtin_stack_save">; def int_stackrestore : Intrinsic<[], [llvm_ptr_ty]>, GCCBuiltin<"__builtin_stack_restore">; +def int_stackaddress : Intrinsic<[llvm_ptr_ty], []>; // IntrWriteArgMem is more pessimistic than strictly necessary for prefetch, // however it does conveniently prevent the prefetch from being reordered Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=104869&r1=104868&r2=104869&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Thu May 27 13:52:11 2010 @@ -3756,6 +3756,10 @@ setValue(&I, DAG.getNode(ISD::FRAMEADDR, dl, TLI.getPointerTy(), getValue(I.getOperand(1)))); return 0; + case Intrinsic::stackaddress: + setValue(&I, DAG.getNode(ISD::STACKADDR, dl, TLI.getPointerTy(), getRoot(), + getValue(I.getOperand(1)))); + return 0; case Intrinsic::setjmp: return "_setjmp"+!TLI.usesUnderscoreSetJmp(); case Intrinsic::longjmp: From espindola at google.com Thu May 27 14:00:42 2010 From: espindola at google.com (Rafael Espindola) Date: Thu, 27 May 2010 15:00:42 -0400 Subject: [llvm-commits] [patch][llvm-gcc] Fix calls to fabs (part 2) Message-ID: This fixes the calls in the "uncommon" case of someone not doing LTO :-) Cheers, -- Rafael ?vila de Esp?ndola -------------- next part -------------- A non-text attachment was scrubbed... Name: callingconv.patch Type: text/x-diff Size: 462 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100527/98ec3e9a/attachment.bin From rafael.espindola at gmail.com Thu May 27 14:06:03 2010 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Thu, 27 May 2010 19:06:03 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r104870 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <20100527190604.098A5312800A@llvm.org> Author: rafael Date: Thu May 27 14:06:03 2010 New Revision: 104870 URL: http://llvm.org/viewvc/llvm-project?rev=104870&view=rev Log: Set the calling convention both in the function prototype and in the call. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=104870&r1=104869&r2=104870&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Thu May 27 14:06:03 2010 @@ -3578,6 +3578,8 @@ TARGET_ADJUST_LLVM_CC(CallingConvention, FunctionType); #endif + Function *F = cast(V); + F->setCallingConv(CallingConvention); CallInst *Call = Builder.CreateCall(V, Op); Call->setDoesNotThrow(); Call->setDoesNotAccessMemory(); From baldrick at free.fr Thu May 27 14:09:07 2010 From: baldrick at free.fr (Duncan Sands) Date: Thu, 27 May 2010 19:09:07 -0000 Subject: [llvm-commits] [llvm] r104871 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombine.h lib/Transforms/InstCombine/InstCombineCalls.cpp lib/Transforms/InstCombine/InstCombineCompares.cpp lib/Transforms/InstCombine/InstructionCombining.cpp test/Transforms/InstCombine/badmalloc.ll test/Transforms/InstCombine/malloc-free-delete.ll Message-ID: <20100527190907.166A5312800A@llvm.org> Author: baldrick Date: Thu May 27 14:09:06 2010 New Revision: 104871 URL: http://llvm.org/viewvc/llvm-project?rev=104871&view=rev Log: Teach instCombine to remove malloc+free if malloc's only uses are comparisons to null. Patch by Matti Niemenmaa. Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombine.h llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp llvm/trunk/test/Transforms/InstCombine/badmalloc.ll llvm/trunk/test/Transforms/InstCombine/malloc-free-delete.ll Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombine.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombine.h?rev=104871&r1=104870&r2=104871&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombine.h (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombine.h Thu May 27 14:09:06 2010 @@ -178,6 +178,7 @@ Instruction *visitPHINode(PHINode &PN); Instruction *visitGetElementPtrInst(GetElementPtrInst &GEP); Instruction *visitAllocaInst(AllocaInst &AI); + Instruction *visitMalloc(Instruction &FI); Instruction *visitFree(Instruction &FI); Instruction *visitLoadInst(LoadInst &LI); Instruction *visitStoreInst(StoreInst &SI); Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=104871&r1=104870&r2=104871&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Thu May 27 14:09:06 2010 @@ -250,6 +250,8 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { if (isFreeCall(&CI)) return visitFree(CI); + if (isMalloc(&CI)) + return visitMalloc(CI); // If the caller function is nounwind, mark the call as nounwind, even if the // callee isn't. Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=104871&r1=104870&r2=104871&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Thu May 27 14:09:06 2010 @@ -1924,35 +1924,6 @@ } break; } - case Instruction::Call: - // If we have (malloc != null), and if the malloc has a single use, we - // can assume it is successful and remove the malloc. - if (isMalloc(LHSI) && LHSI->hasOneUse() && - isa(RHSC)) { - // Need to explicitly erase malloc call here, instead of adding it to - // Worklist, because it won't get DCE'd from the Worklist since - // isInstructionTriviallyDead() returns false for function calls. - // It is OK to replace LHSI/MallocCall with Undef because the - // instruction that uses it will be erased via Worklist. - if (extractMallocCall(LHSI)) { - LHSI->replaceAllUsesWith(UndefValue::get(LHSI->getType())); - EraseInstFromFunction(*LHSI); - return ReplaceInstUsesWith(I, - ConstantInt::get(Type::getInt1Ty(I.getContext()), - !I.isTrueWhenEqual())); - } - if (CallInst* MallocCall = extractMallocCallFromBitCast(LHSI)) - if (MallocCall->hasOneUse()) { - MallocCall->replaceAllUsesWith( - UndefValue::get(MallocCall->getType())); - EraseInstFromFunction(*MallocCall); - Worklist.Add(LHSI); // The malloc's bitcast use. - return ReplaceInstUsesWith(I, - ConstantInt::get(Type::getInt1Ty(I.getContext()), - !I.isTrueWhenEqual())); - } - } - break; case Instruction::IntToPtr: // icmp pred inttoptr(X), null -> icmp pred X, 0 if (RHSC->isNullValue() && TD && Modified: llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp?rev=104871&r1=104870&r2=104871&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp Thu May 27 14:09:06 2010 @@ -710,6 +710,52 @@ return 0; } + + +static bool IsOnlyNullComparedAndFreed(const Value &V) { + for (Value::const_use_iterator UI = V.use_begin(), UE = V.use_end(); + UI != UE; ++UI) { + if (isFreeCall(*UI)) + continue; + if (const ICmpInst *ICI = dyn_cast(*UI)) + if (ICI->isEquality() && isa(ICI->getOperand(1))) + continue; + return false; + } + return true; +} + +Instruction *InstCombiner::visitMalloc(Instruction &MI) { + // If we have a malloc call which is only used in any amount of comparisons + // to null and free calls, delete the calls and replace the comparisons with + // true or false as appropriate. + if (IsOnlyNullComparedAndFreed(MI)) { + for (Value::use_iterator UI = MI.use_begin(), UE = MI.use_end(); + UI != UE;) { + // We can assume that every remaining use is a free call or an icmp eq/ne + // to null, so the cast is safe. + Instruction *I = cast(*UI); + + // Early increment here, as we're about to get rid of the user. + ++UI; + + if (isFreeCall(I)) { + EraseInstFromFunction(*cast(I)); + continue; + } + // Again, the cast is safe. + ICmpInst *C = cast(I); + ReplaceInstUsesWith(*C, ConstantInt::get(Type::getInt1Ty(C->getContext()), + C->isFalseWhenEqual())); + EraseInstFromFunction(*C); + } + return EraseInstFromFunction(MI); + } + return 0; +} + + + Instruction *InstCombiner::visitFree(Instruction &FI) { Value *Op = FI.getOperand(1); @@ -726,23 +772,6 @@ if (isa(Op)) return EraseInstFromFunction(FI); - // If we have a malloc call whose only use is a free call, delete both. - if (isMalloc(Op)) { - if (CallInst* CI = extractMallocCallFromBitCast(Op)) { - if (Op->hasOneUse() && CI->hasOneUse()) { - EraseInstFromFunction(FI); - EraseInstFromFunction(*CI); - return EraseInstFromFunction(*cast(Op)); - } - } else { - // Op is a call to malloc - if (Op->hasOneUse()) { - EraseInstFromFunction(FI); - return EraseInstFromFunction(*cast(Op)); - } - } - } - return 0; } Modified: llvm/trunk/test/Transforms/InstCombine/badmalloc.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/badmalloc.ll?rev=104871&r1=104870&r2=104871&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/badmalloc.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/badmalloc.ll Thu May 27 14:09:06 2010 @@ -10,6 +10,7 @@ define i1 @test1() { %A = call noalias i8* @malloc(i64 4) nounwind %B = icmp eq i8* %A, null + store i8 0, i8* %A call void @free(i8* %A) ret i1 %B Modified: llvm/trunk/test/Transforms/InstCombine/malloc-free-delete.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/malloc-free-delete.ll?rev=104871&r1=104870&r2=104871&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/malloc-free-delete.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/malloc-free-delete.ll Thu May 27 14:09:06 2010 @@ -1,13 +1,25 @@ -; RUN: opt < %s -instcombine -globaldce -S | FileCheck %s +; RUN: opt < %s -instcombine -S | FileCheck %s ; PR1201 define i32 @main(i32 %argc, i8** %argv) { - %c_19 = alloca i8* ; [#uses=2] - %malloc_206 = malloc i8, i32 10 ; [#uses=1] + %c_19 = alloca i8* + %malloc_206 = malloc i8, i32 10 ; CHECK-NOT: malloc store i8* %malloc_206, i8** %c_19 - %tmp_207 = load i8** %c_19 ; [#uses=1] + %tmp_207 = load i8** %c_19 free i8* %tmp_207 ; CHECK-NOT: free ret i32 0 ; CHECK: ret i32 0 } + +declare i8* @malloc(i32) +declare void @free(i8*) + +define i1 @foo() { +; CHECK: @foo +; CHECK-NEXT: ret i1 false + %m = call i8* @malloc(i32 1) + %z = icmp eq i8* %m, null + call void @free(i8* %m) + ret i1 %z +} From baldrick at free.fr Thu May 27 14:11:07 2010 From: baldrick at free.fr (Duncan Sands) Date: Thu, 27 May 2010 21:11:07 +0200 Subject: [llvm-commits] [PATCH] InstCombine: remove malloc+free if malloc's only uses are comparisons to null In-Reply-To: References: <4BF02485.2050508@iki.fi> <4BF1088E.30805@free.fr> <4BF59981.90607@free.fr> <4BF7A953.8000303@iki.fi> <4BFE89B6.2090904@free.fr> Message-ID: <4BFEC3CB.2030704@free.fr> On 27/05/10 17:16, Matti Niemenmaa wrote: > On 2010-05-27 18:03, Duncan Sands wrote: >> I accidentally deleted your email with the patch, which is why >> I didn't apply it. Please send it again. > > Attached. Thanks - applied in commit 104871. Best wishes, Duncan. From echristo at apple.com Thu May 27 14:42:43 2010 From: echristo at apple.com (Eric Christopher) Date: Thu, 27 May 2010 12:42:43 -0700 Subject: [llvm-commits] [patch][llvm-gcc] Fix calls to fabs (part 2) In-Reply-To: References: Message-ID: <3571D036-C1ED-4025-9C58-7639FC8B3D73@apple.com> On May 27, 2010, at 12:00 PM, Rafael Espindola wrote: > This isn't being done above in the adjust calling convention area? -eric From espindola at google.com Thu May 27 14:45:02 2010 From: espindola at google.com (Rafael Espindola) Date: Thu, 27 May 2010 15:45:02 -0400 Subject: [llvm-commits] [patch][llvm-gcc] Fix calls to fabs (part 2) In-Reply-To: <3571D036-C1ED-4025-9C58-7639FC8B3D73@apple.com> References: <3571D036-C1ED-4025-9C58-7639FC8B3D73@apple.com> Message-ID: > This isn't being done above in the adjust calling convention area? No, this is part of my previous patch that I forgot to fix. Before we would never set the calling convention on fabs. With the first patch we would set it on the call but not the prototype. We now set it on both. > -eric > Cheers, -- Rafael ?vila de Esp?ndola From echristo at apple.com Thu May 27 14:47:21 2010 From: echristo at apple.com (Eric Christopher) Date: Thu, 27 May 2010 12:47:21 -0700 Subject: [llvm-commits] [patch][llvm-gcc] Fix calls to fabs (part 2) In-Reply-To: References: <3571D036-C1ED-4025-9C58-7639FC8B3D73@apple.com> Message-ID: On May 27, 2010, at 12:45 PM, Rafael Espindola wrote: >> This isn't being done above in the adjust calling convention area? > > No, this is part of my previous patch that I forgot to fix. Before we > would never set the calling convention on fabs. With the first patch > we would set it on the call but not the prototype. We now set it on > both. Huh. OK. -eric From dpatel at apple.com Thu May 27 14:46:38 2010 From: dpatel at apple.com (Devang Patel) Date: Thu, 27 May 2010 19:46:38 -0000 Subject: [llvm-commits] [llvm] r104872 - /llvm/trunk/test/DebugInfo/2010-05-28-Crash.ll Message-ID: <20100527194639.0BF2E312800A@llvm.org> Author: dpatel Date: Thu May 27 14:46:38 2010 New Revision: 104872 URL: http://llvm.org/viewvc/llvm-project?rev=104872&view=rev Log: Let's try one more time to match patterns. The goal is to match following 3 lines. In otherwords, a temp. label between to DEBUG_VALUE comments. ;DEBUG_VALUE: bar:x <- undef ## 2010-01-18-Inlined-Debug.c:7 Ltmp1: ;DEBUG_VALUE: foo:__x <- undef ## 2010-01-18-Inlined-Debug.c:5 Modified: llvm/trunk/test/DebugInfo/2010-05-28-Crash.ll Modified: llvm/trunk/test/DebugInfo/2010-05-28-Crash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/2010-05-28-Crash.ll?rev=104872&r1=104871&r2=104872&view=diff ============================================================================== --- llvm/trunk/test/DebugInfo/2010-05-28-Crash.ll (original) +++ llvm/trunk/test/DebugInfo/2010-05-28-Crash.ll Thu May 27 14:46:38 2010 @@ -44,6 +44,6 @@ !15 = metadata !{i32 5, i32 0, metadata !11, metadata !8} !16 = metadata !{i32 9, i32 0, metadata !9, null} -;CHECK: ##DEBUG_VALUE: bar:x +;CHECK: DEBUG_VALUE: bar:x ;CHECK-NEXT:Ltmp -;CHECK-NEXT ##DEBUG_VALUE: foo:__x +;CHECK-NEXT DEBUG_VALUE: foo:__x From gohman at apple.com Thu May 27 14:47:36 2010 From: gohman at apple.com (Dan Gohman) Date: Thu, 27 May 2010 19:47:36 -0000 Subject: [llvm-commits] [llvm] r104873 - in /llvm/trunk/tools: llc/llc.cpp llvm-mc/llvm-mc.cpp opt/opt.cpp Message-ID: <20100527194736.3E364312800A@llvm.org> Author: djg Date: Thu May 27 14:47:36 2010 New Revision: 104873 URL: http://llvm.org/viewvc/llvm-project?rev=104873&view=rev Log: Avoid calling outs() and fouts() when the stream isn't really needed. Modified: llvm/trunk/tools/llc/llc.cpp llvm/trunk/tools/llvm-mc/llvm-mc.cpp llvm/trunk/tools/opt/opt.cpp Modified: llvm/trunk/tools/llc/llc.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llc/llc.cpp?rev=104873&r1=104872&r2=104873&view=diff ============================================================================== --- llvm/trunk/tools/llc/llc.cpp (original) +++ llvm/trunk/tools/llc/llc.cpp Thu May 27 14:47:36 2010 @@ -124,7 +124,8 @@ const char *ProgName) { if (OutputFilename != "") { if (OutputFilename == "-") - return &fouts(); + return new formatted_raw_ostream(outs(), + formatted_raw_ostream::PRESERVE_STREAM); // Make sure that the Out file gets unlinked from the disk if we get a // SIGINT @@ -147,7 +148,8 @@ if (InputFilename == "-") { OutputFilename = "-"; - return &fouts(); + return new formatted_raw_ostream(outs(), + formatted_raw_ostream::PRESERVE_STREAM); } OutputFilename = GetFileNameRoot(InputFilename); @@ -332,7 +334,7 @@ DisableVerify)) { errs() << argv[0] << ": target does not support generation of this" << " file type!\n"; - if (Out != &fouts()) delete Out; + delete Out; // And the Out file is empty and useless, so remove it now. sys::Path(OutputFilename).eraseFromDisk(); return 1; @@ -340,8 +342,8 @@ PM.run(mod); - // Delete the ostream if it's not a stdout stream - if (Out != &fouts()) delete Out; + // Delete the ostream. + delete Out; return 0; } Modified: llvm/trunk/tools/llvm-mc/llvm-mc.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mc/llvm-mc.cpp?rev=104873&r1=104872&r2=104873&view=diff ============================================================================== --- llvm/trunk/tools/llvm-mc/llvm-mc.cpp (original) +++ llvm/trunk/tools/llvm-mc/llvm-mc.cpp Thu May 27 14:47:36 2010 @@ -323,8 +323,7 @@ Parser.setTargetParser(*TAP.get()); int Res = Parser.Run(NoInitialTextSection); - if (Out != &fouts()) - delete Out; + delete Out; // Delete output on errors. if (Res && OutputFilename != "-") Modified: llvm/trunk/tools/opt/opt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/opt.cpp?rev=104873&r1=104872&r2=104873&view=diff ============================================================================== --- llvm/trunk/tools/opt/opt.cpp (original) +++ llvm/trunk/tools/opt/opt.cpp Thu May 27 14:47:36 2010 @@ -378,8 +378,12 @@ // Figure out what stream we are supposed to write to... // FIXME: outs() is not binary! - raw_ostream *Out = &outs(); // Default to printing to stdout... - if (OutputFilename != "-") { + raw_ostream *Out = 0; + bool DeleteStream = true; + if (OutputFilename == "-") { + Out = &outs(); // Default to printing to stdout... + DeleteStream = false; + } else { if (NoOutput || AnalyzeOnly) { errs() << "WARNING: The -o (output filename) option is ignored when\n" "the --disable-output or --analyze options are used.\n"; @@ -540,7 +544,7 @@ Passes.run(*M.get()); // Delete the raw_fd_ostream. - if (Out != &outs()) + if (DeleteStream) delete Out; return 0; } From gohman at apple.com Thu May 27 14:48:08 2010 From: gohman at apple.com (Dan Gohman) Date: Thu, 27 May 2010 19:48:08 -0000 Subject: [llvm-commits] [llvm] r104874 - /llvm/trunk/utils/TableGen/TableGen.cpp Message-ID: <20100527194808.BD736312800A@llvm.org> Author: djg Date: Thu May 27 14:48:08 2010 New Revision: 104874 URL: http://llvm.org/viewvc/llvm-project?rev=104874&view=rev Log: Simplify raw_ostream usage. Modified: llvm/trunk/utils/TableGen/TableGen.cpp Modified: llvm/trunk/utils/TableGen/TableGen.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TableGen.cpp?rev=104874&r1=104873&r2=104874&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/TableGen.cpp (original) +++ llvm/trunk/utils/TableGen/TableGen.cpp Thu May 27 14:48:08 2010 @@ -191,105 +191,101 @@ if (ParseFile(InputFilename, IncludeDirs, SrcMgr)) return 1; - raw_ostream *Out = &outs(); - if (OutputFilename != "-") { - std::string Error; - Out = new raw_fd_ostream(OutputFilename.c_str(), Error); - - if (!Error.empty()) { - errs() << argv[0] << ": error opening " << OutputFilename - << ":" << Error << "\n"; - return 1; - } - - // Make sure the file gets removed if *gasp* tablegen crashes... - sys::RemoveFileOnSignal(sys::Path(OutputFilename)); + std::string Error; + raw_fd_ostream Out(OutputFilename.c_str(), Error); + if (!Error.empty()) { + errs() << argv[0] << ": error opening " << OutputFilename + << ":" << Error << "\n"; + return 1; } + // Make sure the file gets removed if *gasp* tablegen crashes... + sys::RemoveFileOnSignal(sys::Path(OutputFilename)); + try { switch (Action) { case PrintRecords: - *Out << Records; // No argument, dump all contents + Out << Records; // No argument, dump all contents break; case GenEmitter: - CodeEmitterGen(Records).run(*Out); + CodeEmitterGen(Records).run(Out); break; case GenRegisterEnums: - RegisterInfoEmitter(Records).runEnums(*Out); + RegisterInfoEmitter(Records).runEnums(Out); break; case GenRegister: - RegisterInfoEmitter(Records).run(*Out); + RegisterInfoEmitter(Records).run(Out); break; case GenRegisterHeader: - RegisterInfoEmitter(Records).runHeader(*Out); + RegisterInfoEmitter(Records).runHeader(Out); break; case GenInstrEnums: - InstrEnumEmitter(Records).run(*Out); + InstrEnumEmitter(Records).run(Out); break; case GenInstrs: - InstrInfoEmitter(Records).run(*Out); + InstrInfoEmitter(Records).run(Out); break; case GenCallingConv: - CallingConvEmitter(Records).run(*Out); + CallingConvEmitter(Records).run(Out); break; case GenAsmWriter: - AsmWriterEmitter(Records).run(*Out); + AsmWriterEmitter(Records).run(Out); break; case GenARMDecoder: - ARMDecoderEmitter(Records).run(*Out); + ARMDecoderEmitter(Records).run(Out); break; case GenAsmMatcher: - AsmMatcherEmitter(Records).run(*Out); + AsmMatcherEmitter(Records).run(Out); break; case GenClangDiagsDefs: - ClangDiagsDefsEmitter(Records, ClangComponent).run(*Out); + ClangDiagsDefsEmitter(Records, ClangComponent).run(Out); break; case GenClangDiagGroups: - ClangDiagGroupsEmitter(Records).run(*Out); + ClangDiagGroupsEmitter(Records).run(Out); break; case GenClangStmtNodes: - ClangStmtNodesEmitter(Records).run(*Out); + ClangStmtNodesEmitter(Records).run(Out); break; case GenDisassembler: - DisassemblerEmitter(Records).run(*Out); + DisassemblerEmitter(Records).run(Out); break; case GenOptParserDefs: - OptParserEmitter(Records, true).run(*Out); + OptParserEmitter(Records, true).run(Out); break; case GenOptParserImpl: - OptParserEmitter(Records, false).run(*Out); + OptParserEmitter(Records, false).run(Out); break; case GenDAGISel: - DAGISelEmitter(Records).run(*Out); + DAGISelEmitter(Records).run(Out); break; case GenFastISel: - FastISelEmitter(Records).run(*Out); + FastISelEmitter(Records).run(Out); break; case GenSubtarget: - SubtargetEmitter(Records).run(*Out); + SubtargetEmitter(Records).run(Out); break; case GenIntrinsic: - IntrinsicEmitter(Records).run(*Out); + IntrinsicEmitter(Records).run(Out); break; case GenTgtIntrinsic: - IntrinsicEmitter(Records, true).run(*Out); + IntrinsicEmitter(Records, true).run(Out); break; case GenLLVMCConf: - LLVMCConfigurationEmitter(Records).run(*Out); + LLVMCConfigurationEmitter(Records).run(Out); break; case GenEDHeader: - EDEmitter(Records).runHeader(*Out); + EDEmitter(Records).runHeader(Out); break; case GenEDInfo: - EDEmitter(Records).run(*Out); + EDEmitter(Records).run(Out); break; case PrintEnums: { std::vector Recs = Records.getAllDerivedDefinitions(Class); for (unsigned i = 0, e = Recs.size(); i != e; ++i) - *Out << Recs[i]->getName() << ", "; - *Out << "\n"; + Out << Recs[i]->getName() << ", "; + Out << "\n"; break; } default: @@ -297,8 +293,6 @@ return 1; } - if (Out != &outs()) - delete Out; // Close the file return 0; } catch (const TGError &Error) { @@ -313,9 +307,7 @@ errs() << argv[0] << ": Unknown unexpected exception occurred.\n"; } - if (Out != &outs()) { - delete Out; // Close the file + if (OutputFilename != "-") std::remove(OutputFilename.c_str()); // Remove the file, it's broken - } return 1; } From gohman at apple.com Thu May 27 14:52:20 2010 From: gohman at apple.com (Dan Gohman) Date: Thu, 27 May 2010 19:52:20 -0000 Subject: [llvm-commits] [llvm] r104875 - /llvm/trunk/tools/opt/opt.cpp Message-ID: <20100527195220.C3AA8312800A@llvm.org> Author: djg Date: Thu May 27 14:52:20 2010 New Revision: 104875 URL: http://llvm.org/viewvc/llvm-project?rev=104875&view=rev Log: Don't create an output stream when output is disabled. Modified: llvm/trunk/tools/opt/opt.cpp Modified: llvm/trunk/tools/opt/opt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/opt.cpp?rev=104875&r1=104874&r2=104875&view=diff ============================================================================== --- llvm/trunk/tools/opt/opt.cpp (original) +++ llvm/trunk/tools/opt/opt.cpp Thu May 27 14:52:20 2010 @@ -379,26 +379,28 @@ // Figure out what stream we are supposed to write to... // FIXME: outs() is not binary! raw_ostream *Out = 0; - bool DeleteStream = true; - if (OutputFilename == "-") { - Out = &outs(); // Default to printing to stdout... - DeleteStream = false; - } else { - if (NoOutput || AnalyzeOnly) { - errs() << "WARNING: The -o (output filename) option is ignored when\n" - "the --disable-output or --analyze options are used.\n"; + bool DeleteStream = false; + if (!NoOutput && !AnalyzeOnly) { + if (OutputFilename == "-") { + Out = &outs(); // Default to printing to stdout... } else { - // Make sure that the Output file gets unlinked from the disk if we get a - // SIGINT - sys::RemoveFileOnSignal(sys::Path(OutputFilename)); - - std::string ErrorInfo; - Out = new raw_fd_ostream(OutputFilename.c_str(), ErrorInfo, - raw_fd_ostream::F_Binary); - if (!ErrorInfo.empty()) { - errs() << ErrorInfo << '\n'; - delete Out; - return 1; + if (NoOutput || AnalyzeOnly) { + errs() << "WARNING: The -o (output filename) option is ignored when\n" + "the --disable-output or --analyze options are used.\n"; + } else { + // Make sure that the Output file gets unlinked from the disk if we get + // a SIGINT. + sys::RemoveFileOnSignal(sys::Path(OutputFilename)); + + std::string ErrorInfo; + Out = new raw_fd_ostream(OutputFilename.c_str(), ErrorInfo, + raw_fd_ostream::F_Binary); + if (!ErrorInfo.empty()) { + errs() << ErrorInfo << '\n'; + delete Out; + return 1; + } + DeleteStream = true; } } } From stuart at apple.com Thu May 27 14:57:51 2010 From: stuart at apple.com (Stuart Hastings) Date: Thu, 27 May 2010 19:57:51 -0000 Subject: [llvm-commits] [llvm] r104876 - /llvm/trunk/test/FrontendC/2010-03-5-LexicalScope.c Message-ID: <20100527195751.87030312800A@llvm.org> Author: stuart Date: Thu May 27 14:57:51 2010 New Revision: 104876 URL: http://llvm.org/viewvc/llvm-project?rev=104876&view=rev Log: Adjust test case for lexical block pruning. Follow-on to r104842 and Radar 7424645. Modified: llvm/trunk/test/FrontendC/2010-03-5-LexicalScope.c Modified: llvm/trunk/test/FrontendC/2010-03-5-LexicalScope.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendC/2010-03-5-LexicalScope.c?rev=104876&r1=104875&r2=104876&view=diff ============================================================================== --- llvm/trunk/test/FrontendC/2010-03-5-LexicalScope.c (original) +++ llvm/trunk/test/FrontendC/2010-03-5-LexicalScope.c Thu May 27 14:57:51 2010 @@ -1,4 +1,4 @@ -// RUN: %llvmgcc -S -O0 -g %s -o - | grep DW_TAG_lexical_block | count 3 +// RUN: %llvmgcc -S -O0 -g %s -o - | grep DW_TAG_lexical_block | count 2 int foo(int i) { if (i) { int j = 2; From gohman at apple.com Thu May 27 15:06:51 2010 From: gohman at apple.com (Dan Gohman) Date: Thu, 27 May 2010 20:06:51 -0000 Subject: [llvm-commits] [llvm] r104878 - in /llvm/trunk: include/llvm/Bitcode/ReaderWriter.h lib/Bitcode/Writer/BitcodeWriter.cpp tools/opt/opt.cpp Message-ID: <20100527200651.7F387312800A@llvm.org> Author: djg Date: Thu May 27 15:06:51 2010 New Revision: 104878 URL: http://llvm.org/viewvc/llvm-project?rev=104878&view=rev Log: Don't special-case stdout in llvm::WriteBitcodeToFile; just consider it to be the caller's responsibility to provide a stream in binary mode. This fixes a layering violation and avoids an outs() call. Modified: llvm/trunk/include/llvm/Bitcode/ReaderWriter.h llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp llvm/trunk/tools/opt/opt.cpp Modified: llvm/trunk/include/llvm/Bitcode/ReaderWriter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/ReaderWriter.h?rev=104878&r1=104877&r2=104878&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/ReaderWriter.h (original) +++ llvm/trunk/include/llvm/Bitcode/ReaderWriter.h Thu May 27 15:06:51 2010 @@ -40,7 +40,8 @@ std::string *ErrMsg = 0); /// WriteBitcodeToFile - Write the specified module to the specified - /// raw output stream. + /// raw output stream. For streams where it matters, the given stream + /// should be in "binary" mode. void WriteBitcodeToFile(const Module *M, raw_ostream &Out); /// WriteBitcodeToStream - Write the specified module to the specified Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=104878&r1=104877&r2=104878&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original) +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Thu May 27 15:06:51 2010 @@ -1662,10 +1662,6 @@ WriteBitcodeToStream( M, Stream ); - // If writing to stdout, set binary mode. - if (&llvm::outs() == &Out) - sys::Program::ChangeStdoutToBinary(); - // Write the generated bitstream to "Out". Out.write((char*)&Buffer.front(), Buffer.size()); Modified: llvm/trunk/tools/opt/opt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/opt.cpp?rev=104878&r1=104877&r2=104878&view=diff ============================================================================== --- llvm/trunk/tools/opt/opt.cpp (original) +++ llvm/trunk/tools/opt/opt.cpp Thu May 27 15:06:51 2010 @@ -377,12 +377,16 @@ } // Figure out what stream we are supposed to write to... - // FIXME: outs() is not binary! raw_ostream *Out = 0; bool DeleteStream = false; if (!NoOutput && !AnalyzeOnly) { if (OutputFilename == "-") { - Out = &outs(); // Default to printing to stdout... + // Print to stdout. + Out = &outs(); + // If we're printing a bitcode file, switch stdout to binary mode. + // FIXME: This switches outs() globally, not just for the bitcode output. + if (!OutputAssembly) + sys::Program::ChangeStdoutToBinary(); } else { if (NoOutput || AnalyzeOnly) { errs() << "WARNING: The -o (output filename) option is ignored when\n" From dalej at apple.com Thu May 27 15:12:41 2010 From: dalej at apple.com (Dale Johannesen) Date: Thu, 27 May 2010 20:12:41 -0000 Subject: [llvm-commits] [llvm] r104879 - /llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Message-ID: <20100527201241.76350312800A@llvm.org> Author: johannes Date: Thu May 27 15:12:41 2010 New Revision: 104879 URL: http://llvm.org/viewvc/llvm-project?rev=104879&view=rev Log: Mark some math lib intrinsic nodes Legal on SSE4.1. No functional effect as these nodes are not generated yet. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=104879&r1=104878&r2=104879&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Thu May 27 15:12:41 2010 @@ -825,6 +825,17 @@ } if (Subtarget->hasSSE41()) { + setOperationAction(ISD::FFLOOR, MVT::f32, Legal); + setOperationAction(ISD::FCEIL, MVT::f32, Legal); + setOperationAction(ISD::FTRUNC, MVT::f32, Legal); + setOperationAction(ISD::FRINT, MVT::f32, Legal); + setOperationAction(ISD::FNEARBYINT, MVT::f32, Legal); + setOperationAction(ISD::FFLOOR, MVT::f64, Legal); + setOperationAction(ISD::FCEIL, MVT::f64, Legal); + setOperationAction(ISD::FTRUNC, MVT::f64, Legal); + setOperationAction(ISD::FRINT, MVT::f64, Legal); + setOperationAction(ISD::FNEARBYINT, MVT::f64, Legal); + // FIXME: Do we need to handle scalar-to-vector here? setOperationAction(ISD::MUL, MVT::v4i32, Legal); From gohman at apple.com Thu May 27 15:17:28 2010 From: gohman at apple.com (Dan Gohman) Date: Thu, 27 May 2010 20:17:28 -0000 Subject: [llvm-commits] [llvm] r104881 - /llvm/trunk/utils/FileUpdate/FileUpdate.cpp Message-ID: <20100527201728.444CE312800A@llvm.org> Author: djg Date: Thu May 27 15:17:28 2010 New Revision: 104881 URL: http://llvm.org/viewvc/llvm-project?rev=104881&view=rev Log: When handling raw_ostream errors manually, use clear_error() so that raw_ostream doesn't try to do its own error handling. Modified: llvm/trunk/utils/FileUpdate/FileUpdate.cpp Modified: llvm/trunk/utils/FileUpdate/FileUpdate.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/FileUpdate/FileUpdate.cpp?rev=104881&r1=104880&r2=104881&view=diff ============================================================================== --- llvm/trunk/utils/FileUpdate/FileUpdate.cpp (original) +++ llvm/trunk/utils/FileUpdate/FileUpdate.cpp Thu May 27 15:17:28 2010 @@ -79,6 +79,7 @@ if (OutStream.has_error()) { errs() << argv[0] << ": Could not open output file '" << OutputFilename << "': " << ErrorStr << '\n'; + OutStream.clear_error(); return 1; } From gohman at apple.com Thu May 27 15:19:47 2010 From: gohman at apple.com (Dan Gohman) Date: Thu, 27 May 2010 20:19:47 -0000 Subject: [llvm-commits] [llvm] r104882 - /llvm/trunk/tools/lto/LTOCodeGenerator.cpp Message-ID: <20100527201947.9A518312800A@llvm.org> Author: djg Date: Thu May 27 15:19:47 2010 New Revision: 104882 URL: http://llvm.org/viewvc/llvm-project?rev=104882&view=rev Log: When handling raw_ostream errors manually, use clear_error() so that raw_ostream doesn't try to do its own error handling. Also, close the raw_ostream before checking for errors so that any errors that occur during closing are caught by the manual check. Modified: llvm/trunk/tools/lto/LTOCodeGenerator.cpp Modified: llvm/trunk/tools/lto/LTOCodeGenerator.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/LTOCodeGenerator.cpp?rev=104882&r1=104881&r2=104882&view=diff ============================================================================== --- llvm/trunk/tools/lto/LTOCodeGenerator.cpp (original) +++ llvm/trunk/tools/lto/LTOCodeGenerator.cpp Thu May 27 15:19:47 2010 @@ -152,10 +152,12 @@ // write bitcode to it WriteBitcodeToFile(_linker.getModule(), Out); - + Out.close(); + if (Out.has_error()) { errMsg = "could not write bitcode file: "; errMsg += path; + Out.clear_error(); return true; } From bob.wilson at apple.com Thu May 27 15:23:42 2010 From: bob.wilson at apple.com (Bob Wilson) Date: Thu, 27 May 2010 20:23:42 -0000 Subject: [llvm-commits] [llvm] r104883 - /llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Message-ID: <20100527202342.E410B312800A@llvm.org> Author: bwilson Date: Thu May 27 15:23:42 2010 New Revision: 104883 URL: http://llvm.org/viewvc/llvm-project?rev=104883&view=rev Log: Fix some bad fall-throughs in a switch statement. Both the 'Q' and 'R' cases should fall through to the 'H' case, but instead 'Q' was falling through to 'R' so that it would do the wrong thing for a big-endian ARM target. Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp?rev=104883&r1=104882&r2=104883&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Thu May 27 15:23:42 2010 @@ -1064,21 +1064,27 @@ printOperand(MI, OpNum, O); return false; case 'Q': - if (TM.getTargetData()->isLittleEndian()) + // Print the least significant half of a register pair. + if (TM.getTargetData()->isBigEndian()) break; - // Fallthrough + printOperand(MI, OpNum, O); + return false; case 'R': - if (TM.getTargetData()->isBigEndian()) + // Print the most significant half of a register pair. + if (TM.getTargetData()->isLittleEndian()) break; - // Fallthrough - case 'H': // Write second word of DI / DF reference. - // Verify that this operand has two consecutive registers. - if (!MI->getOperand(OpNum).isReg() || - OpNum+1 == MI->getNumOperands() || - !MI->getOperand(OpNum+1).isReg()) - return true; - ++OpNum; // Return the high-part. + printOperand(MI, OpNum, O); + return false; + case 'H': + break; } + // Print the second half of a register pair (for 'Q', 'R' or 'H'). + // Verify that this operand has two consecutive registers. + if (!MI->getOperand(OpNum).isReg() || + OpNum+1 == MI->getNumOperands() || + !MI->getOperand(OpNum+1).isReg()) + return true; + ++OpNum; } printOperand(MI, OpNum, O); From dpatel at apple.com Thu May 27 15:25:04 2010 From: dpatel at apple.com (Devang Patel) Date: Thu, 27 May 2010 20:25:04 -0000 Subject: [llvm-commits] [llvm] r104884 - in /llvm/trunk: lib/CodeGen/AsmPrinter/DwarfDebug.cpp lib/Transforms/Utils/PromoteMemoryToRegister.cpp test/Transforms/Mem2Reg/ConvertDebugInfo2.ll Message-ID: <20100527202504.E51BA312800A@llvm.org> Author: dpatel Date: Thu May 27 15:25:04 2010 New Revision: 104884 URL: http://llvm.org/viewvc/llvm-project?rev=104884&view=rev Log: Do not drop location info for inlined function args. Added: llvm/trunk/test/Transforms/Mem2Reg/ConvertDebugInfo2.ll Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=104884&r1=104883&r2=104884&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Thu May 27 15:25:04 2010 @@ -2200,7 +2200,11 @@ } DbgScope *Scope = findDbgScope(MInsn); - if (!Scope && DV.getTag() == dwarf::DW_TAG_arg_variable) + bool CurFnArg = false; + if (DV.getTag() == dwarf::DW_TAG_arg_variable && + DISubprogram(DV.getContext()).describes(MF->getFunction())) + CurFnArg = true; + if (!Scope && CurFnArg) Scope = CurrentFnDbgScope; // If variable scope is not found then skip this variable. if (!Scope) @@ -2209,7 +2213,7 @@ Processed.insert(DV); DbgVariable *RegVar = new DbgVariable(DV); Scope->addVariable(RegVar); - if (DV.getTag() != dwarf::DW_TAG_arg_variable) + if (!CurFnArg) DbgVariableLabelsMap[RegVar] = getLabelBeforeInsn(MInsn); if (DbgVariable *AbsVar = findAbstractVariable(DV, MInsn->getDebugLoc())) { DbgVariableToDbgInstMap[AbsVar] = MInsn; Modified: llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp?rev=104884&r1=104883&r2=104884&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Thu May 27 15:25:04 2010 @@ -897,6 +897,11 @@ // Propagate any debug metadata from the store onto the dbg.value. if (MDNode *SIMD = SI->getMetadata("dbg")) DbgVal->setMetadata("dbg", SIMD); + // Otherwise propgate debug metadata from dbg.delcare for inlined fn args. + else if (!DISubprogram(DIVar.getContext()). + describes(DDI->getParent()->getParent())) + if (MDNode *MD = DDI->getMetadata("dbg")) + DbgVal->setMetadata("dbg", MD); } // QueuePhiNode - queues a phi-node to be added to a basic-block for a specific Added: llvm/trunk/test/Transforms/Mem2Reg/ConvertDebugInfo2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Mem2Reg/ConvertDebugInfo2.ll?rev=104884&view=auto ============================================================================== --- llvm/trunk/test/Transforms/Mem2Reg/ConvertDebugInfo2.ll (added) +++ llvm/trunk/test/Transforms/Mem2Reg/ConvertDebugInfo2.ll Thu May 27 15:25:04 2010 @@ -0,0 +1,52 @@ +; RUN: opt -mem2reg < %s | llvm-dis | grep ".dbg "| count 6 + +declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone + +declare void @foo(i32, i64, i8*) + +define void @baz(i32 %a) nounwind ssp { +entry: + %x_addr.i = alloca i32 ; [#uses=2] + %y_addr.i = alloca i64 ; [#uses=2] + %z_addr.i = alloca i8* ; [#uses=2] + %a_addr = alloca i32 ; [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + call void @llvm.dbg.declare(metadata !{i32* %a_addr}, metadata !0), !dbg !7 + store i32 %a, i32* %a_addr + %0 = load i32* %a_addr, align 4, !dbg !8 ; [#uses=1] + call void @llvm.dbg.declare(metadata !{i32* %x_addr.i}, metadata !9) nounwind, !dbg !15 + store i32 %0, i32* %x_addr.i + call void @llvm.dbg.declare(metadata !{i64* %y_addr.i}, metadata !16) nounwind, !dbg !15 + store i64 55, i64* %y_addr.i + call void @llvm.dbg.declare(metadata !{i8** %z_addr.i}, metadata !17) nounwind, !dbg !15 + store i8* bitcast (void (i32)* @baz to i8*), i8** %z_addr.i + %1 = load i32* %x_addr.i, align 4, !dbg !18 ; [#uses=1] + %2 = load i64* %y_addr.i, align 8, !dbg !18 ; [#uses=1] + %3 = load i8** %z_addr.i, align 8, !dbg !18 ; [#uses=1] + call void @foo(i32 %1, i64 %2, i8* %3) nounwind, !dbg !18 + br label %return, !dbg !19 + +return: ; preds = %entry + ret void, !dbg !19 +} + +!0 = metadata !{i32 524545, metadata !1, metadata !"a", metadata !2, i32 8, metadata !6} ; [ DW_TAG_arg_variable ] +!1 = metadata !{i32 524334, i32 0, metadata !2, metadata !"baz", metadata !"baz", metadata !"baz", metadata !2, i32 8, metadata !4, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 false} ; [ DW_TAG_subprogram ] +!2 = metadata !{i32 524329, metadata !"bar.c", metadata !"/tmp/", metadata !3} ; [ DW_TAG_file_type ] +!3 = metadata !{i32 524305, i32 0, i32 1, metadata !"bar.c", metadata !"/tmp/", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] +!4 = metadata !{i32 524309, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !5, i32 0, null} ; [ DW_TAG_subroutine_type ] +!5 = metadata !{null, metadata !6} +!6 = metadata !{i32 524324, metadata !2, metadata !"int", metadata !2, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!7 = metadata !{i32 8, i32 0, metadata !1, null} +!8 = metadata !{i32 9, i32 0, metadata !1, null} +!9 = metadata !{i32 524545, metadata !10, metadata !"x", metadata !2, i32 4, metadata !6} ; [ DW_TAG_arg_variable ] +!10 = metadata !{i32 524334, i32 0, metadata !2, metadata !"bar", metadata !"bar", metadata !"bar", metadata !2, i32 4, metadata !11, i1 true, i1 true, i32 0, i32 0, null, i1 false, i1 false} ; [ DW_TAG_subprogram ] +!11 = metadata !{i32 524309, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !12, i32 0, null} ; [ DW_TAG_subroutine_type ] +!12 = metadata !{null, metadata !6, metadata !13, metadata !14} +!13 = metadata !{i32 524324, metadata !2, metadata !"long int", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!14 = metadata !{i32 524303, metadata !2, metadata !"", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 0, null} ; [ DW_TAG_pointer_type ] +!15 = metadata !{i32 4, i32 0, metadata !10, metadata !8} +!16 = metadata !{i32 524545, metadata !10, metadata !"y", metadata !2, i32 4, metadata !13} ; [ DW_TAG_arg_variable ] +!17 = metadata !{i32 524545, metadata !10, metadata !"z", metadata !2, i32 4, metadata !14} ; [ DW_TAG_arg_variable ] +!18 = metadata !{i32 5, i32 0, metadata !10, metadata !8} +!19 = metadata !{i32 10, i32 0, metadata !1, null} From gohman at apple.com Thu May 27 15:26:51 2010 From: gohman at apple.com (Dan Gohman) Date: Thu, 27 May 2010 20:26:51 -0000 Subject: [llvm-commits] [llvm] r104885 - /llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Message-ID: <20100527202651.B2B46312800A@llvm.org> Author: djg Date: Thu May 27 15:26:51 2010 New Revision: 104885 URL: http://llvm.org/viewvc/llvm-project?rev=104885&view=rev Log: Don't flush the raw_ostream in llvm::WriteBitcodeToFile; it's at the wrong level. Clients which need to leave the stream open but which still require the bitcode bits to be on disk should call flush themselves. Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=104885&r1=104884&r2=104885&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original) +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Thu May 27 15:26:51 2010 @@ -1664,9 +1664,6 @@ // Write the generated bitstream to "Out". Out.write((char*)&Buffer.front(), Buffer.size()); - - // Make sure it hits disk now. - Out.flush(); } /// WriteBitcodeToStream - Write the specified module to the specified output From gohman at apple.com Thu May 27 15:47:38 2010 From: gohman at apple.com (Dan Gohman) Date: Thu, 27 May 2010 20:47:38 -0000 Subject: [llvm-commits] [llvm] r104887 - /llvm/trunk/include/llvm/Support/IRReader.h Message-ID: <20100527204738.C3C1A312800A@llvm.org> Author: djg Date: Thu May 27 15:47:38 2010 New Revision: 104887 URL: http://llvm.org/viewvc/llvm-project?rev=104887&view=rev Log: Make ParseIRFile and getLazyIRFileModule incoporate the underlying error message string into their own error message string, so that the information isn't lost. Modified: llvm/trunk/include/llvm/Support/IRReader.h Modified: llvm/trunk/include/llvm/Support/IRReader.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/IRReader.h?rev=104887&r1=104886&r2=104887&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/IRReader.h (original) +++ llvm/trunk/include/llvm/Support/IRReader.h Thu May 27 15:47:38 2010 @@ -60,7 +60,8 @@ MemoryBuffer *F = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), &ErrMsg); if (F == 0) { Err = SMDiagnostic(Filename, - "Could not open input file '" + Filename + "'"); + "Could not open input file " + "'" + Filename + "': " + ErrMsg); return 0; } @@ -98,7 +99,8 @@ MemoryBuffer *F = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), &ErrMsg); if (F == 0) { Err = SMDiagnostic(Filename, - "Could not open input file '" + Filename + "'"); + "Could not open input file " + "'" + Filename + "': " + ErrMsg); return 0; } From gohman at apple.com Thu May 27 15:51:55 2010 From: gohman at apple.com (Dan Gohman) Date: Thu, 27 May 2010 20:51:55 -0000 Subject: [llvm-commits] [llvm] r104888 - in /llvm/trunk: lib/Archive/ArchiveWriter.cpp tools/bugpoint/ExtractFunction.cpp tools/llvm-link/llvm-link.cpp tools/lto/LTOCodeGenerator.cpp Message-ID: <20100527205155.22925312800A@llvm.org> Author: djg Date: Thu May 27 15:51:54 2010 New Revision: 104888 URL: http://llvm.org/viewvc/llvm-project?rev=104888&view=rev Log: Eliminate some unnessary Path::exists() calls. Modified: llvm/trunk/lib/Archive/ArchiveWriter.cpp llvm/trunk/tools/bugpoint/ExtractFunction.cpp llvm/trunk/tools/llvm-link/llvm-link.cpp llvm/trunk/tools/lto/LTOCodeGenerator.cpp Modified: llvm/trunk/lib/Archive/ArchiveWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Archive/ArchiveWriter.cpp?rev=104888&r1=104887&r2=104888&view=diff ============================================================================== --- llvm/trunk/lib/Archive/ArchiveWriter.cpp (original) +++ llvm/trunk/lib/Archive/ArchiveWriter.cpp Thu May 27 15:51:54 2010 @@ -366,8 +366,7 @@ // Check for errors opening or creating archive file. if (!ArchiveFile.is_open() || ArchiveFile.bad()) { - if (TmpArchive.exists()) - TmpArchive.eraseFromDisk(); + TmpArchive.eraseFromDisk(); if (ErrMsg) *ErrMsg = "Error opening archive file: " + archPath.str(); return true; @@ -387,8 +386,7 @@ for (MembersList::iterator I = begin(), E = end(); I != E; ++I) { if (writeMember(*I, ArchiveFile, CreateSymbolTable, TruncateNames, Compress, ErrMsg)) { - if (TmpArchive.exists()) - TmpArchive.eraseFromDisk(); + TmpArchive.eraseFromDisk(); ArchiveFile.close(); return true; } @@ -420,8 +418,7 @@ std::ofstream FinalFile(FinalFilePath.c_str(), io_mode); if (!FinalFile.is_open() || FinalFile.bad()) { - if (TmpArchive.exists()) - TmpArchive.eraseFromDisk(); + TmpArchive.eraseFromDisk(); if (ErrMsg) *ErrMsg = "Error opening archive file: " + FinalFilePath.str(); return true; @@ -438,8 +435,7 @@ if (foreignST) { if (writeMember(*foreignST, FinalFile, false, false, false, ErrMsg)) { FinalFile.close(); - if (TmpArchive.exists()) - TmpArchive.eraseFromDisk(); + TmpArchive.eraseFromDisk(); return true; } } Modified: llvm/trunk/tools/bugpoint/ExtractFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/ExtractFunction.cpp?rev=104888&r1=104887&r2=104888&view=diff ============================================================================== --- llvm/trunk/tools/bugpoint/ExtractFunction.cpp (original) +++ llvm/trunk/tools/bugpoint/ExtractFunction.cpp Thu May 27 15:51:54 2010 @@ -365,8 +365,7 @@ PI.push_back(getPI(createBlockExtractorPass(EmptyBBs))); Module *Ret = runPassesOn(M, PI, false, 1, &ExtraArg); - if (uniqueFilename.exists()) - uniqueFilename.eraseFromDisk(); // Free disk space + uniqueFilename.eraseFromDisk(); // Free disk space if (Ret == 0) { outs() << "*** Basic Block extraction failed, please report a bug!\n"; Modified: llvm/trunk/tools/llvm-link/llvm-link.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-link/llvm-link.cpp?rev=104888&r1=104887&r2=104888&view=diff ============================================================================== --- llvm/trunk/tools/llvm-link/llvm-link.cpp (original) +++ llvm/trunk/tools/llvm-link/llvm-link.cpp Thu May 27 15:51:54 2010 @@ -62,20 +62,14 @@ } SMDiagnostic Err; - if (Filename.exists()) { - if (Verbose) errs() << "Loading '" << Filename.c_str() << "'\n"; - Module* Result = 0; - - const std::string &FNStr = Filename.str(); - Result = ParseIRFile(FNStr, Err, Context); - if (Result) return std::auto_ptr(Result); // Load successful! - - if (Verbose) - Err.Print(argv0, errs()); - } else { - errs() << "Bitcode file: '" << Filename.c_str() << "' does not exist.\n"; - } + if (Verbose) errs() << "Loading '" << Filename.c_str() << "'\n"; + Module* Result = 0; + + const std::string &FNStr = Filename.str(); + Result = ParseIRFile(FNStr, Err, Context); + if (Result) return std::auto_ptr(Result); // Load successful! + Err.Print(argv0, errs()); return std::auto_ptr(); } Modified: llvm/trunk/tools/lto/LTOCodeGenerator.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/LTOCodeGenerator.cpp?rev=104888&r1=104887&r2=104888&view=diff ============================================================================== --- llvm/trunk/tools/lto/LTOCodeGenerator.cpp (original) +++ llvm/trunk/tools/lto/LTOCodeGenerator.cpp Thu May 27 15:51:54 2010 @@ -183,16 +183,14 @@ genResult = this->generateAssemblyCode(asmFile, errMsg); } if ( genResult ) { - if ( uniqueAsmPath.exists() ) - uniqueAsmPath.eraseFromDisk(); + uniqueAsmPath.eraseFromDisk(); return NULL; } // make unique temp .o file to put generated object file sys::PathWithStatus uniqueObjPath("lto-llvm.o"); if ( uniqueObjPath.createTemporaryFileOnDisk(true, &errMsg) ) { - if ( uniqueAsmPath.exists() ) - uniqueAsmPath.eraseFromDisk(); + uniqueAsmPath.eraseFromDisk(); return NULL; } sys::RemoveFileOnSignal(uniqueObjPath); From enderby at apple.com Thu May 27 16:33:19 2010 From: enderby at apple.com (Kevin Enderby) Date: Thu, 27 May 2010 21:33:19 -0000 Subject: [llvm-commits] [llvm] r104890 - in /llvm/trunk: lib/Target/X86/AsmParser/X86AsmParser.cpp test/MC/MachO/jcc.s Message-ID: <20100527213319.CE67D312800A@llvm.org> Author: enderby Date: Thu May 27 16:33:19 2010 New Revision: 104890 URL: http://llvm.org/viewvc/llvm-project?rev=104890&view=rev Log: MC/X86: Add aliases for Jcc variants. Added: llvm/trunk/test/MC/MachO/jcc.s Modified: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp Modified: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp?rev=104890&r1=104889&r2=104890&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp (original) +++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp Thu May 27 16:33:19 2010 @@ -617,6 +617,19 @@ .Case("setnz", "setne") .Case("jz", "je") .Case("jnz", "jne") + .Case("jc", "jb") + .Case("jecxz", "jcxz") + .Case("jna", "jbe") + .Case("jnae", "jb") + .Case("jnb", "jae") + .Case("jnbe", "ja") + .Case("jnc", "jae") + .Case("jng", "jle") + .Case("jnge", "jl") + .Case("jnl", "jge") + .Case("jnle", "jg") + .Case("jpe", "jp") + .Case("jpo", "jnp") .Case("cmovcl", "cmovbl") .Case("cmovcl", "cmovbl") .Case("cmovnal", "cmovbel") Added: llvm/trunk/test/MC/MachO/jcc.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MachO/jcc.s?rev=104890&view=auto ============================================================================== --- llvm/trunk/test/MC/MachO/jcc.s (added) +++ llvm/trunk/test/MC/MachO/jcc.s Thu May 27 16:33:19 2010 @@ -0,0 +1,106 @@ +// RUN: llvm-mc -triple i386-apple-darwin9 %s -filetype=obj -o - | macho-dump --dump-section-data | FileCheck %s + + ja 1f +1: nop + jae 1f +1: nop + jb 1f +1: nop + jbe 1f +1: nop + jc 1f +1: nop + jcxz 1f +1: nop + jecxz 1f +1: nop + je 1f +1: nop + jg 1f +1: nop + jge 1f +1: nop + jl 1f +1: nop + jle 1f +1: nop + jna 1f +1: nop + jnae 1f +1: nop + jnb 1f +1: nop + jnbe 1f +1: nop + jnc 1f +1: nop + jne 1f +1: nop + jng 1f +1: nop + jnge 1f +1: nop + jnl 1f +1: nop + jnle 1f +1: nop + jno 1f +1: nop + jnp 1f +1: nop + jns 1f +1: nop + jnz 1f +1: nop + jo 1f +1: nop + jp 1f +1: nop + jpe 1f +1: nop + jpo 1f +1: nop + js 1f +1: nop + jz 1f +1: nop + +// CHECK: ('cputype', 7) +// CHECK: ('cpusubtype', 3) +// CHECK: ('filetype', 1) +// CHECK: ('num_load_commands', 1) +// CHECK: ('load_commands_size', 124) +// CHECK: ('flag', 0) +// CHECK: ('load_commands', [ +// CHECK: # Load Command 0 +// CHECK: (('command', 1) +// CHECK: ('size', 124) +// CHECK: ('segment_name', '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +// CHECK: ('vm_addr', 0) +// CHECK: ('vm_size', 96) +// CHECK: ('file_offset', 152) +// CHECK: ('file_size', 96) +// CHECK: ('maxprot', 7) +// CHECK: ('initprot', 7) +// CHECK: ('num_sections', 1) +// CHECK: ('flags', 0) +// CHECK: ('sections', [ +// CHECK: # Section 0 +// CHECK: (('section_name', '__text\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +// CHECK: ('segment_name', '__TEXT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +// CHECK: ('address', 0) +// CHECK: ('size', 96) +// CHECK: ('offset', 152) +// CHECK: ('alignment', 0) +// CHECK: ('reloc_offset', 0) +// CHECK: ('num_reloc', 0) +// CHECK: ('flags', 0x80000400) +// CHECK: ('reserved1', 0) +// CHECK: ('reserved2', 0) +// CHECK: ), +// CHECK: ('_relocations', [ +// CHECK: ]) +// CHECK: ('_section_data', 'w\x00\x90s\x00\x90r\x00\x90v\x00\x90r\x00\x90\xe3\x00\x90\xe3\x00\x90t\x00\x90\x7f\x00\x90}\x00\x90|\x00\x90~\x00\x90v\x00\x90r\x00\x90s\x00\x90w\x00\x90s\x00\x90u\x00\x90~\x00\x90|\x00\x90}\x00\x90\x7f\x00\x90q\x00\x90{\x00\x90y\x00\x90u\x00\x90p\x00\x90z\x00\x90z\x00\x90{\x00\x90x\x00\x90t\x00\x90') +// CHECK: ]) +// CHECK: ), +// CHECK: ]) From evan.cheng at apple.com Thu May 27 17:08:38 2010 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 27 May 2010 22:08:38 -0000 Subject: [llvm-commits] [llvm] r104891 - in /llvm/trunk: lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp test/CodeGen/ARM/inlineasm.ll Message-ID: <20100527220838.F1763312800A@llvm.org> Author: evancheng Date: Thu May 27 17:08:38 2010 New Revision: 104891 URL: http://llvm.org/viewvc/llvm-project?rev=104891&view=rev Log: llvm can't correctly support 'H', 'Q' and 'R' modifiers. Just mark it an error. Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp llvm/trunk/test/CodeGen/ARM/inlineasm.ll Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp?rev=104891&r1=104890&r2=104891&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Thu May 27 17:08:38 2010 @@ -1064,27 +1064,11 @@ printOperand(MI, OpNum, O); return false; case 'Q': - // Print the least significant half of a register pair. - if (TM.getTargetData()->isBigEndian()) - break; - printOperand(MI, OpNum, O); - return false; case 'R': - // Print the most significant half of a register pair. - if (TM.getTargetData()->isLittleEndian()) - break; - printOperand(MI, OpNum, O); - return false; case 'H': - break; - } - // Print the second half of a register pair (for 'Q', 'R' or 'H'). - // Verify that this operand has two consecutive registers. - if (!MI->getOperand(OpNum).isReg() || - OpNum+1 == MI->getNumOperands() || - !MI->getOperand(OpNum+1).isReg()) + llvm_unreachable("llvm does not support 'Q', 'R', and 'H' modifiers!"); return true; - ++OpNum; + } } printOperand(MI, OpNum, O); Modified: llvm/trunk/test/CodeGen/ARM/inlineasm.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/inlineasm.ll?rev=104891&r1=104890&r2=104891&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/inlineasm.ll (original) +++ llvm/trunk/test/CodeGen/ARM/inlineasm.ll Thu May 27 17:08:38 2010 @@ -6,14 +6,6 @@ } define void @test2() { - %tmp1 = call i64 asm "ldmia $1!, {$0, ${0:H}}", "=r,=*r,1"( i32** null, i32* null ) ; [#uses=2] - %tmp2 = lshr i64 %tmp1, 32 ; [#uses=1] - %tmp3 = trunc i64 %tmp2 to i32 ; [#uses=1] - %tmp4 = call i32 asm "pkhbt $0, $1, $2, lsl #16", "=r,r,r"( i32 0, i32 %tmp3 ) ; [#uses=0] - ret void -} - -define void @test3() { tail call void asm sideeffect "/* number: ${0:c} */", "i"( i32 1 ) ret void } From evan.cheng at apple.com Thu May 27 17:21:21 2010 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 27 May 2010 15:21:21 -0700 Subject: [llvm-commits] [llvm] r104653 - /llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp In-Reply-To: References: <20100526002505.7DBA93128034@llvm.org> <7C8551B3-8E39-484E-A2DB-C830636F141B@apple.com> Message-ID: <6DD1CB04-9E57-43FF-BD93-F02A48467D95@apple.com> On May 26, 2010, at 6:19 PM, Shih-wei Liao wrote: > I hope to address the valid concern. I spent time today in retrying. Unfortunately I think it's hard to find a way to generalize these instructions. BFC and BFI are really "special" ones. So I think they deserve these 5 lines of encoding in the patch. > Compared with 1600 lines in ARMCodeEmitter.cpp, maybe these lines are not adding too much. My apologies for not being able to cut down to 0. Ok. Thanks for making the effort! Evan > > On Wed, May 26, 2010 at 2:15 AM, Shih-wei Liao wrote: > I agree that it's probably too easy to add one more to the many cases in ARMCodeEmitter.cpp. My bad. If changing ARM*.td can fix the bugs completely, that will be the best. Anyone knows of a better patch that's doable now? That will be great. I tried and stopped after the irregularities like widthm1 encoding and so on. > > Probably we should overhaul the ARM*.td some time soon. Currently these 2 if-conditions can make the ARM JIT usable first, and I agree that I should strive for a better solution. Stay tuned. > > On Tue, May 25, 2010 at 10:07 PM, Evan Cheng wrote: > > > > Sorry I have been behind on patch reviews. I have some concerns about these patches. We want to prevent special casing for individual instructions. Is it not possible to add generic support for these? > > > > Evan > > > > On May 25, 2010, at 5:25 PM, Shih-wei Liao wrote: > > > > > Author: sliao > > > Date: Tue May 25 19:25:05 2010 > > > New Revision: 104653 > > > > > > URL: http://llvm.org/viewvc/llvm-project?rev=104653&view=rev > > > Log: > > > Adding the missing implementation of Bitfield's "clear" and "insert". > > > Fixing http://llvm.org/bugs/show_bug.cgi?id=7222. > > > > > > Modified: > > > llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp > > > > > > Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp > > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=104653&r1=104652&r2=104653&view=diff > > > ============================================================================== > > > --- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original) > > > +++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Tue May 25 19:25:05 2010 > > > @@ -781,10 +781,6 @@ > > > unsigned ImplicitRn) { > > > const TargetInstrDesc &TID = MI.getDesc(); > > > > > > - if (TID.Opcode == ARM::BFC) { > > > - report_fatal_error("ARMv6t2 JIT is not yet supported."); > > > - } > > > - > > > // Part of binary is determined by TableGn. > > > unsigned Binary = getBinaryCodeForInstr(MI); > > > > > > @@ -820,6 +816,15 @@ > > > Binary |= ((Hi16 >> 12) & 0xF) << 16; > > > emitWordLE(Binary); > > > return; > > > + } else if((TID.Opcode == ARM::BFC) || (TID.Opcode == ARM::BFI)) { > > > + uint32_t v = ~MI.getOperand(2).getImm(); > > > + int32_t lsb = CountTrailingZeros_32(v); > > > + int32_t msb = (32 - CountLeadingZeros_32(v)) - 1; > > > + // Insts[20-16] = msb, Insts[11-7] = lsb > > > + Binary |= (msb & 0x1F) << 16; > > > + Binary |= (lsb & 0x1F) << 7; > > > + emitWordLE(Binary); > > > + return; > > > } > > > > > > // If this is a two-address operand, skip it. e.g. MOVCCr operand 1. > > > > > > > > > _______________________________________________ > > > llvm-commits mailing list > > > llvm-commits at cs.uiuc.edu > > > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > > > -- > Thanks, > Shih-wei > > > > -- > Thanks, > Shih-wei -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100527/5e5bdf0c/attachment.html From nlewycky at google.com Thu May 27 17:28:56 2010 From: nlewycky at google.com (Nick Lewycky) Date: Thu, 27 May 2010 15:28:56 -0700 Subject: [llvm-commits] [llvm] r104884 - in /llvm/trunk: lib/CodeGen/AsmPrinter/DwarfDebug.cpp lib/Transforms/Utils/PromoteMemoryToRegister.cpp test/Transforms/Mem2Reg/ConvertDebugInfo2.ll In-Reply-To: <20100527202504.E51BA312800A@llvm.org> References: <20100527202504.E51BA312800A@llvm.org> Message-ID: On 27 May 2010 13:25, Devang Patel wrote: > Author: dpatel > Date: Thu May 27 15:25:04 2010 > New Revision: 104884 > > URL: http://llvm.org/viewvc/llvm-project?rev=104884&view=rev > Log: > Do not drop location info for inlined function args. > > Added: > llvm/trunk/test/Transforms/Mem2Reg/ConvertDebugInfo2.ll > Modified: > llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp > llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp > > Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=104884&r1=104883&r2=104884&view=diff > > ============================================================================== > --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) > +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Thu May 27 15:25:04 > 2010 > @@ -2200,7 +2200,11 @@ > } > > DbgScope *Scope = findDbgScope(MInsn); > - if (!Scope && DV.getTag() == dwarf::DW_TAG_arg_variable) > + bool CurFnArg = false; > + if (DV.getTag() == dwarf::DW_TAG_arg_variable && > + DISubprogram(DV.getContext()).describes(MF->getFunction())) > + CurFnArg = true; > + if (!Scope && CurFnArg) > Scope = CurrentFnDbgScope; > // If variable scope is not found then skip this variable. > if (!Scope) > @@ -2209,7 +2213,7 @@ > Processed.insert(DV); > DbgVariable *RegVar = new DbgVariable(DV); > Scope->addVariable(RegVar); > - if (DV.getTag() != dwarf::DW_TAG_arg_variable) > + if (!CurFnArg) > DbgVariableLabelsMap[RegVar] = getLabelBeforeInsn(MInsn); > if (DbgVariable *AbsVar = findAbstractVariable(DV, > MInsn->getDebugLoc())) { > DbgVariableToDbgInstMap[AbsVar] = MInsn; > > Modified: llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp?rev=104884&r1=104883&r2=104884&view=diff > > ============================================================================== > --- llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp (original) > +++ llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Thu May 27 > 15:25:04 2010 > @@ -897,6 +897,11 @@ > // Propagate any debug metadata from the store onto the dbg.value. > if (MDNode *SIMD = SI->getMetadata("dbg")) > DbgVal->setMetadata("dbg", SIMD); > + // Otherwise propgate debug metadata from dbg.delcare for inlined fn > args. > Typo: dbg.delcare Nick + else if (!DISubprogram(DIVar.getContext()). > + describes(DDI->getParent()->getParent())) > + if (MDNode *MD = DDI->getMetadata("dbg")) > + DbgVal->setMetadata("dbg", MD); > } > > // QueuePhiNode - queues a phi-node to be added to a basic-block for a > specific > > Added: llvm/trunk/test/Transforms/Mem2Reg/ConvertDebugInfo2.ll > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Mem2Reg/ConvertDebugInfo2.ll?rev=104884&view=auto > > ============================================================================== > --- llvm/trunk/test/Transforms/Mem2Reg/ConvertDebugInfo2.ll (added) > +++ llvm/trunk/test/Transforms/Mem2Reg/ConvertDebugInfo2.ll Thu May 27 > 15:25:04 2010 > @@ -0,0 +1,52 @@ > +; RUN: opt -mem2reg < %s | llvm-dis | grep ".dbg "| count 6 > + > +declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone > + > +declare void @foo(i32, i64, i8*) > + > +define void @baz(i32 %a) nounwind ssp { > +entry: > + %x_addr.i = alloca i32 ; [#uses=2] > + %y_addr.i = alloca i64 ; [#uses=2] > + %z_addr.i = alloca i8* ; [#uses=2] > + %a_addr = alloca i32 ; [#uses=2] > + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] > + call void @llvm.dbg.declare(metadata !{i32* %a_addr}, metadata !0), !dbg > !7 > + store i32 %a, i32* %a_addr > + %0 = load i32* %a_addr, align 4, !dbg !8 ; [#uses=1] > + call void @llvm.dbg.declare(metadata !{i32* %x_addr.i}, metadata !9) > nounwind, !dbg !15 > + store i32 %0, i32* %x_addr.i > + call void @llvm.dbg.declare(metadata !{i64* %y_addr.i}, metadata !16) > nounwind, !dbg !15 > + store i64 55, i64* %y_addr.i > + call void @llvm.dbg.declare(metadata !{i8** %z_addr.i}, metadata !17) > nounwind, !dbg !15 > + store i8* bitcast (void (i32)* @baz to i8*), i8** %z_addr.i > + %1 = load i32* %x_addr.i, align 4, !dbg !18 ; [#uses=1] > + %2 = load i64* %y_addr.i, align 8, !dbg !18 ; [#uses=1] > + %3 = load i8** %z_addr.i, align 8, !dbg !18 ; [#uses=1] > + call void @foo(i32 %1, i64 %2, i8* %3) nounwind, !dbg !18 > + br label %return, !dbg !19 > + > +return: ; preds = %entry > + ret void, !dbg !19 > +} > + > +!0 = metadata !{i32 524545, metadata !1, metadata !"a", metadata !2, i32 > 8, metadata !6} ; [ DW_TAG_arg_variable ] > +!1 = metadata !{i32 524334, i32 0, metadata !2, metadata !"baz", metadata > !"baz", metadata !"baz", metadata !2, i32 8, metadata !4, i1 false, i1 true, > i32 0, i32 0, null, i1 false, i1 false} ; [ DW_TAG_subprogram ] > +!2 = metadata !{i32 524329, metadata !"bar.c", metadata !"/tmp/", metadata > !3} ; [ DW_TAG_file_type ] > +!3 = metadata !{i32 524305, i32 0, i32 1, metadata !"bar.c", metadata > !"/tmp/", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", > i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] > +!4 = metadata !{i32 524309, metadata !2, metadata !"", metadata !2, i32 0, > i64 0, i64 0, i64 0, i32 0, null, metadata !5, i32 0, null} ; [ > DW_TAG_subroutine_type ] > +!5 = metadata !{null, metadata !6} > +!6 = metadata !{i32 524324, metadata !2, metadata !"int", metadata !2, i32 > 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] > +!7 = metadata !{i32 8, i32 0, metadata !1, null} > +!8 = metadata !{i32 9, i32 0, metadata !1, null} > +!9 = metadata !{i32 524545, metadata !10, metadata !"x", metadata !2, i32 > 4, metadata !6} ; [ DW_TAG_arg_variable ] > +!10 = metadata !{i32 524334, i32 0, metadata !2, metadata !"bar", metadata > !"bar", metadata !"bar", metadata !2, i32 4, metadata !11, i1 true, i1 true, > i32 0, i32 0, null, i1 false, i1 false} ; [ DW_TAG_subprogram ] > +!11 = metadata !{i32 524309, metadata !2, metadata !"", metadata !2, i32 > 0, i64 0, i64 0, i64 0, i32 0, null, metadata !12, i32 0, null} ; [ > DW_TAG_subroutine_type ] > +!12 = metadata !{null, metadata !6, metadata !13, metadata !14} > +!13 = metadata !{i32 524324, metadata !2, metadata !"long int", metadata > !2, i32 0, i64 64, i64 64, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] > +!14 = metadata !{i32 524303, metadata !2, metadata !"", metadata !2, i32 > 0, i64 64, i64 64, i64 0, i32 0, null} ; [ DW_TAG_pointer_type ] > +!15 = metadata !{i32 4, i32 0, metadata !10, metadata !8} > +!16 = metadata !{i32 524545, metadata !10, metadata !"y", metadata !2, i32 > 4, metadata !13} ; [ DW_TAG_arg_variable ] > +!17 = metadata !{i32 524545, metadata !10, metadata !"z", metadata !2, i32 > 4, metadata !14} ; [ DW_TAG_arg_variable ] > +!18 = metadata !{i32 5, i32 0, metadata !10, metadata !8} > +!19 = metadata !{i32 10, i32 0, metadata !1, null} > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100527/880ba117/attachment.html From wdietz2 at illinois.edu Thu May 27 17:27:59 2010 From: wdietz2 at illinois.edu (Will Dietz) Date: Thu, 27 May 2010 22:27:59 -0000 Subject: [llvm-commits] [poolalloc] r104894 - /poolalloc/trunk/tools/Pa/pa.cpp Message-ID: <20100527222759.7652D312800A@llvm.org> Author: wdietz2 Date: Thu May 27 17:27:59 2010 New Revision: 104894 URL: http://llvm.org/viewvc/llvm-project?rev=104894&view=rev Log: tools/pa: remove try/catch block since we're exception-free Modified: poolalloc/trunk/tools/Pa/pa.cpp Modified: poolalloc/trunk/tools/Pa/pa.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/tools/Pa/pa.cpp?rev=104894&r1=104893&r2=104894&view=diff ============================================================================== --- poolalloc/trunk/tools/Pa/pa.cpp (original) +++ poolalloc/trunk/tools/Pa/pa.cpp Thu May 27 17:27:59 2010 @@ -68,104 +68,95 @@ // main - Entry point for the sc compiler. // int main(int argc, char **argv) { - std::string mt; - std::string & msg = mt; - try { - cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n"); - sys::PrintStackTraceOnErrorSignal(); - - // Load the module to be compiled... - std::auto_ptr M; - std::string ErrorMessage; - if (MemoryBuffer *Buffer - = MemoryBuffer::getFileOrSTDIN(InputFilename, &ErrorMessage)) { - M.reset(ParseBitcodeFile(Buffer, getGlobalContext(), &ErrorMessage)); - delete Buffer; - } + cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n"); + sys::PrintStackTraceOnErrorSignal(); - if (M.get() == 0) { - std::cerr << argv[0] << ": bytecode didn't read correctly.\n"; - return 1; - } + // Load the module to be compiled... + std::auto_ptr M; + std::string ErrorMessage; + if (MemoryBuffer *Buffer + = MemoryBuffer::getFileOrSTDIN(InputFilename, &ErrorMessage)) { + M.reset(ParseBitcodeFile(Buffer, getGlobalContext(), &ErrorMessage)); + delete Buffer; + } - // Build up all of the passes that we want to do to the module... - PassManager Passes; + if (M.get() == 0) { + std::cerr << argv[0] << ": bytecode didn't read correctly.\n"; + return 1; + } - Passes.add(new TargetData(M.get())); + // Build up all of the passes that we want to do to the module... + PassManager Passes; - // Currently deactiviated - Passes.add(new PoolAllocate()); + Passes.add(new TargetData(M.get())); - // Verify the final result - Passes.add(createVerifierPass()); - - // Figure out where we are going to send the output... - raw_fd_ostream *Out = 0; - std::string error; - if (OutputFilename != "") { - if (OutputFilename != "-") { - // Specified an output filename? - if (!Force && std::ifstream(OutputFilename.c_str())) { - // If force is not specified, make sure not to overwrite a file! - std::cerr << argv[0] << ": error opening '" << OutputFilename - << "': file exists!\n" - << "Use -f command line argument to force output\n"; - return 1; - } - Out = new raw_fd_ostream (OutputFilename.c_str(), error); - - // Make sure that the Out file gets unlinked from the disk if we get a - // SIGINT - sys::RemoveFileOnSignal(sys::Path(OutputFilename)); - } else { - Out = new raw_stdout_ostream(); - } - } else { - if (InputFilename == "-") { - OutputFilename = "-"; - Out = new raw_stdout_ostream(); - } else { - OutputFilename = GetFileNameRoot(InputFilename); - - OutputFilename += ".abc.bc"; - } + // Currently deactiviated + Passes.add(new PoolAllocate()); + // Verify the final result + Passes.add(createVerifierPass()); + + // Figure out where we are going to send the output... + raw_fd_ostream *Out = 0; + std::string error; + if (OutputFilename != "") { + if (OutputFilename != "-") { + // Specified an output filename? if (!Force && std::ifstream(OutputFilename.c_str())) { // If force is not specified, make sure not to overwrite a file! - std::cerr << argv[0] << ": error opening '" << OutputFilename - << "': file exists!\n" - << "Use -f command line argument to force output\n"; - return 1; - } - - Out = new raw_fd_ostream(OutputFilename.c_str(), error); - if (error.length()) { - std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n"; - delete Out; + std::cerr << argv[0] << ": error opening '" << OutputFilename + << "': file exists!\n" + << "Use -f command line argument to force output\n"; return 1; } + Out = new raw_fd_ostream (OutputFilename.c_str(), error); // Make sure that the Out file gets unlinked from the disk if we get a // SIGINT sys::RemoveFileOnSignal(sys::Path(OutputFilename)); + } else { + Out = new raw_stdout_ostream(); } - - // Add the writing of the output file to the list of passes - Passes.add (createBitcodeWriterPass(*Out)); - - // Run our queue of passes all at once now, efficiently. - Passes.run(*M.get()); - - // Delete the ostream - delete Out; - - return 0; - } catch (msg) { - std::cerr << argv[0] << ": " << msg << "\n"; - } catch (...) { - std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n"; + } else { + if (InputFilename == "-") { + OutputFilename = "-"; + Out = new raw_stdout_ostream(); + } else { + OutputFilename = GetFileNameRoot(InputFilename); + + OutputFilename += ".abc.bc"; + } + + if (!Force && std::ifstream(OutputFilename.c_str())) { + // If force is not specified, make sure not to overwrite a file! + std::cerr << argv[0] << ": error opening '" << OutputFilename + << "': file exists!\n" + << "Use -f command line argument to force output\n"; + return 1; + } + + Out = new raw_fd_ostream(OutputFilename.c_str(), error); + if (error.length()) { + std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n"; + delete Out; + return 1; + } + + // Make sure that the Out file gets unlinked from the disk if we get a + // SIGINT + sys::RemoveFileOnSignal(sys::Path(OutputFilename)); } - return 1; + + // Add the writing of the output file to the list of passes + Passes.add (createBitcodeWriterPass(*Out)); + + // Run our queue of passes all at once now, efficiently. + Passes.run(*M.get()); + + // Delete the ostream + delete Out; + + return 0; } From gohman at apple.com Thu May 27 18:11:55 2010 From: gohman at apple.com (Dan Gohman) Date: Thu, 27 May 2010 23:11:55 -0000 Subject: [llvm-commits] [llvm] r104896 - /llvm/trunk/lib/System/Unix/Signals.inc Message-ID: <20100527231155.A6928312800A@llvm.org> Author: djg Date: Thu May 27 18:11:55 2010 New Revision: 104896 URL: http://llvm.org/viewvc/llvm-project?rev=104896&view=rev Log: Factor out the handler work from SignalHandler into a helper function, and change llvm::sys::RunInterruptHandlers to call that function directly instead of calling SignalHandler, because the rest of SignalHandler invokes side effects which aren't appropriate, including raising the signal. Modified: llvm/trunk/lib/System/Unix/Signals.inc Modified: llvm/trunk/lib/System/Unix/Signals.inc URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/System/Unix/Signals.inc?rev=104896&r1=104895&r2=104896&view=diff ============================================================================== --- llvm/trunk/lib/System/Unix/Signals.inc (original) +++ llvm/trunk/lib/System/Unix/Signals.inc Thu May 27 18:11:55 2010 @@ -111,6 +111,14 @@ } +/// RemoveFilesToRemove - Process the FilesToRemove list. This function +/// should be called with the SignalsMutex lock held. +static void RemoveFilesToRemove() { + while (!FilesToRemove.empty()) { + FilesToRemove.back().eraseFromDisk(true); + FilesToRemove.pop_back(); + } +} // SignalHandler - The signal handler that runs. static RETSIGTYPE SignalHandler(int Sig) { @@ -126,10 +134,7 @@ sigprocmask(SIG_UNBLOCK, &SigMask, 0); SignalsMutex.acquire(); - while (!FilesToRemove.empty()) { - FilesToRemove.back().eraseFromDisk(true); - FilesToRemove.pop_back(); - } + RemoveFilesToRemove(); if (std::find(IntSigs, IntSigsEnd, Sig) != IntSigsEnd) { if (InterruptFunction) { @@ -153,7 +158,9 @@ } void llvm::sys::RunInterruptHandlers() { - SignalHandler(SIGINT); + SignalsMutex.acquire(); + RemoveFilesToRemove(); + SignalsMutex.release(); } void llvm::sys::SetInterruptFunction(void (*IF)()) { From grosbach at apple.com Thu May 27 18:11:57 2010 From: grosbach at apple.com (Jim Grosbach) Date: Thu, 27 May 2010 23:11:57 -0000 Subject: [llvm-commits] [llvm] r104897 - in /llvm/trunk: include/llvm/CodeGen/ISDOpcodes.h include/llvm/Intrinsics.td lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMISelLowering.h Message-ID: <20100527231157.D8F003128018@llvm.org> Author: grosbach Date: Thu May 27 18:11:57 2010 New Revision: 104897 URL: http://llvm.org/viewvc/llvm-project?rev=104897&view=rev Log: back out 104862/104869. Can reuse stacksave after all. Very cool. Modified: llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h llvm/trunk/include/llvm/Intrinsics.td llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.h Modified: llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h?rev=104897&r1=104896&r2=104897&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h (original) +++ llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h Thu May 27 18:11:57 2010 @@ -72,9 +72,6 @@ // parent's frame or return address, and so on. FRAMEADDR, RETURNADDR, - // STACKADDR - The current stack pointer address. - STACKADDR, - // FRAME_TO_ARGS_OFFSET - This node represents offset from frame pointer to // first (possible) on-stack argument. This is needed for correct stack // adjustment during unwind. Modified: llvm/trunk/include/llvm/Intrinsics.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=104897&r1=104896&r2=104897&view=diff ============================================================================== --- llvm/trunk/include/llvm/Intrinsics.td (original) +++ llvm/trunk/include/llvm/Intrinsics.td Thu May 27 18:11:57 2010 @@ -197,13 +197,12 @@ def int_returnaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>; def int_frameaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>; -// Note: we treat stacksave/stackrestore and stackaddr as writemem because we -// don't otherwise model their dependencies on allocas. +// Note: we treat stacksave/stackrestore as writemem because we don't otherwise +// model their dependencies on allocas. def int_stacksave : Intrinsic<[llvm_ptr_ty]>, GCCBuiltin<"__builtin_stack_save">; def int_stackrestore : Intrinsic<[], [llvm_ptr_ty]>, GCCBuiltin<"__builtin_stack_restore">; -def int_stackaddress : Intrinsic<[llvm_ptr_ty], []>; // IntrWriteArgMem is more pessimistic than strictly necessary for prefetch, // however it does conveniently prevent the prefetch from being reordered Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=104897&r1=104896&r2=104897&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Thu May 27 18:11:57 2010 @@ -3756,10 +3756,6 @@ setValue(&I, DAG.getNode(ISD::FRAMEADDR, dl, TLI.getPointerTy(), getValue(I.getOperand(1)))); return 0; - case Intrinsic::stackaddress: - setValue(&I, DAG.getNode(ISD::STACKADDR, dl, TLI.getPointerTy(), getRoot(), - getValue(I.getOperand(1)))); - return 0; case Intrinsic::setjmp: return "_setjmp"+!TLI.usesUnderscoreSetJmp(); case Intrinsic::longjmp: Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=104897&r1=104896&r2=104897&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Thu May 27 18:11:57 2010 @@ -2183,13 +2183,6 @@ return FrameAddr; } -SDValue ARMTargetLowering::LowerSTACKADDR(SDValue Op, SelectionDAG &DAG) const { - EVT VT = Op.getValueType(); - DebugLoc dl = Op.getDebugLoc(); // FIXME probably not meaningful - SDValue StackAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, ARM::SP, VT); - return StackAddr; -} - /// ExpandBIT_CONVERT - If the target supports VFP, this function is called to /// expand a bit convert where either the source or destination type is i64 to /// use a VMOVDRR or VMOVRRD node. This should not be done when the non-i64 @@ -3194,7 +3187,6 @@ case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG); case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG); case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); - case ISD::STACKADDR: return LowerSTACKADDR(Op, DAG); case ISD::GLOBAL_OFFSET_TABLE: return LowerGLOBAL_OFFSET_TABLE(Op, DAG); case ISD::EH_SJLJ_SETJMP: return LowerEH_SJLJ_SETJMP(Op, DAG); case ISD::EH_SJLJ_LONGJMP: return LowerEH_SJLJ_LONGJMP(Op, DAG); Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=104897&r1=104896&r2=104897&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Thu May 27 18:11:57 2010 @@ -305,7 +305,6 @@ SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const; SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const; SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; - SDValue LowerSTACKADDR(SDValue Op, SelectionDAG &DAG) const; SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const; SDValue LowerShiftRightParts(SDValue Op, SelectionDAG &DAG) const; SDValue LowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const; From clattner at apple.com Thu May 27 18:33:52 2010 From: clattner at apple.com (Chris Lattner) Date: Thu, 27 May 2010 16:33:52 -0700 Subject: [llvm-commits] [llvm] r104891 - in /llvm/trunk: lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp test/CodeGen/ARM/inlineasm.ll In-Reply-To: <20100527220838.F1763312800A@llvm.org> References: <20100527220838.F1763312800A@llvm.org> Message-ID: <6954CBD8-3E8C-46E4-8405-240F5E0DA751@apple.com> On May 27, 2010, at 3:08 PM, Evan Cheng wrote: > Author: evancheng > Date: Thu May 27 17:08:38 2010 > New Revision: 104891 > > URL: http://llvm.org/viewvc/llvm-project?rev=104891&view=rev > Log: > llvm can't correctly support 'H', 'Q' and 'R' modifiers. Just mark it an error. Evan, this should use report_fatal_error, not llvm_unreachable. -Chris > > Modified: > llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp > llvm/trunk/test/CodeGen/ARM/inlineasm.ll > > Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp?rev=104891&r1=104890&r2=104891&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp (original) > +++ llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Thu May 27 17:08:38 2010 > @@ -1064,27 +1064,11 @@ > printOperand(MI, OpNum, O); > return false; > case 'Q': > - // Print the least significant half of a register pair. > - if (TM.getTargetData()->isBigEndian()) > - break; > - printOperand(MI, OpNum, O); > - return false; > case 'R': > - // Print the most significant half of a register pair. > - if (TM.getTargetData()->isLittleEndian()) > - break; > - printOperand(MI, OpNum, O); > - return false; > case 'H': > - break; > - } > - // Print the second half of a register pair (for 'Q', 'R' or 'H'). > - // Verify that this operand has two consecutive registers. > - if (!MI->getOperand(OpNum).isReg() || > - OpNum+1 == MI->getNumOperands() || > - !MI->getOperand(OpNum+1).isReg()) > + llvm_unreachable("llvm does not support 'Q', 'R', and 'H' modifiers!"); > return true; > - ++OpNum; > + } > } > > printOperand(MI, OpNum, O); > > Modified: llvm/trunk/test/CodeGen/ARM/inlineasm.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/inlineasm.ll?rev=104891&r1=104890&r2=104891&view=diff > ============================================================================== > --- llvm/trunk/test/CodeGen/ARM/inlineasm.ll (original) > +++ llvm/trunk/test/CodeGen/ARM/inlineasm.ll Thu May 27 17:08:38 2010 > @@ -6,14 +6,6 @@ > } > > define void @test2() { > - %tmp1 = call i64 asm "ldmia $1!, {$0, ${0:H}}", "=r,=*r,1"( i32** null, i32* null ) ; [#uses=2] > - %tmp2 = lshr i64 %tmp1, 32 ; [#uses=1] > - %tmp3 = trunc i64 %tmp2 to i32 ; [#uses=1] > - %tmp4 = call i32 asm "pkhbt $0, $1, $2, lsl #16", "=r,r,r"( i32 0, i32 %tmp3 ) ; [#uses=0] > - ret void > -} > - > -define void @test3() { > tail call void asm sideeffect "/* number: ${0:c} */", "i"( i32 1 ) > ret void > } > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From evan.cheng at apple.com Thu May 27 18:45:31 2010 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 27 May 2010 23:45:31 -0000 Subject: [llvm-commits] [llvm] r104899 - /llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Message-ID: <20100527234531.674F4312800A@llvm.org> Author: evancheng Date: Thu May 27 18:45:31 2010 New Revision: 104899 URL: http://llvm.org/viewvc/llvm-project?rev=104899&view=rev Log: Use report_fatal_error, not llvm_unreachable. Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp?rev=104899&r1=104898&r2=104899&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Thu May 27 18:45:31 2010 @@ -1066,7 +1066,7 @@ case 'Q': case 'R': case 'H': - llvm_unreachable("llvm does not support 'Q', 'R', and 'H' modifiers!"); + report_fatal_error("llvm does not support 'Q', 'R', and 'H' modifiers!"); return true; } } From grosbach at apple.com Thu May 27 18:49:24 2010 From: grosbach at apple.com (Jim Grosbach) Date: Thu, 27 May 2010 23:49:24 -0000 Subject: [llvm-commits] [llvm] r104900 - in /llvm/trunk/lib: CodeGen/SelectionDAG/LegalizeDAG.cpp CodeGen/SjLjEHPrepare.cpp Target/ARM/ARMBaseInstrInfo.cpp Target/ARM/ARMISelLowering.cpp Target/ARM/ARMInstrInfo.td Target/ARM/ARMInstrThumb.td Target/ARM/ARMInstrThumb2.td Message-ID: <20100527234924.89936312800A@llvm.org> Author: grosbach Date: Thu May 27 18:49:24 2010 New Revision: 104900 URL: http://llvm.org/viewvc/llvm-project?rev=104900&view=rev Log: Update the saved stack pointer in the sjlj function context following either an alloca() or an llvm.stackrestore(). rdar://8031573 Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp llvm/trunk/lib/CodeGen/SjLjEHPrepare.cpp llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMInstrInfo.td llvm/trunk/lib/Target/ARM/ARMInstrThumb.td llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=104900&r1=104899&r2=104900&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Thu May 27 18:49:24 2010 @@ -862,6 +862,8 @@ case ISD::TRAMPOLINE: case ISD::FRAMEADDR: case ISD::RETURNADDR: + case ISD::EH_SJLJ_SETJMP: + case ISD::EH_SJLJ_LONGJMP: // These operations lie about being legal: when they claim to be legal, // they should actually be custom-lowered. Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0)); Modified: llvm/trunk/lib/CodeGen/SjLjEHPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SjLjEHPrepare.cpp?rev=104900&r1=104899&r2=104900&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SjLjEHPrepare.cpp (original) +++ llvm/trunk/lib/CodeGen/SjLjEHPrepare.cpp Thu May 27 18:49:24 2010 @@ -46,6 +46,8 @@ Constant *UnregisterFn; Constant *BuiltinSetjmpFn; Constant *FrameAddrFn; + Constant *StackAddrFn; + Constant *StackRestoreFn; Constant *LSDAAddrFn; Value *PersonalityFn; Constant *SelectorFn; @@ -107,6 +109,8 @@ PointerType::getUnqual(FunctionContextTy), (Type *)0); FrameAddrFn = Intrinsic::getDeclaration(&M, Intrinsic::frameaddress); + StackAddrFn = Intrinsic::getDeclaration(&M, Intrinsic::stacksave); + StackRestoreFn = Intrinsic::getDeclaration(&M, Intrinsic::stackrestore); BuiltinSetjmpFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_setjmp); LSDAAddrFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_lsda); SelectorFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_selector); @@ -294,14 +298,22 @@ // If we don't have any invokes or unwinds, there's nothing to do. if (Unwinds.empty() && Invokes.empty()) return false; - // Find the eh.selector.* and eh.exception calls. We'll use the first - // eh.selector to determine the right personality function to use. For - // SJLJ, we always use the same personality for the whole function, - // not on a per-selector basis. + // Find the eh.selector.*, eh.exception and alloca calls. + // + // Remember any allocas() that aren't in the entry block, as the + // jmpbuf saved SP will need to be updated for them. + // + // We'll use the first eh.selector to determine the right personality + // function to use. For SJLJ, we always use the same personality for the + // whole function, not on a per-selector basis. // FIXME: That's a bit ugly. Better way? SmallVector EH_Selectors; SmallVector EH_Exceptions; - for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { + SmallVector JmpbufUpdatePoints; + // Note: Skip the entry block since there's nothing there that interests + // us. eh.selector and eh.exception shouldn't ever be there, and we + // want to disregard any allocas that are there. + for (Function::iterator BB = F.begin(), E = F.end(); ++BB != E;) { for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) { if (CallInst *CI = dyn_cast(I)) { if (CI->getCalledFunction() == SelectorFn) { @@ -309,7 +321,11 @@ EH_Selectors.push_back(CI); } else if (CI->getCalledFunction() == ExceptionFn) { EH_Exceptions.push_back(CI); + } else if (CI->getCalledFunction() == StackRestoreFn) { + JmpbufUpdatePoints.push_back(CI); } + } else if (AllocaInst *AI = dyn_cast(I)) { + JmpbufUpdatePoints.push_back(AI); } } } @@ -419,7 +435,7 @@ // Populate the Function Context // 1. LSDA address // 2. Personality function address - // 3. jmpbuf (save FP and call eh.sjlj.setjmp) + // 3. jmpbuf (save SP, FP and call eh.sjlj.setjmp) // LSDA address Idxs[0] = Zero; @@ -440,31 +456,41 @@ new StoreInst(PersonalityFn, PersonalityFieldPtr, true, EntryBB->getTerminator()); - // Save the frame pointer. + // Save the frame pointer. Idxs[1] = ConstantInt::get(Int32Ty, 5); - Value *FieldPtr + Value *JBufPtr = GetElementPtrInst::Create(FunctionContext, Idxs, Idxs+2, "jbuf_gep", EntryBB->getTerminator()); Idxs[1] = ConstantInt::get(Int32Ty, 0); - Value *ElemPtr = - GetElementPtrInst::Create(FieldPtr, Idxs, Idxs+2, "jbuf_fp_gep", + Value *FramePtr = + GetElementPtrInst::Create(JBufPtr, Idxs, Idxs+2, "jbuf_fp_gep", EntryBB->getTerminator()); Value *Val = CallInst::Create(FrameAddrFn, ConstantInt::get(Int32Ty, 0), "fp", EntryBB->getTerminator()); - new StoreInst(Val, ElemPtr, true, EntryBB->getTerminator()); - // Call the setjmp instrinsic. It fills in the rest of the jmpbuf + new StoreInst(Val, FramePtr, true, EntryBB->getTerminator()); + + // Save the stack pointer. + Idxs[1] = ConstantInt::get(Int32Ty, 2); + Value *StackPtr = + GetElementPtrInst::Create(JBufPtr, Idxs, Idxs+2, "jbuf_sp_gep", + EntryBB->getTerminator()); + + Val = CallInst::Create(StackAddrFn, "sp", EntryBB->getTerminator()); + new StoreInst(Val, StackPtr, true, EntryBB->getTerminator()); + + // Call the setjmp instrinsic. It fills in the rest of the jmpbuf. Value *SetjmpArg = - CastInst::Create(Instruction::BitCast, FieldPtr, + CastInst::Create(Instruction::BitCast, JBufPtr, Type::getInt8PtrTy(F.getContext()), "", EntryBB->getTerminator()); Value *DispatchVal = CallInst::Create(BuiltinSetjmpFn, SetjmpArg, "dispatch", EntryBB->getTerminator()); - // check the return value of the setjmp. non-zero goes to dispatcher + // check the return value of the setjmp. non-zero goes to dispatcher. Value *IsNormal = new ICmpInst(EntryBB->getTerminator(), ICmpInst::ICMP_EQ, DispatchVal, Zero, "notunwind"); @@ -509,6 +535,16 @@ Unwinds[i]->eraseFromParent(); } + // Following any allocas not in the entry block, update the saved SP + // in the jmpbuf to the new value. + for (unsigned i = 0, e = JmpbufUpdatePoints.size(); i != e; ++i) { + Instruction *AI = JmpbufUpdatePoints[i]; + Instruction *StackAddr = CallInst::Create(StackAddrFn, "sp"); + StackAddr->insertAfter(AI); + Instruction *StoreStackAddr = new StoreInst(StackAddr, StackPtr, true); + StoreStackAddr->insertAfter(StackAddr); + } + // Finally, for any returns from this function, if this function contains an // invoke, add a call to unregister the function context. for (unsigned i = 0, e = Returns.size(); i != e; ++i) Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp?rev=104900&r1=104899&r2=104900&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp Thu May 27 18:49:24 2010 @@ -524,11 +524,11 @@ return 10; case ARM::Int_eh_sjlj_setjmp: case ARM::Int_eh_sjlj_setjmp_nofp: - return 24; + return 20; case ARM::tInt_eh_sjlj_setjmp: case ARM::t2Int_eh_sjlj_setjmp: case ARM::t2Int_eh_sjlj_setjmp_nofp: - return 14; + return 12; case ARM::BR_JTr: case ARM::BR_JTm: case ARM::BR_JTadd: Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=104900&r1=104899&r2=104900&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Thu May 27 18:49:24 2010 @@ -412,8 +412,6 @@ // We want to custom lower some of our intrinsics. setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); - setOperationAction(ISD::EH_SJLJ_SETJMP, MVT::i32, Custom); - setOperationAction(ISD::EH_SJLJ_LONGJMP, MVT::Other, Custom); setOperationAction(ISD::SETCC, MVT::i32, Expand); setOperationAction(ISD::SETCC, MVT::f32, Expand); @@ -1552,9 +1550,7 @@ SDValue ARMTargetLowering::LowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const { DebugLoc dl = Op.getDebugLoc(); - SDValue Val = Subtarget->isThumb() ? - DAG.getCopyFromReg(DAG.getEntryNode(), dl, ARM::SP, MVT::i32) : - DAG.getConstant(0, MVT::i32); + SDValue Val = DAG.getConstant(0, MVT::i32); return DAG.getNode(ARMISD::EH_SJLJ_SETJMP, dl, MVT::i32, Op.getOperand(0), Op.getOperand(1), Val); } Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=104900&r1=104899&r2=104900&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Thu May 27 18:49:24 2010 @@ -2534,8 +2534,7 @@ def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val), AddrModeNone, SizeSpecial, IndexModeNone, Pseudo, NoItinerary, - "str\tsp, [$src, #+8] ${:comment} eh_setjmp begin\n\t" - "add\t$val, pc, #8\n\t" + "add\t$val, pc, #8\t${:comment} eh_setjmp begin\t" "str\t$val, [$src, #+4]\n\t" "mov\tr0, #0\n\t" "add\tpc, pc, #0\n\t" @@ -2549,8 +2548,7 @@ def Int_eh_sjlj_setjmp_nofp : XI<(outs), (ins GPR:$src, GPR:$val), AddrModeNone, SizeSpecial, IndexModeNone, Pseudo, NoItinerary, - "str\tsp, [$src, #+8] ${:comment} eh_setjmp begin\n\t" - "add\t$val, pc, #8\n\t" + "add\t$val, pc, #8\n ${:comment} eh_setjmp begin\t" "str\t$val, [$src, #+4]\n\t" "mov\tr0, #0\n\t" "add\tpc, pc, #0\n\t" Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=104900&r1=104899&r2=104900&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Thu May 27 18:49:24 2010 @@ -923,13 +923,12 @@ // except for our own input by listing the relevant registers in Defs. By // doing so, we also cause the prologue/epilogue code to actively preserve // all of the callee-saved resgisters, which is exactly what we want. -// The current SP is passed in $val, and we reuse the reg as a scratch. +// $val is a scratch register for our use. let Defs = [ R0, R1, R2, R3, R4, R5, R6, R7, R12 ] in { def tInt_eh_sjlj_setjmp : ThumbXI<(outs),(ins tGPR:$src, tGPR:$val), AddrModeNone, SizeSpecial, NoItinerary, - "str\t$val, [$src, #8]\t${:comment} begin eh.setjmp\n" - "\tmov\t$val, pc\n" + "mov\t$val, pc\t${:comment} begin eh.setjmp\n" "\tadds\t$val, #7\n" "\tstr\t$val, [$src, #4]\n" "\tmovs\tr0, #0\n" Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=104900&r1=104899&r2=104900&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Thu May 27 18:49:24 2010 @@ -2389,7 +2389,7 @@ // except for our own input by listing the relevant registers in Defs. By // doing so, we also cause the prologue/epilogue code to actively preserve // all of the callee-saved resgisters, which is exactly what we want. -// The current SP is passed in $val, and we reuse the reg as a scratch. +// $val is a scratch register for our use. let Defs = [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, @@ -2397,8 +2397,7 @@ D31 ] in { def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins GPR:$src, tGPR:$val), AddrModeNone, SizeSpecial, NoItinerary, - "str\t$val, [$src, #8]\t${:comment} begin eh.setjmp\n" - "\tmov\t$val, pc\n" + "mov\t$val, pc\t${:comment} begin eh.setjmp\n" "\tadds\t$val, #7\n" "\tstr\t$val, [$src, #4]\n" "\tmovs\tr0, #0\n" @@ -2413,8 +2412,7 @@ [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ] in { def t2Int_eh_sjlj_setjmp_nofp : Thumb2XI<(outs), (ins GPR:$src, tGPR:$val), AddrModeNone, SizeSpecial, NoItinerary, - "str\t$val, [$src, #8]\t${:comment} begin eh.setjmp\n" - "\tmov\t$val, pc\n" + "mov\t$val, pc\t${:comment} begin eh.setjmp\n" "\tadds\t$val, #7\n" "\tstr\t$val, [$src, #4]\n" "\tmovs\tr0, #0\n" From stoklund at 2pi.dk Thu May 27 18:57:19 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Thu, 27 May 2010 23:57:19 -0000 Subject: [llvm-commits] [llvm] r104903 - /llvm/trunk/include/llvm/CodeGen/Passes.h Message-ID: <20100527235719.DB8B5312800A@llvm.org> Author: stoklund Date: Thu May 27 18:57:19 2010 New Revision: 104903 URL: http://llvm.org/viewvc/llvm-project?rev=104903&view=rev Log: Remove ancient prototype. Modified: llvm/trunk/include/llvm/CodeGen/Passes.h Modified: llvm/trunk/include/llvm/CodeGen/Passes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=104903&r1=104902&r2=104903&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/Passes.h (original) +++ llvm/trunk/include/llvm/CodeGen/Passes.h Thu May 27 18:57:19 2010 @@ -147,10 +147,6 @@ /// headers to target specific alignment boundary. FunctionPass *createCodePlacementOptPass(); - /// getRegisterAllocator - This creates an instance of the register allocator - /// for the Sparc. - FunctionPass *getRegisterAllocator(TargetMachine &T); - /// IntrinsicLowering Pass - Performs target-independent LLVM IR /// transformations for highly portable strategies. FunctionPass *createGCLoweringPass(); From stoklund at 2pi.dk Thu May 27 18:57:25 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Thu, 27 May 2010 23:57:25 -0000 Subject: [llvm-commits] [llvm] r104904 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/LLVMTargetMachine.cpp lib/CodeGen/Passes.cpp test/CodeGen/ARM/2010-05-20-NEONSpillCrash.ll test/CodeGen/X86/2008-05-21-CoalescerBug.ll test/CodeGen/X86/fast-isel-bc.ll test/CodeGen/X86/inline-asm-tied.ll Message-ID: <20100527235725.AFC223128018@llvm.org> Author: stoklund Date: Thu May 27 18:57:25 2010 New Revision: 104904 URL: http://llvm.org/viewvc/llvm-project?rev=104904&view=rev Log: Add a -regalloc=default option that chooses a register allocator based on the -O optimization level. This only really affects llc for now because both the llvm-gcc and clang front ends override the default register allocator. I intend to remove that code later. Modified: llvm/trunk/include/llvm/CodeGen/Passes.h llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp llvm/trunk/lib/CodeGen/Passes.cpp llvm/trunk/test/CodeGen/ARM/2010-05-20-NEONSpillCrash.ll llvm/trunk/test/CodeGen/X86/2008-05-21-CoalescerBug.ll llvm/trunk/test/CodeGen/X86/fast-isel-bc.ll llvm/trunk/test/CodeGen/X86/inline-asm-tied.ll Modified: llvm/trunk/include/llvm/CodeGen/Passes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=104904&r1=104903&r2=104904&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/Passes.h (original) +++ llvm/trunk/include/llvm/CodeGen/Passes.h Thu May 27 18:57:25 2010 @@ -85,9 +85,10 @@ /// FunctionPass *createDeadMachineInstructionElimPass(); - /// Creates a register allocator as the user specified on the command line. + /// Creates a register allocator as the user specified on the command line, or + /// picks one that matches OptLevel. /// - FunctionPass *createRegisterAllocator(); + FunctionPass *createRegisterAllocator(CodeGenOpt::Level OptLevel); /// LocalRegisterAllocation Pass - This pass register allocates the input code /// a basic block at a time, yielding code better than the simple register Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp?rev=104904&r1=104903&r2=104904&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp (original) +++ llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Thu May 27 18:57:25 2010 @@ -358,7 +358,7 @@ /* allowDoubleDefs= */ true); // Perform register allocation. - PM.add(createRegisterAllocator()); + PM.add(createRegisterAllocator(OptLevel)); printAndVerify(PM, "After Register Allocation"); // Perform stack slot coloring and post-ra machine LICM. Modified: llvm/trunk/lib/CodeGen/Passes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/Passes.cpp?rev=104904&r1=104903&r2=104904&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/Passes.cpp (original) +++ llvm/trunk/lib/CodeGen/Passes.cpp Thu May 27 18:57:25 2010 @@ -24,6 +24,11 @@ //===---------------------------------------------------------------------===// MachinePassRegistry RegisterRegAlloc::Registry; +static FunctionPass *createDefaultRegisterAllocator() { return 0; } +static RegisterRegAlloc +defaultRegAlloc("default", + "pick register allocator based on -O option", + createDefaultRegisterAllocator); //===---------------------------------------------------------------------===// /// @@ -33,8 +38,8 @@ static cl::opt > RegAlloc("regalloc", - cl::init(&createLinearScanRegisterAllocator), - cl::desc("Register allocator to use (default=linearscan)")); + cl::init(&createDefaultRegisterAllocator), + cl::desc("Register allocator to use")); //===---------------------------------------------------------------------===// @@ -42,13 +47,22 @@ /// createRegisterAllocator - choose the appropriate register allocator. /// //===---------------------------------------------------------------------===// -FunctionPass *llvm::createRegisterAllocator() { +FunctionPass *llvm::createRegisterAllocator(CodeGenOpt::Level OptLevel) { RegisterRegAlloc::FunctionPassCtor Ctor = RegisterRegAlloc::getDefault(); - + if (!Ctor) { Ctor = RegAlloc; RegisterRegAlloc::setDefault(RegAlloc); } - - return Ctor(); + + if (Ctor != createDefaultRegisterAllocator) + return Ctor(); + + // When the 'default' allocator is requested, pick one based on OptLevel. + switch (OptLevel) { + case CodeGenOpt::None: + return createLocalRegisterAllocator(); + default: + return createLinearScanRegisterAllocator(); + } } Modified: llvm/trunk/test/CodeGen/ARM/2010-05-20-NEONSpillCrash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2010-05-20-NEONSpillCrash.ll?rev=104904&r1=104903&r2=104904&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/2010-05-20-NEONSpillCrash.ll (original) +++ llvm/trunk/test/CodeGen/ARM/2010-05-20-NEONSpillCrash.ll Thu May 27 18:57:25 2010 @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=arm -mattr=+neon -O0 +; RUN: llc < %s -march=arm -mattr=+neon -O0 -regalloc=linearscan ; This test would crash the rewriter when trying to handle a spill after one of ; the @llvm.arm.neon.vld3.v8i8 defined three parts of a register. Modified: llvm/trunk/test/CodeGen/X86/2008-05-21-CoalescerBug.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2008-05-21-CoalescerBug.ll?rev=104904&r1=104903&r2=104904&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2008-05-21-CoalescerBug.ll (original) +++ llvm/trunk/test/CodeGen/X86/2008-05-21-CoalescerBug.ll Thu May 27 18:57:25 2010 @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86 -O0 -fast-isel=false | grep mov | count 5 +; RUN: llc < %s -march=x86 -O0 -fast-isel=false -regalloc=linearscan | grep mov | count 5 ; PR2343 %llvm.dbg.anchor.type = type { i32, i32 } Modified: llvm/trunk/test/CodeGen/X86/fast-isel-bc.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fast-isel-bc.ll?rev=104904&r1=104903&r2=104904&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/fast-isel-bc.ll (original) +++ llvm/trunk/test/CodeGen/X86/fast-isel-bc.ll Thu May 27 18:57:25 2010 @@ -1,4 +1,4 @@ -; RUN: llc < %s -O0 -march=x86-64 -mattr=+mmx | FileCheck %s +; RUN: llc < %s -O0 -regalloc=linearscan -march=x86-64 -mattr=+mmx | FileCheck %s ; PR4684 target datalayout = Modified: llvm/trunk/test/CodeGen/X86/inline-asm-tied.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/inline-asm-tied.ll?rev=104904&r1=104903&r2=104904&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/inline-asm-tied.ll (original) +++ llvm/trunk/test/CodeGen/X86/inline-asm-tied.ll Thu May 27 18:57:25 2010 @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=i386-apple-darwin9 -O0 | grep {movl %edx, 12(%esp)} | count 2 +; RUN: llc < %s -mtriple=i386-apple-darwin9 -O0 -regalloc=linearscan | grep {movl %edx, 12(%esp)} | count 2 ; rdar://6992609 target triple = "i386-apple-darwin9.0" From bob.wilson at apple.com Thu May 27 19:27:16 2010 From: bob.wilson at apple.com (Bob Wilson) Date: Fri, 28 May 2010 00:27:16 -0000 Subject: [llvm-commits] [llvm] r104907 - /llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Message-ID: <20100528002716.2526E3128018@llvm.org> Author: bwilson Date: Thu May 27 19:27:15 2010 New Revision: 104907 URL: http://llvm.org/viewvc/llvm-project?rev=104907&view=rev Log: Add the cc_out operand for t2RSBrs instructions. I missed this when I changed the instruction class for t2RSB to add that operand in svn r104582. Radar 8033757. Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=104907&r1=104906&r2=104907&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Thu May 27 19:27:15 2010 @@ -1954,8 +1954,8 @@ SDValue ShImmOp = CurDAG->getTargetConstant(ShImm, MVT::i32); SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); if (Subtarget->isThumb()) { - SDValue Ops[] = { V, V, ShImmOp, getAL(CurDAG), Reg0 }; - return CurDAG->SelectNodeTo(N, ARM::t2RSBrs, MVT::i32, Ops, 5); + SDValue Ops[] = { V, V, ShImmOp, getAL(CurDAG), Reg0, Reg0 }; + return CurDAG->SelectNodeTo(N, ARM::t2RSBrs, MVT::i32, Ops, 6); } else { SDValue Ops[] = { V, V, Reg0, ShImmOp, getAL(CurDAG), Reg0, Reg0 }; return CurDAG->SelectNodeTo(N, ARM::RSBrs, MVT::i32, Ops, 7); From natebegeman at mac.com Thu May 27 20:08:32 2010 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 28 May 2010 01:08:32 -0000 Subject: [llvm-commits] [llvm] r104910 - in /llvm/trunk/utils/TableGen: CMakeLists.txt NeonEmitter.cpp NeonEmitter.h TableGen.cpp Message-ID: <20100528010832.6E923312800A@llvm.org> Author: sampo Date: Thu May 27 20:08:32 2010 New Revision: 104910 URL: http://llvm.org/viewvc/llvm-project?rev=104910&view=rev Log: Add support to tablegen for auto-generating arm_neon.h from a tablegen description of the intrinsics. The goal is to auto-generate both support for GCC-style (vector) and ARM-style (struct of vector) intrinsics. This is work in progress, but will be completed soon. Added: llvm/trunk/utils/TableGen/NeonEmitter.cpp llvm/trunk/utils/TableGen/NeonEmitter.h Modified: llvm/trunk/utils/TableGen/CMakeLists.txt llvm/trunk/utils/TableGen/TableGen.cpp Modified: llvm/trunk/utils/TableGen/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CMakeLists.txt?rev=104910&r1=104909&r2=104910&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CMakeLists.txt (original) +++ llvm/trunk/utils/TableGen/CMakeLists.txt Thu May 27 20:08:32 2010 @@ -22,6 +22,7 @@ InstrInfoEmitter.cpp IntrinsicEmitter.cpp LLVMCConfigurationEmitter.cpp + NeonEmitter.cpp OptParserEmitter.cpp Record.cpp RegisterInfoEmitter.cpp Added: llvm/trunk/utils/TableGen/NeonEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/NeonEmitter.cpp?rev=104910&view=auto ============================================================================== --- llvm/trunk/utils/TableGen/NeonEmitter.cpp (added) +++ llvm/trunk/utils/TableGen/NeonEmitter.cpp Thu May 27 20:08:32 2010 @@ -0,0 +1,62 @@ +//===- NeonEmitter.cpp - Generate arm_neon.h for use with clang -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This tablegen backend is responsible for emitting arm_neon.h, which includes +// a declaration and definition of each function specified by the ARM NEON +// compiler interface. See ARM document DUI0348B. +// +//===----------------------------------------------------------------------===// + +#include "NeonEmitter.h" +#include "Record.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringMap.h" +#include + +using namespace llvm; + +void NeonEmitter::run(raw_ostream &OS) { + EmitSourceFileHeader("ARM NEON Header", OS); + + // FIXME: emit license into file? + + OS << "#ifndef __ARM_NEON_H\n"; + OS << "#define __ARM_NEON_H\n\n"; + + OS << "#ifndef __ARM_NEON__\n"; + OS << "#error \"NEON support not enabled\"\n"; + OS << "#endif\n\n"; + + OS << "#include \n\n"; + + // EmitTypedefs(OS); + + // Process Records + + std::vector RV = Records.getAllDerivedDefinitions("Inst"); + + // Unique the pattern types, and assign them + + // emit #define directives for uniq'd prototypes + + // emit record directives + + for (unsigned i = 0, e = RV.size(); i != e; ++i) { + Record *R = RV[i]; + + OS << LowercaseString(R->getName()) << "\n"; + + std::string Types = R->getValueAsString("Types"); + std::string Pattern = R->getValueAsString("Pattern"); + + OS << Types << "\n" << Pattern << "\n\n"; + } + + OS << "#endif /* __ARM_NEON_H */\n"; +} Added: llvm/trunk/utils/TableGen/NeonEmitter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/NeonEmitter.h?rev=104910&view=auto ============================================================================== --- llvm/trunk/utils/TableGen/NeonEmitter.h (added) +++ llvm/trunk/utils/TableGen/NeonEmitter.h Thu May 27 20:08:32 2010 @@ -0,0 +1,34 @@ +//===- NeonEmitter.h - Generate arm_neon.h for use with clang ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This tablegen backend is responsible for emitting arm_neon.h, which includes +// a declaration and definition of each function specified by the ARM NEON +// compiler interface. See ARM document DUI0348B. +// +//===----------------------------------------------------------------------===// + +#ifndef NEON_EMITTER_H +#define NEON_EMITTER_H + +#include "TableGenBackend.h" + +namespace llvm { + + class NeonEmitter : public TableGenBackend { + RecordKeeper &Records; + public: + NeonEmitter(RecordKeeper &R) : Records(R) {} + + // runHeader - Emit a header file that allows use of the instruction table. + void run(raw_ostream &o); + }; + +} // End llvm namespace + +#endif Modified: llvm/trunk/utils/TableGen/TableGen.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TableGen.cpp?rev=104910&r1=104909&r2=104910&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/TableGen.cpp (original) +++ llvm/trunk/utils/TableGen/TableGen.cpp Thu May 27 20:08:32 2010 @@ -29,6 +29,7 @@ #include "InstrInfoEmitter.h" #include "IntrinsicEmitter.h" #include "LLVMCConfigurationEmitter.h" +#include "NeonEmitter.h" #include "OptParserEmitter.h" #include "Record.h" #include "RegisterInfoEmitter.h" @@ -63,6 +64,7 @@ GenTgtIntrinsic, GenLLVMCConf, GenEDHeader, GenEDInfo, + GenNeonHeader, PrintEnums }; @@ -119,6 +121,8 @@ "Generate enhanced disassembly info header"), clEnumValN(GenEDInfo, "gen-enhanced-disassembly-info", "Generate enhanced disassembly info"), + clEnumValN(GenNeonHeader, "gen-arm-neon-header", + "Generate arm_neon.h for clang"), clEnumValN(PrintEnums, "print-enums", "Print enum values for a class"), clEnumValEnd)); @@ -280,6 +284,9 @@ case GenEDInfo: EDEmitter(Records).run(Out); break; + case GenNeonHeader: + NeonEmitter(Records).run(*Out); + break; case PrintEnums: { std::vector Recs = Records.getAllDerivedDefinitions(Class); From gohman at apple.com Thu May 27 20:14:11 2010 From: gohman at apple.com (Dan Gohman) Date: Fri, 28 May 2010 01:14:11 -0000 Subject: [llvm-commits] [llvm] r104911 - in /llvm/trunk: docs/LangRef.html lib/AsmParser/LLParser.cpp lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp lib/VMCore/Instructions.cpp lib/VMCore/Verifier.cpp test/CodeGen/X86/alloca-align-rounding-32.ll test/CodeGen/X86/alloca-align-rounding.ll Message-ID: <20100528011411.D2632312800A@llvm.org> Author: djg Date: Thu May 27 20:14:11 2010 New Revision: 104911 URL: http://llvm.org/viewvc/llvm-project?rev=104911&view=rev Log: Eliminate the restriction that the array size in an alloca must be i32. This will help reduce the amount of casting required on 64-bit targets. Added: llvm/trunk/test/CodeGen/X86/alloca-align-rounding-32.ll - copied, changed from r104897, llvm/trunk/test/CodeGen/X86/alloca-align-rounding.ll Modified: llvm/trunk/docs/LangRef.html llvm/trunk/lib/AsmParser/LLParser.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/trunk/lib/VMCore/Instructions.cpp llvm/trunk/lib/VMCore/Verifier.cpp llvm/trunk/test/CodeGen/X86/alloca-align-rounding.ll Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=104911&r1=104910&r2=104911&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Thu May 27 20:14:11 2010 @@ -4239,7 +4239,7 @@
    Syntax:
    -  <result> = alloca <type>[, i32 <NumElements>][, align <alignment>]     ; yields {type*}:result
    +  <result> = alloca <type>[, <ty> <NumElements>][, align <alignment>]     ; yields {type*}:result
     
    Overview:
    Modified: llvm/trunk/lib/AsmParser/LLParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=104911&r1=104910&r2=104911&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLParser.cpp (original) +++ llvm/trunk/lib/AsmParser/LLParser.cpp Thu May 27 20:14:11 2010 @@ -3791,8 +3791,8 @@ } } - if (Size && !Size->getType()->isIntegerTy(32)) - return Error(SizeLoc, "element count must be i32"); + if (Size && !Size->getType()->isIntegerTy()) + return Error(SizeLoc, "element count must have integer type"); if (isAlloca) { Inst = new AllocaInst(Ty, Size, Alignment); @@ -3801,6 +3801,8 @@ // Autoupgrade old malloc instruction to malloc call. // FIXME: Remove in LLVM 3.0. + if (Size && !Size->getType()->isIntegerTy(32)) + return Error(SizeLoc, "element count must be i32"); const Type *IntPtrTy = Type::getInt32Ty(Context); Constant *AllocSize = ConstantExpr::getSizeOf(Ty); AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, IntPtrTy); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=104911&r1=104910&r2=104911&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Thu May 27 20:14:11 2010 @@ -2643,12 +2643,13 @@ SDValue AllocSize = getValue(I.getArraySize()); - AllocSize = DAG.getNode(ISD::MUL, getCurDebugLoc(), AllocSize.getValueType(), - AllocSize, - DAG.getConstant(TySize, AllocSize.getValueType())); - EVT IntPtr = TLI.getPointerTy(); - AllocSize = DAG.getZExtOrTrunc(AllocSize, getCurDebugLoc(), IntPtr); + if (AllocSize.getValueType() != IntPtr) + AllocSize = DAG.getZExtOrTrunc(AllocSize, getCurDebugLoc(), IntPtr); + + AllocSize = DAG.getNode(ISD::MUL, getCurDebugLoc(), IntPtr, + AllocSize, + DAG.getConstant(TySize, IntPtr)); // Handle alignment. If the requested alignment is less than or equal to // the stack alignment, ignore it. If the size is greater than or equal to Modified: llvm/trunk/lib/VMCore/Instructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=104911&r1=104910&r2=104911&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instructions.cpp (original) +++ llvm/trunk/lib/VMCore/Instructions.cpp Thu May 27 20:14:11 2010 @@ -828,8 +828,8 @@ else { assert(!isa(Amt) && "Passed basic block into allocation size parameter! Use other ctor"); - assert(Amt->getType()->isIntegerTy(32) && - "Allocation array size is not a 32-bit integer!"); + assert(Amt->getType()->isIntegerTy() && + "Allocation array size is not an integer!"); } return Amt; } Modified: llvm/trunk/lib/VMCore/Verifier.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=104911&r1=104910&r2=104911&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Verifier.cpp (original) +++ llvm/trunk/lib/VMCore/Verifier.cpp Thu May 27 20:14:11 2010 @@ -1371,8 +1371,8 @@ &AI); Assert1(PTy->getElementType()->isSized(), "Cannot allocate unsized type", &AI); - Assert1(AI.getArraySize()->getType()->isIntegerTy(32), - "Alloca array size must be i32", &AI); + Assert1(AI.getArraySize()->getType()->isIntegerTy(), + "Alloca array size must have integer type", &AI); visitInstruction(AI); } Copied: llvm/trunk/test/CodeGen/X86/alloca-align-rounding-32.ll (from r104897, llvm/trunk/test/CodeGen/X86/alloca-align-rounding.ll) URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/alloca-align-rounding-32.ll?p2=llvm/trunk/test/CodeGen/X86/alloca-align-rounding-32.ll&p1=llvm/trunk/test/CodeGen/X86/alloca-align-rounding.ll&r1=104897&r2=104911&rev=104911&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/alloca-align-rounding.ll (original) +++ llvm/trunk/test/CodeGen/X86/alloca-align-rounding-32.ll Thu May 27 20:14:11 2010 @@ -1,5 +1,4 @@ ; RUN: llc < %s -march=x86 -mtriple=i686-apple-darwin | grep and | count 1 -; RUN: llc < %s -march=x86-64 -mtriple=i686-pc-linux | grep and | count 1 declare void @bar(<2 x i64>* %n) Modified: llvm/trunk/test/CodeGen/X86/alloca-align-rounding.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/alloca-align-rounding.ll?rev=104911&r1=104910&r2=104911&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/alloca-align-rounding.ll (original) +++ llvm/trunk/test/CodeGen/X86/alloca-align-rounding.ll Thu May 27 20:14:11 2010 @@ -1,16 +1,15 @@ -; RUN: llc < %s -march=x86 -mtriple=i686-apple-darwin | grep and | count 1 ; RUN: llc < %s -march=x86-64 -mtriple=i686-pc-linux | grep and | count 1 declare void @bar(<2 x i64>* %n) -define void @foo(i32 %h) { - %p = alloca <2 x i64>, i32 %h +define void @foo(i64 %h) { + %p = alloca <2 x i64>, i64 %h call void @bar(<2 x i64>* %p) ret void } -define void @foo2(i32 %h) { - %p = alloca <2 x i64>, i32 %h, align 32 +define void @foo2(i64 %h) { + %p = alloca <2 x i64>, i64 %h, align 32 call void @bar(<2 x i64>* %p) ret void } From eli.friedman at gmail.com Thu May 27 20:15:28 2010 From: eli.friedman at gmail.com (Eli Friedman) Date: Fri, 28 May 2010 01:15:28 -0000 Subject: [llvm-commits] [llvm] r104912 - /llvm/trunk/utils/TableGen/TableGen.cpp Message-ID: <20100528011528.9D3F7312800A@llvm.org> Author: efriedma Date: Thu May 27 20:15:28 2010 New Revision: 104912 URL: http://llvm.org/viewvc/llvm-project?rev=104912&view=rev Log: Fix build breakage. Modified: llvm/trunk/utils/TableGen/TableGen.cpp Modified: llvm/trunk/utils/TableGen/TableGen.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TableGen.cpp?rev=104912&r1=104911&r2=104912&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/TableGen.cpp (original) +++ llvm/trunk/utils/TableGen/TableGen.cpp Thu May 27 20:15:28 2010 @@ -285,7 +285,7 @@ EDEmitter(Records).run(Out); break; case GenNeonHeader: - NeonEmitter(Records).run(*Out); + NeonEmitter(Records).run(Out); break; case PrintEnums: { From dpatel at apple.com Thu May 27 20:17:52 2010 From: dpatel at apple.com (Devang Patel) Date: Fri, 28 May 2010 01:17:52 -0000 Subject: [llvm-commits] [llvm] r104913 - /llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Message-ID: <20100528011752.1B411312800A@llvm.org> Author: dpatel Date: Thu May 27 20:17:51 2010 New Revision: 104913 URL: http://llvm.org/viewvc/llvm-project?rev=104913&view=rev Log: Fix typo. Modified: llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Modified: llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp?rev=104913&r1=104912&r2=104913&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Thu May 27 20:17:51 2010 @@ -897,7 +897,7 @@ // Propagate any debug metadata from the store onto the dbg.value. if (MDNode *SIMD = SI->getMetadata("dbg")) DbgVal->setMetadata("dbg", SIMD); - // Otherwise propgate debug metadata from dbg.delcare for inlined fn args. + // Otherwise propgate debug metadata from dbg.declare for inlined fn args. else if (!DISubprogram(DIVar.getContext()). describes(DDI->getParent()->getParent())) if (MDNode *MD = DDI->getMetadata("dbg")) From wendling at apple.com Thu May 27 20:24:13 2010 From: wendling at apple.com (Bill Wendling) Date: Thu, 27 May 2010 18:24:13 -0700 Subject: [llvm-commits] [llvm] r104910 - in /llvm/trunk/utils/TableGen: CMakeLists.txt NeonEmitter.cpp NeonEmitter.h TableGen.cpp In-Reply-To: <20100528010832.6E923312800A@llvm.org> References: <20100528010832.6E923312800A@llvm.org> Message-ID: hi Nate, This is causing build failures here: http://google1.osuosl.org:8011/builders/llvm-gcc-x86_64-darwin10-self-mingw32/builds/408 -bw On May 27, 2010, at 6:08 PM, Nate Begeman wrote: > Author: sampo > Date: Thu May 27 20:08:32 2010 > New Revision: 104910 > > URL: http://llvm.org/viewvc/llvm-project?rev=104910&view=rev > Log: > Add support to tablegen for auto-generating arm_neon.h from a tablegen description > of the intrinsics. The goal is to auto-generate both support for GCC-style (vector) > and ARM-style (struct of vector) intrinsics. > > This is work in progress, but will be completed soon. > > Added: > llvm/trunk/utils/TableGen/NeonEmitter.cpp > llvm/trunk/utils/TableGen/NeonEmitter.h > Modified: > llvm/trunk/utils/TableGen/CMakeLists.txt > llvm/trunk/utils/TableGen/TableGen.cpp > > Modified: llvm/trunk/utils/TableGen/CMakeLists.txt > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CMakeLists.txt?rev=104910&r1=104909&r2=104910&view=diff > ============================================================================== > --- llvm/trunk/utils/TableGen/CMakeLists.txt (original) > +++ llvm/trunk/utils/TableGen/CMakeLists.txt Thu May 27 20:08:32 2010 > @@ -22,6 +22,7 @@ > InstrInfoEmitter.cpp > IntrinsicEmitter.cpp > LLVMCConfigurationEmitter.cpp > + NeonEmitter.cpp > OptParserEmitter.cpp > Record.cpp > RegisterInfoEmitter.cpp > > Added: llvm/trunk/utils/TableGen/NeonEmitter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/NeonEmitter.cpp?rev=104910&view=auto > ============================================================================== > --- llvm/trunk/utils/TableGen/NeonEmitter.cpp (added) > +++ llvm/trunk/utils/TableGen/NeonEmitter.cpp Thu May 27 20:08:32 2010 > @@ -0,0 +1,62 @@ > +//===- NeonEmitter.cpp - Generate arm_neon.h for use with clang -*- C++ -*-===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > +// > +// This tablegen backend is responsible for emitting arm_neon.h, which includes > +// a declaration and definition of each function specified by the ARM NEON > +// compiler interface. See ARM document DUI0348B. > +// > +//===----------------------------------------------------------------------===// > + > +#include "NeonEmitter.h" > +#include "Record.h" > +#include "llvm/ADT/StringExtras.h" > +#include "llvm/ADT/StringMap.h" > +#include > + > +using namespace llvm; > + > +void NeonEmitter::run(raw_ostream &OS) { > + EmitSourceFileHeader("ARM NEON Header", OS); > + > + // FIXME: emit license into file? > + > + OS << "#ifndef __ARM_NEON_H\n"; > + OS << "#define __ARM_NEON_H\n\n"; > + > + OS << "#ifndef __ARM_NEON__\n"; > + OS << "#error \"NEON support not enabled\"\n"; > + OS << "#endif\n\n"; > + > + OS << "#include \n\n"; > + > + // EmitTypedefs(OS); > + > + // Process Records > + > + std::vector RV = Records.getAllDerivedDefinitions("Inst"); > + > + // Unique the pattern types, and assign them > + > + // emit #define directives for uniq'd prototypes > + > + // emit record directives > + > + for (unsigned i = 0, e = RV.size(); i != e; ++i) { > + Record *R = RV[i]; > + > + OS << LowercaseString(R->getName()) << "\n"; > + > + std::string Types = R->getValueAsString("Types"); > + std::string Pattern = R->getValueAsString("Pattern"); > + > + OS << Types << "\n" << Pattern << "\n\n"; > + } > + > + OS << "#endif /* __ARM_NEON_H */\n"; > +} > > Added: llvm/trunk/utils/TableGen/NeonEmitter.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/NeonEmitter.h?rev=104910&view=auto > ============================================================================== > --- llvm/trunk/utils/TableGen/NeonEmitter.h (added) > +++ llvm/trunk/utils/TableGen/NeonEmitter.h Thu May 27 20:08:32 2010 > @@ -0,0 +1,34 @@ > +//===- NeonEmitter.h - Generate arm_neon.h for use with clang ---*- C++ -*-===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > +// > +// This tablegen backend is responsible for emitting arm_neon.h, which includes > +// a declaration and definition of each function specified by the ARM NEON > +// compiler interface. See ARM document DUI0348B. > +// > +//===----------------------------------------------------------------------===// > + > +#ifndef NEON_EMITTER_H > +#define NEON_EMITTER_H > + > +#include "TableGenBackend.h" > + > +namespace llvm { > + > + class NeonEmitter : public TableGenBackend { > + RecordKeeper &Records; > + public: > + NeonEmitter(RecordKeeper &R) : Records(R) {} > + > + // runHeader - Emit a header file that allows use of the instruction table. > + void run(raw_ostream &o); > + }; > + > +} // End llvm namespace > + > +#endif > > Modified: llvm/trunk/utils/TableGen/TableGen.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TableGen.cpp?rev=104910&r1=104909&r2=104910&view=diff > ============================================================================== > --- llvm/trunk/utils/TableGen/TableGen.cpp (original) > +++ llvm/trunk/utils/TableGen/TableGen.cpp Thu May 27 20:08:32 2010 > @@ -29,6 +29,7 @@ > #include "InstrInfoEmitter.h" > #include "IntrinsicEmitter.h" > #include "LLVMCConfigurationEmitter.h" > +#include "NeonEmitter.h" > #include "OptParserEmitter.h" > #include "Record.h" > #include "RegisterInfoEmitter.h" > @@ -63,6 +64,7 @@ > GenTgtIntrinsic, > GenLLVMCConf, > GenEDHeader, GenEDInfo, > + GenNeonHeader, > PrintEnums > }; > > @@ -119,6 +121,8 @@ > "Generate enhanced disassembly info header"), > clEnumValN(GenEDInfo, "gen-enhanced-disassembly-info", > "Generate enhanced disassembly info"), > + clEnumValN(GenNeonHeader, "gen-arm-neon-header", > + "Generate arm_neon.h for clang"), > clEnumValN(PrintEnums, "print-enums", > "Print enum values for a class"), > clEnumValEnd)); > @@ -280,6 +284,9 @@ > case GenEDInfo: > EDEmitter(Records).run(Out); > break; > + case GenNeonHeader: > + NeonEmitter(Records).run(*Out); > + break; > case PrintEnums: > { > std::vector Recs = Records.getAllDerivedDefinitions(Class); > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From eli.friedman at gmail.com Thu May 27 20:29:11 2010 From: eli.friedman at gmail.com (Eli Friedman) Date: Thu, 27 May 2010 18:29:11 -0700 Subject: [llvm-commits] [llvm] r104913 - /llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp In-Reply-To: <20100528011752.1B411312800A@llvm.org> References: <20100528011752.1B411312800A@llvm.org> Message-ID: On Thu, May 27, 2010 at 6:17 PM, Devang Patel wrote: > Author: dpatel > Date: Thu May 27 20:17:51 2010 > New Revision: 104913 > > URL: http://llvm.org/viewvc/llvm-project?rev=104913&view=rev > Log: > Fix typo. > > Modified: > ? ?llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp > > Modified: llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp?rev=104913&r1=104912&r2=104913&view=diff > ============================================================================== > --- llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp (original) > +++ llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Thu May 27 20:17:51 2010 > @@ -897,7 +897,7 @@ > ? // Propagate any debug metadata from the store onto the dbg.value. > ? if (MDNode *SIMD = SI->getMetadata("dbg")) > ? ? DbgVal->setMetadata("dbg", SIMD); > - ?// Otherwise propgate debug metadata from dbg.delcare for inlined fn args. > + ?// Otherwise propgate debug metadata from dbg.declare for inlined fn args. Can you find the other typo in this line? :) -Eli From dpatel at apple.com Thu May 27 20:29:50 2010 From: dpatel at apple.com (Devang Patel) Date: Fri, 28 May 2010 01:29:50 -0000 Subject: [llvm-commits] [llvm] r104914 - /llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Message-ID: <20100528012950.D75C9312800A@llvm.org> Author: dpatel Date: Thu May 27 20:29:50 2010 New Revision: 104914 URL: http://llvm.org/viewvc/llvm-project?rev=104914&view=rev Log: Fix typo. Modified: llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Modified: llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp?rev=104914&r1=104913&r2=104914&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Thu May 27 20:29:50 2010 @@ -897,7 +897,7 @@ // Propagate any debug metadata from the store onto the dbg.value. if (MDNode *SIMD = SI->getMetadata("dbg")) DbgVal->setMetadata("dbg", SIMD); - // Otherwise propgate debug metadata from dbg.declare for inlined fn args. + // Otherwise propagate debug metadata from dbg.declare for inlined fn args. else if (!DISubprogram(DIVar.getContext()). describes(DDI->getParent()->getParent())) if (MDNode *MD = DDI->getMetadata("dbg")) From gohman at apple.com Thu May 27 20:38:28 2010 From: gohman at apple.com (Dan Gohman) Date: Fri, 28 May 2010 01:38:28 -0000 Subject: [llvm-commits] [llvm] r104915 - in /llvm/trunk/lib/Bitcode: Reader/BitcodeReader.cpp Writer/BitcodeWriter.cpp Message-ID: <20100528013828.6B941312800A@llvm.org> Author: djg Date: Thu May 27 20:38:28 2010 New Revision: 104915 URL: http://llvm.org/viewvc/llvm-project?rev=104915&view=rev Log: Bitcode support for allocas with arbitrary array size types. Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=104915&r1=104914&r2=104915&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original) +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Thu May 27 20:38:28 2010 @@ -2178,13 +2178,18 @@ InstructionList.push_back(I); break; } - case bitc::FUNC_CODE_INST_ALLOCA: { // ALLOCA: [instty, op, align] - if (Record.size() < 3) + case bitc::FUNC_CODE_INST_ALLOCA: { // ALLOCA: [instty, opty, op, align] + // For backward compatibility, tolerate a lack of an opty, and use i32. + // LLVM 3.0: Remove this. + if (Record.size() < 3 || Record.size() > 4) return Error("Invalid ALLOCA record"); + unsigned OpNum = 0; const PointerType *Ty = - dyn_cast_or_null(getTypeByID(Record[0])); - Value *Size = getFnValueByID(Record[1], Type::getInt32Ty(Context)); - unsigned Align = Record[2]; + dyn_cast_or_null(getTypeByID(Record[OpNum++])); + const Type *OpTy = Record.size() == 4 ? getTypeByID(Record[OpNum++]) : + Type::getInt32Ty(Context); + Value *Size = getFnValueByID(Record[OpNum++], OpTy); + unsigned Align = Record[OpNum++]; if (!Ty || !Size) return Error("Invalid ALLOCA record"); I = new AllocaInst(Ty->getElementType(), Size, (1 << Align) >> 1); InstructionList.push_back(I); Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=104915&r1=104914&r2=104915&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original) +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Thu May 27 20:38:28 2010 @@ -1114,6 +1114,7 @@ case Instruction::Alloca: Code = bitc::FUNC_CODE_INST_ALLOCA; Vals.push_back(VE.getTypeID(I.getType())); + Vals.push_back(VE.getTypeID(I.getOperand(0)->getType())); Vals.push_back(VE.getValueID(I.getOperand(0))); // size. Vals.push_back(Log2_32(cast(I).getAlignment())+1); break; From gohman at apple.com Thu May 27 20:43:06 2010 From: gohman at apple.com (Dan Gohman) Date: Fri, 28 May 2010 01:43:06 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r104918 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <20100528014306.D6930312800A@llvm.org> Author: djg Date: Thu May 27 20:43:06 2010 New Revision: 104918 URL: http://llvm.org/viewvc/llvm-project?rev=104918&view=rev Log: These casts are no longer required. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=104918&r1=104917&r2=104918&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Thu May 27 20:43:06 2010 @@ -1762,7 +1762,6 @@ Size = Emit(DECL_SIZE_UNIT(decl), 0); Ty = Type::getInt8Ty(Context); } - Size = CastToUIntType(Size, Type::getInt32Ty(Context)); } unsigned Alignment = 0; // Alignment in bytes. @@ -6676,7 +6675,6 @@ if (!validate_arglist(arglist, INTEGER_TYPE, VOID_TYPE)) return false; Value *Amt = Emit(TREE_VALUE(arglist), 0); - Amt = CastToSIntType(Amt, Type::getInt32Ty(Context)); Result = Builder.CreateAlloca(Type::getInt8Ty(Context), Amt); return true; } From natebegeman at mac.com Thu May 27 21:19:09 2010 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 28 May 2010 02:19:09 -0000 Subject: [llvm-commits] [llvm] r104927 - /llvm/trunk/utils/TableGen/NeonEmitter.cpp Message-ID: <20100528021909.264AC312800A@llvm.org> Author: sampo Date: Thu May 27 21:19:08 2010 New Revision: 104927 URL: http://llvm.org/viewvc/llvm-project?rev=104927&view=rev Log: Comment out some code in prep for actual .td file checkpoint. Modified: llvm/trunk/utils/TableGen/NeonEmitter.cpp Modified: llvm/trunk/utils/TableGen/NeonEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/NeonEmitter.cpp?rev=104927&r1=104926&r2=104927&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/NeonEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/NeonEmitter.cpp Thu May 27 21:19:08 2010 @@ -53,9 +53,8 @@ OS << LowercaseString(R->getName()) << "\n"; std::string Types = R->getValueAsString("Types"); - std::string Pattern = R->getValueAsString("Pattern"); - - OS << Types << "\n" << Pattern << "\n\n"; + //std::string Pattern = R->getValueAsString("Pattern"); + //OS << Types << "\n" << Pattern << "\n\n"; } OS << "#endif /* __ARM_NEON_H */\n"; From gohman at apple.com Thu May 27 23:33:04 2010 From: gohman at apple.com (Dan Gohman) Date: Fri, 28 May 2010 04:33:04 -0000 Subject: [llvm-commits] [llvm] r104935 - /llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Message-ID: <20100528043304.8BAF1312800A@llvm.org> Author: djg Date: Thu May 27 23:33:04 2010 New Revision: 104935 URL: http://llvm.org/viewvc/llvm-project?rev=104935&view=rev Log: Fix instcombine's handling of alloca to accept non-i32 types. Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp?rev=104935&r1=104934&r2=104935&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Thu May 27 23:33:04 2010 @@ -22,19 +22,18 @@ /// X*Scale+Offset. /// static Value *DecomposeSimpleLinearExpr(Value *Val, unsigned &Scale, - int &Offset) { - assert(Val->getType()->isIntegerTy(32) && "Unexpected allocation size type!"); + uint64_t &Offset) { if (ConstantInt *CI = dyn_cast(Val)) { Offset = CI->getZExtValue(); Scale = 0; - return ConstantInt::get(Type::getInt32Ty(Val->getContext()), 0); + return ConstantInt::get(Val->getType(), 0); } if (BinaryOperator *I = dyn_cast(Val)) { if (ConstantInt *RHS = dyn_cast(I->getOperand(1))) { if (I->getOpcode() == Instruction::Shl) { // This is a value scaled by '1 << the shift amt'. - Scale = 1U << RHS->getZExtValue(); + Scale = UINT64_C(1) << RHS->getZExtValue(); Offset = 0; return I->getOperand(0); } @@ -100,7 +99,7 @@ // See if we can satisfy the modulus by pulling a scale out of the array // size argument. unsigned ArraySizeScale; - int ArrayOffset; + uint64_t ArrayOffset; Value *NumElements = // See if the array size is a decomposable linear expr. DecomposeSimpleLinearExpr(AI.getOperand(0), ArraySizeScale, ArrayOffset); @@ -114,13 +113,13 @@ if (Scale == 1) { Amt = NumElements; } else { - Amt = ConstantInt::get(Type::getInt32Ty(CI.getContext()), Scale); + Amt = ConstantInt::get(AI.getArraySize()->getType(), Scale); // Insert before the alloca, not before the cast. Amt = AllocaBuilder.CreateMul(Amt, NumElements, "tmp"); } - if (int Offset = (AllocElTySize*ArrayOffset)/CastElTySize) { - Value *Off = ConstantInt::get(Type::getInt32Ty(CI.getContext()), + if (uint64_t Offset = (AllocElTySize*ArrayOffset)/CastElTySize) { + Value *Off = ConstantInt::get(AI.getArraySize()->getType(), Offset, true); Amt = AllocaBuilder.CreateAdd(Amt, Off, "tmp"); } From gohman at apple.com Thu May 27 23:33:42 2010 From: gohman at apple.com (Dan Gohman) Date: Fri, 28 May 2010 04:33:42 -0000 Subject: [llvm-commits] [llvm] r104936 - in /llvm/trunk: lib/Analysis/Lint.cpp test/Other/lint.ll Message-ID: <20100528043342.5416E312800A@llvm.org> Author: djg Date: Thu May 27 23:33:42 2010 New Revision: 104936 URL: http://llvm.org/viewvc/llvm-project?rev=104936&view=rev Log: Add a lint check for returning the address of stack memory. Modified: llvm/trunk/lib/Analysis/Lint.cpp llvm/trunk/test/Other/lint.ll Modified: llvm/trunk/lib/Analysis/Lint.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/Lint.cpp?rev=104936&r1=104935&r2=104936&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/Lint.cpp (original) +++ llvm/trunk/lib/Analysis/Lint.cpp Thu May 27 23:33:42 2010 @@ -310,6 +310,12 @@ Assert1(!F->doesNotReturn(), "Unusual: Return statement in function with noreturn attribute", &I); + + if (Value *V = I.getReturnValue()) { + Value *Obj = V->getUnderlyingObject(); + Assert1(!isa(Obj) && !isa(Obj), + "Unusual: Returning alloca or va_arg value", &I); + } } // TODO: Add a length argument and check that the reference is in bounds Modified: llvm/trunk/test/Other/lint.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/lint.ll?rev=104936&r1=104935&r2=104936&view=diff ============================================================================== --- llvm/trunk/test/Other/lint.ll (original) +++ llvm/trunk/test/Other/lint.ll Thu May 27 23:33:42 2010 @@ -97,3 +97,10 @@ tail call void @tailcallee(i8* %s) ret void } + +; CHECK: Unusual: Returning alloca or va_arg value +define i8* @return_local(i32 %n, i32 %m) { + %t = alloca i8, i32 %n + %s = getelementptr i8* %t, i32 %m + ret i8* %s +} From eli.friedman at gmail.com Thu May 27 23:45:56 2010 From: eli.friedman at gmail.com (Eli Friedman) Date: Thu, 27 May 2010 21:45:56 -0700 Subject: [llvm-commits] [llvm] r104936 - in /llvm/trunk: lib/Analysis/Lint.cpp test/Other/lint.ll In-Reply-To: <20100528043342.5416E312800A@llvm.org> References: <20100528043342.5416E312800A@llvm.org> Message-ID: On Thu, May 27, 2010 at 9:33 PM, Dan Gohman wrote: > Author: djg > Date: Thu May 27 23:33:42 2010 > New Revision: 104936 > > URL: http://llvm.org/viewvc/llvm-project?rev=104936&view=rev > Log: > Add a lint check for returning the address of stack memory. > > Modified: > ? ?llvm/trunk/lib/Analysis/Lint.cpp > ? ?llvm/trunk/test/Other/lint.ll > > Modified: llvm/trunk/lib/Analysis/Lint.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/Lint.cpp?rev=104936&r1=104935&r2=104936&view=diff > ============================================================================== > --- llvm/trunk/lib/Analysis/Lint.cpp (original) > +++ llvm/trunk/lib/Analysis/Lint.cpp Thu May 27 23:33:42 2010 > @@ -310,6 +310,12 @@ > ? Assert1(!F->doesNotReturn(), > ? ? ? ? ? "Unusual: Return statement in function with noreturn attribute", > ? ? ? ? ? &I); > + > + ?if (Value *V = I.getReturnValue()) { > + ? ?Value *Obj = V->getUnderlyingObject(); > + ? ?Assert1(!isa(Obj) && !isa(Obj), > + ? ? ? ? ? ?"Unusual: Returning alloca or va_arg value", &I); > + ?} > ?} A VAArgInst doesn't in general return a pointer to something on the stack... -Eli From natebegeman at me.com Thu May 27 21:04:44 2010 From: natebegeman at me.com (Nate Begeman) Date: Thu, 27 May 2010 19:04:44 -0700 Subject: [llvm-commits] [llvm] r104912 - /llvm/trunk/utils/TableGen/TableGen.cpp In-Reply-To: <20100528011528.9D3F7312800A@llvm.org> References: <20100528011528.9D3F7312800A@llvm.org> Message-ID: <7466FA20-C9E3-4111-9234-99B5870E49BE@me.com> D'oh, thanks. On May 27, 2010, at 6:15 PM, Eli Friedman wrote: > Author: efriedma > Date: Thu May 27 20:15:28 2010 > New Revision: 104912 > > URL: http://llvm.org/viewvc/llvm-project?rev=104912&view=rev > Log: > Fix build breakage. > > > Modified: > llvm/trunk/utils/TableGen/TableGen.cpp > > Modified: llvm/trunk/utils/TableGen/TableGen.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TableGen.cpp?rev=104912&r1=104911&r2=104912&view=diff > ============================================================================== > --- llvm/trunk/utils/TableGen/TableGen.cpp (original) > +++ llvm/trunk/utils/TableGen/TableGen.cpp Thu May 27 20:15:28 2010 > @@ -285,7 +285,7 @@ > EDEmitter(Records).run(Out); > break; > case GenNeonHeader: > - NeonEmitter(Records).run(*Out); > + NeonEmitter(Records).run(Out); > break; > case PrintEnums: > { > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From gohman at apple.com Fri May 28 10:07:59 2010 From: gohman at apple.com (Dan Gohman) Date: Fri, 28 May 2010 15:07:59 -0000 Subject: [llvm-commits] [llvm] r104944 - /llvm/trunk/test/Transforms/InstCombine/getelementptr.ll Message-ID: <20100528150759.6E5FD312800A@llvm.org> Author: djg Date: Fri May 28 10:07:59 2010 New Revision: 104944 URL: http://llvm.org/viewvc/llvm-project?rev=104944&view=rev Log: Add a testcase for getelementptr index promotion. Modified: llvm/trunk/test/Transforms/InstCombine/getelementptr.ll Modified: llvm/trunk/test/Transforms/InstCombine/getelementptr.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/getelementptr.ll?rev=104944&r1=104943&r2=104944&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/getelementptr.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/getelementptr.ll Fri May 28 10:07:59 2010 @@ -468,3 +468,12 @@ getelementptr ([1 x i8]* @A37, i64 1, i64 0) ret i1 %t } + +; Test index promotion +define i32* @test38(i32* %I, i32 %n) { + %A = getelementptr i32* %I, i32 %n + ret i32* %A +; CHECK: @test38 +; CHECK: = sext i32 %n to i64 +; CHECK: %A = getelementptr i32* %I, i64 % +} From gohman at apple.com Fri May 28 10:09:00 2010 From: gohman at apple.com (Dan Gohman) Date: Fri, 28 May 2010 15:09:00 -0000 Subject: [llvm-commits] [llvm] r104945 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp test/Transforms/InstCombine/alloca.ll Message-ID: <20100528150900.CBDF9312800A@llvm.org> Author: djg Date: Fri May 28 10:09:00 2010 New Revision: 104945 URL: http://llvm.org/viewvc/llvm-project?rev=104945&view=rev Log: Teach instcombine to promote alloca array sizes. Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp llvm/trunk/test/Transforms/InstCombine/alloca.ll Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp?rev=104945&r1=104944&r2=104945&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp Fri May 28 10:09:00 2010 @@ -22,6 +22,18 @@ STATISTIC(NumDeadStore, "Number of dead stores eliminated"); Instruction *InstCombiner::visitAllocaInst(AllocaInst &AI) { + // Ensure that the alloca array size argument has type intptr_t, so that + // any casting is exposed early. + if (TD) { + const Type *IntPtrTy = TD->getIntPtrType(AI.getContext()); + if (AI.getArraySize()->getType() != IntPtrTy) { + Value *V = Builder->CreateIntCast(AI.getArraySize(), + IntPtrTy, false); + AI.setOperand(0, V); + return &AI; + } + } + // Convert: alloca Ty, C - where C is a constant != 1 into: alloca [C x Ty], 1 if (AI.isArrayAllocation()) { // Check C != 1 if (const ConstantInt *C = dyn_cast(AI.getArraySize())) { Modified: llvm/trunk/test/Transforms/InstCombine/alloca.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/alloca.ll?rev=104945&r1=104944&r2=104945&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/alloca.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/alloca.ll Fri May 28 10:09:00 2010 @@ -1,12 +1,13 @@ -; Zero byte allocas should be deleted. target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" -; RUN: opt < %s -instcombine -S | \ -; RUN: not grep alloca +; RUN: opt < %s -instcombine -S | FileCheck %s ; END. declare void @use(...) +; Zero byte allocas should be deleted. +; CHECK: @test +; CHECK-NOT: alloca define void @test() { %X = alloca [0 x i32] ; <[0 x i32]*> [#uses=1] call void (...)* @use( [0 x i32]* %X ) @@ -17,12 +18,18 @@ ret void } +; Zero byte allocas should be deleted. +; CHECK: @test2 +; CHECK-NOT: alloca define void @test2() { %A = alloca i32 ; [#uses=1] store i32 123, i32* %A ret void } +; Zero byte allocas should be deleted. +; CHECK: @test3 +; CHECK-NOT: alloca define void @test3() { %A = alloca { i32 } ; <{ i32 }*> [#uses=1] %B = getelementptr { i32 }* %A, i32 0, i32 0 ; [#uses=1] @@ -30,3 +37,10 @@ ret void } +; CHECK: @test4 +; CHECK: = zext i32 %n to i64 +; CHECK: %A = alloca i32, i64 % +define i32* @test4(i32 %n) { + %A = alloca i32, i32 %n + ret i32* %A +} From gohman at apple.com Fri May 28 11:06:09 2010 From: gohman at apple.com (Dan Gohman) Date: Fri, 28 May 2010 16:06:09 -0000 Subject: [llvm-commits] [llvm] r104947 - /llvm/trunk/include/llvm/Analysis/ValueTracking.h Message-ID: <20100528160609.45E4D312800A@llvm.org> Author: djg Date: Fri May 28 11:06:09 2010 New Revision: 104947 URL: http://llvm.org/viewvc/llvm-project?rev=104947&view=rev Log: Fix a comment. Modified: llvm/trunk/include/llvm/Analysis/ValueTracking.h Modified: llvm/trunk/include/llvm/Analysis/ValueTracking.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ValueTracking.h?rev=104947&r1=104946&r2=104947&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/ValueTracking.h (original) +++ llvm/trunk/include/llvm/Analysis/ValueTracking.h Fri May 28 11:06:09 2010 @@ -97,7 +97,7 @@ - /// FindScalarValue - Given an aggregrate and an sequence of indices, see if + /// FindInsertedValue - Given an aggregrate and an sequence of indices, see if /// the scalar value indexed is already around as a register, for example if /// it were inserted directly into the aggregrate. /// From gohman at apple.com Fri May 28 11:12:09 2010 From: gohman at apple.com (Dan Gohman) Date: Fri, 28 May 2010 16:12:09 -0000 Subject: [llvm-commits] [llvm] r104948 - /llvm/trunk/lib/Analysis/ScalarEvolution.cpp Message-ID: <20100528161209.2C870312800A@llvm.org> Author: djg Date: Fri May 28 11:12:08 2010 New Revision: 104948 URL: http://llvm.org/viewvc/llvm-project?rev=104948&view=rev Log: ConstantFoldConstantExpression can theoretically return null. Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=104948&r1=104947&r2=104948&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Fri May 28 11:12:08 2010 @@ -2278,7 +2278,8 @@ Constant *C = ConstantExpr::getSizeOf(AllocTy); if (ConstantExpr *CE = dyn_cast(C)) - C = ConstantFoldConstantExpression(CE, TD); + if (Constant *Folded = ConstantFoldConstantExpression(CE, TD)) + C = Folded; const Type *Ty = getEffectiveSCEVType(PointerType::getUnqual(AllocTy)); return getTruncateOrZeroExtend(getSCEV(C), Ty); } @@ -2286,7 +2287,8 @@ const SCEV *ScalarEvolution::getAlignOfExpr(const Type *AllocTy) { Constant *C = ConstantExpr::getAlignOf(AllocTy); if (ConstantExpr *CE = dyn_cast(C)) - C = ConstantFoldConstantExpression(CE, TD); + if (Constant *Folded = ConstantFoldConstantExpression(CE, TD)) + C = Folded; const Type *Ty = getEffectiveSCEVType(PointerType::getUnqual(AllocTy)); return getTruncateOrZeroExtend(getSCEV(C), Ty); } @@ -2302,7 +2304,8 @@ Constant *C = ConstantExpr::getOffsetOf(STy, FieldNo); if (ConstantExpr *CE = dyn_cast(C)) - C = ConstantFoldConstantExpression(CE, TD); + if (Constant *Folded = ConstantFoldConstantExpression(CE, TD)) + C = Folded; const Type *Ty = getEffectiveSCEVType(PointerType::getUnqual(STy)); return getTruncateOrZeroExtend(getSCEV(C), Ty); } @@ -2311,7 +2314,8 @@ Constant *FieldNo) { Constant *C = ConstantExpr::getOffsetOf(CTy, FieldNo); if (ConstantExpr *CE = dyn_cast(C)) - C = ConstantFoldConstantExpression(CE, TD); + if (Constant *Folded = ConstantFoldConstantExpression(CE, TD)) + C = Folded; const Type *Ty = getEffectiveSCEVType(PointerType::getUnqual(CTy)); return getTruncateOrZeroExtend(getSCEV(C), Ty); } From gohman at apple.com Fri May 28 11:19:17 2010 From: gohman at apple.com (Dan Gohman) Date: Fri, 28 May 2010 16:19:17 -0000 Subject: [llvm-commits] [llvm] r104949 - in /llvm/trunk: include/llvm/Analysis/Loads.h include/llvm/Transforms/Utils/BasicBlockUtils.h include/llvm/Transforms/Utils/Local.h lib/Analysis/CMakeLists.txt lib/Analysis/Loads.cpp lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp lib/Transforms/Scalar/GVN.cpp lib/Transforms/Scalar/JumpThreading.cpp lib/Transforms/Scalar/TailRecursionElimination.cpp lib/Transforms/Utils/BasicBlockUtils.cpp lib/Transforms/Utils/Local.cpp Message-ID: <20100528161918.0F511312800A@llvm.org> Author: djg Date: Fri May 28 11:19:17 2010 New Revision: 104949 URL: http://llvm.org/viewvc/llvm-project?rev=104949&view=rev Log: Move FindAvailableLoadedValue isSafeToLoadUnconditionally out of lib/Transforms/Utils and into lib/Analysis so that Analysis passes can use them. Added: llvm/trunk/include/llvm/Analysis/Loads.h llvm/trunk/lib/Analysis/Loads.cpp Modified: llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h llvm/trunk/include/llvm/Transforms/Utils/Local.h llvm/trunk/lib/Analysis/CMakeLists.txt llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp llvm/trunk/lib/Transforms/Scalar/GVN.cpp llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp llvm/trunk/lib/Transforms/Utils/Local.cpp Added: llvm/trunk/include/llvm/Analysis/Loads.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/Loads.h?rev=104949&view=auto ============================================================================== --- llvm/trunk/include/llvm/Analysis/Loads.h (added) +++ llvm/trunk/include/llvm/Analysis/Loads.h Fri May 28 11:19:17 2010 @@ -0,0 +1,51 @@ +//===- Loads.h - Local load analysis --------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares simple local analyses for load instructions. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_LOADS_H +#define LLVM_ANALYSIS_LOADS_H + +#include "llvm/BasicBlock.h" + +namespace llvm { + +class AliasAnalysis; +class TargetData; + +/// isSafeToLoadUnconditionally - Return true if we know that executing a load +/// from this value cannot trap. If it is not obviously safe to load from the +/// specified pointer, we do a quick local scan of the basic block containing +/// ScanFrom, to determine if the address is already accessed. +bool isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom, + unsigned Align, const TargetData *TD = 0); + +/// FindAvailableLoadedValue - Scan the ScanBB block backwards (starting at +/// the instruction before ScanFrom) checking to see if we have the value at +/// the memory address *Ptr locally available within a small number of +/// instructions. If the value is available, return it. +/// +/// If not, return the iterator for the last validated instruction that the +/// value would be live through. If we scanned the entire block and didn't +/// find something that invalidates *Ptr or provides it, ScanFrom would be +/// left at begin() and this returns null. ScanFrom could also be left +/// +/// MaxInstsToScan specifies the maximum instructions to scan in the block. +/// If it is set to 0, it will scan the whole block. You can also optionally +/// specify an alias analysis implementation, which makes this more precise. +Value *FindAvailableLoadedValue(Value *Ptr, BasicBlock *ScanBB, + BasicBlock::iterator &ScanFrom, + unsigned MaxInstsToScan = 6, + AliasAnalysis *AA = 0); + +} + +#endif Modified: llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h?rev=104949&r1=104948&r2=104949&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h (original) +++ llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h Fri May 28 11:19:17 2010 @@ -66,24 +66,6 @@ // void ReplaceInstWithInst(Instruction *From, Instruction *To); -/// FindAvailableLoadedValue - Scan the ScanBB block backwards (starting at the -/// instruction before ScanFrom) checking to see if we have the value at the -/// memory address *Ptr locally available within a small number of instructions. -/// If the value is available, return it. -/// -/// If not, return the iterator for the last validated instruction that the -/// value would be live through. If we scanned the entire block and didn't find -/// something that invalidates *Ptr or provides it, ScanFrom would be left at -/// begin() and this returns null. ScanFrom could also be left -/// -/// MaxInstsToScan specifies the maximum instructions to scan in the block. If -/// it is set to 0, it will scan the whole block. You can also optionally -/// specify an alias analysis implementation, which makes this more precise. -Value *FindAvailableLoadedValue(Value *Ptr, BasicBlock *ScanBB, - BasicBlock::iterator &ScanFrom, - unsigned MaxInstsToScan = 6, - AliasAnalysis *AA = 0); - /// FindFunctionBackedges - Analyze the specified function to find all of the /// loop backedges in the function and return them. This is a relatively cheap /// (compared to computing dominators and loop info) analysis. Modified: llvm/trunk/include/llvm/Transforms/Utils/Local.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Local.h?rev=104949&r1=104948&r2=104949&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/Local.h (original) +++ llvm/trunk/include/llvm/Transforms/Utils/Local.h Fri May 28 11:19:17 2010 @@ -31,17 +31,6 @@ template class SmallVectorImpl; //===----------------------------------------------------------------------===// -// Local analysis. -// - -/// isSafeToLoadUnconditionally - Return true if we know that executing a load -/// from this value cannot trap. If it is not obviously safe to load from the -/// specified pointer, we do a quick local scan of the basic block containing -/// ScanFrom, to determine if the address is already accessed. -bool isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom, - unsigned Align, const TargetData *TD = 0); - -//===----------------------------------------------------------------------===// // Local constant propagation. // Modified: llvm/trunk/lib/Analysis/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CMakeLists.txt?rev=104949&r1=104948&r2=104949&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/CMakeLists.txt (original) +++ llvm/trunk/lib/Analysis/CMakeLists.txt Fri May 28 11:19:17 2010 @@ -23,6 +23,7 @@ LibCallSemantics.cpp Lint.cpp LiveValues.cpp + Loads.cpp LoopDependenceAnalysis.cpp LoopInfo.cpp LoopPass.cpp Added: llvm/trunk/lib/Analysis/Loads.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/Loads.cpp?rev=104949&view=auto ============================================================================== --- llvm/trunk/lib/Analysis/Loads.cpp (added) +++ llvm/trunk/lib/Analysis/Loads.cpp Fri May 28 11:19:17 2010 @@ -0,0 +1,235 @@ +//===- Loads.cpp - Local load analysis ------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines simple local analyses for load instructions. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Analysis/Loads.h" +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Target/TargetData.h" +#include "llvm/GlobalAlias.h" +#include "llvm/GlobalVariable.h" +#include "llvm/IntrinsicInst.h" +using namespace llvm; + +/// AreEquivalentAddressValues - Test if A and B will obviously have the same +/// value. This includes recognizing that %t0 and %t1 will have the same +/// value in code like this: +/// %t0 = getelementptr \@a, 0, 3 +/// store i32 0, i32* %t0 +/// %t1 = getelementptr \@a, 0, 3 +/// %t2 = load i32* %t1 +/// +static bool AreEquivalentAddressValues(const Value *A, const Value *B) { + // Test if the values are trivially equivalent. + if (A == B) return true; + + // Test if the values come from identical arithmetic instructions. + // Use isIdenticalToWhenDefined instead of isIdenticalTo because + // this function is only used when one address use dominates the + // other, which means that they'll always either have the same + // value or one of them will have an undefined value. + if (isa(A) || isa(A) || + isa(A) || isa(A)) + if (const Instruction *BI = dyn_cast(B)) + if (cast(A)->isIdenticalToWhenDefined(BI)) + return true; + + // Otherwise they may not be equivalent. + return false; +} + +/// getUnderlyingObjectWithOffset - Strip off up to MaxLookup GEPs and +/// bitcasts to get back to the underlying object being addressed, keeping +/// track of the offset in bytes from the GEPs relative to the result. +/// This is closely related to Value::getUnderlyingObject but is located +/// here to avoid making VMCore depend on TargetData. +static Value *getUnderlyingObjectWithOffset(Value *V, const TargetData *TD, + uint64_t &ByteOffset, + unsigned MaxLookup = 6) { + if (!V->getType()->isPointerTy()) + return V; + for (unsigned Count = 0; MaxLookup == 0 || Count < MaxLookup; ++Count) { + if (GEPOperator *GEP = dyn_cast(V)) { + if (!GEP->hasAllConstantIndices()) + return V; + SmallVector Indices(GEP->op_begin() + 1, GEP->op_end()); + ByteOffset += TD->getIndexedOffset(GEP->getPointerOperandType(), + &Indices[0], Indices.size()); + V = GEP->getPointerOperand(); + } else if (Operator::getOpcode(V) == Instruction::BitCast) { + V = cast(V)->getOperand(0); + } else if (GlobalAlias *GA = dyn_cast(V)) { + if (GA->mayBeOverridden()) + return V; + V = GA->getAliasee(); + } else { + return V; + } + assert(V->getType()->isPointerTy() && "Unexpected operand type!"); + } + return V; +} + +/// isSafeToLoadUnconditionally - Return true if we know that executing a load +/// from this value cannot trap. If it is not obviously safe to load from the +/// specified pointer, we do a quick local scan of the basic block containing +/// ScanFrom, to determine if the address is already accessed. +bool llvm::isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom, + unsigned Align, const TargetData *TD) { + uint64_t ByteOffset = 0; + Value *Base = V; + if (TD) + Base = getUnderlyingObjectWithOffset(V, TD, ByteOffset); + + const Type *BaseType = 0; + unsigned BaseAlign = 0; + if (const AllocaInst *AI = dyn_cast(Base)) { + // An alloca is safe to load from as load as it is suitably aligned. + BaseType = AI->getAllocatedType(); + BaseAlign = AI->getAlignment(); + } else if (const GlobalValue *GV = dyn_cast(Base)) { + // Global variables are safe to load from but their size cannot be + // guaranteed if they are overridden. + if (!isa(GV) && !GV->mayBeOverridden()) { + BaseType = GV->getType()->getElementType(); + BaseAlign = GV->getAlignment(); + } + } + + if (BaseType && BaseType->isSized()) { + if (TD && BaseAlign == 0) + BaseAlign = TD->getPrefTypeAlignment(BaseType); + + if (Align <= BaseAlign) { + if (!TD) + return true; // Loading directly from an alloca or global is OK. + + // Check if the load is within the bounds of the underlying object. + const PointerType *AddrTy = cast(V->getType()); + uint64_t LoadSize = TD->getTypeStoreSize(AddrTy->getElementType()); + if (ByteOffset + LoadSize <= TD->getTypeAllocSize(BaseType) && + (Align == 0 || (ByteOffset % Align) == 0)) + return true; + } + } + + // Otherwise, be a little bit aggressive by scanning the local block where we + // want to check to see if the pointer is already being loaded or stored + // from/to. If so, the previous load or store would have already trapped, + // so there is no harm doing an extra load (also, CSE will later eliminate + // the load entirely). + BasicBlock::iterator BBI = ScanFrom, E = ScanFrom->getParent()->begin(); + + while (BBI != E) { + --BBI; + + // If we see a free or a call which may write to memory (i.e. which might do + // a free) the pointer could be marked invalid. + if (isa(BBI) && BBI->mayWriteToMemory() && + !isa(BBI)) + return false; + + if (LoadInst *LI = dyn_cast(BBI)) { + if (AreEquivalentAddressValues(LI->getOperand(0), V)) return true; + } else if (StoreInst *SI = dyn_cast(BBI)) { + if (AreEquivalentAddressValues(SI->getOperand(1), V)) return true; + } + } + return false; +} + +/// FindAvailableLoadedValue - Scan the ScanBB block backwards (starting at the +/// instruction before ScanFrom) checking to see if we have the value at the +/// memory address *Ptr locally available within a small number of instructions. +/// If the value is available, return it. +/// +/// If not, return the iterator for the last validated instruction that the +/// value would be live through. If we scanned the entire block and didn't find +/// something that invalidates *Ptr or provides it, ScanFrom would be left at +/// begin() and this returns null. ScanFrom could also be left +/// +/// MaxInstsToScan specifies the maximum instructions to scan in the block. If +/// it is set to 0, it will scan the whole block. You can also optionally +/// specify an alias analysis implementation, which makes this more precise. +Value *llvm::FindAvailableLoadedValue(Value *Ptr, BasicBlock *ScanBB, + BasicBlock::iterator &ScanFrom, + unsigned MaxInstsToScan, + AliasAnalysis *AA) { + if (MaxInstsToScan == 0) MaxInstsToScan = ~0U; + + // If we're using alias analysis to disambiguate get the size of *Ptr. + unsigned AccessSize = 0; + if (AA) { + const Type *AccessTy = cast(Ptr->getType())->getElementType(); + AccessSize = AA->getTypeStoreSize(AccessTy); + } + + while (ScanFrom != ScanBB->begin()) { + // We must ignore debug info directives when counting (otherwise they + // would affect codegen). + Instruction *Inst = --ScanFrom; + if (isa(Inst)) + continue; + + // Restore ScanFrom to expected value in case next test succeeds + ScanFrom++; + + // Don't scan huge blocks. + if (MaxInstsToScan-- == 0) return 0; + + --ScanFrom; + // If this is a load of Ptr, the loaded value is available. + if (LoadInst *LI = dyn_cast(Inst)) + if (AreEquivalentAddressValues(LI->getOperand(0), Ptr)) + return LI; + + if (StoreInst *SI = dyn_cast(Inst)) { + // If this is a store through Ptr, the value is available! + if (AreEquivalentAddressValues(SI->getOperand(1), Ptr)) + return SI->getOperand(0); + + // If Ptr is an alloca and this is a store to a different alloca, ignore + // the store. This is a trivial form of alias analysis that is important + // for reg2mem'd code. + if ((isa(Ptr) || isa(Ptr)) && + (isa(SI->getOperand(1)) || + isa(SI->getOperand(1)))) + continue; + + // If we have alias analysis and it says the store won't modify the loaded + // value, ignore the store. + if (AA && + (AA->getModRefInfo(SI, Ptr, AccessSize) & AliasAnalysis::Mod) == 0) + continue; + + // Otherwise the store that may or may not alias the pointer, bail out. + ++ScanFrom; + return 0; + } + + // If this is some other instruction that may clobber Ptr, bail out. + if (Inst->mayWriteToMemory()) { + // If alias analysis claims that it really won't modify the load, + // ignore it. + if (AA && + (AA->getModRefInfo(Inst, Ptr, AccessSize) & AliasAnalysis::Mod) == 0) + continue; + + // May modify the pointer, bail out. + ++ScanFrom; + return 0; + } + } + + // Got to the start of the block, we didn't find it, but are done for this + // block. + return 0; +} Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp?rev=104949&r1=104948&r2=104949&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp Fri May 28 11:19:17 2010 @@ -13,6 +13,7 @@ #include "InstCombine.h" #include "llvm/IntrinsicInst.h" +#include "llvm/Analysis/Loads.h" #include "llvm/Target/TargetData.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/Local.h" Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=104949&r1=104948&r2=104949&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Fri May 28 11:19:17 2010 @@ -35,6 +35,7 @@ #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/Loads.h" #include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/MemoryDependenceAnalysis.h" #include "llvm/Analysis/PHITransAddr.h" Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=104949&r1=104948&r2=104949&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Fri May 28 11:19:17 2010 @@ -18,6 +18,7 @@ #include "llvm/Pass.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/LazyValueInfo.h" +#include "llvm/Analysis/Loads.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/SSAUpdater.h" Modified: llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp?rev=104949&r1=104948&r2=104949&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/TailRecursionElimination.cpp Fri May 28 11:19:17 2010 @@ -60,6 +60,7 @@ #include "llvm/Pass.h" #include "llvm/Analysis/CaptureTracking.h" #include "llvm/Analysis/InlineCost.h" +#include "llvm/Analysis/Loads.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/CFG.h" #include "llvm/ADT/Statistic.h" Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp?rev=104949&r1=104948&r2=104949&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Fri May 28 11:19:17 2010 @@ -558,121 +558,3 @@ } - - - -/// AreEquivalentAddressValues - Test if A and B will obviously have the same -/// value. This includes recognizing that %t0 and %t1 will have the same -/// value in code like this: -/// %t0 = getelementptr \@a, 0, 3 -/// store i32 0, i32* %t0 -/// %t1 = getelementptr \@a, 0, 3 -/// %t2 = load i32* %t1 -/// -static bool AreEquivalentAddressValues(const Value *A, const Value *B) { - // Test if the values are trivially equivalent. - if (A == B) return true; - - // Test if the values come from identical arithmetic instructions. - // Use isIdenticalToWhenDefined instead of isIdenticalTo because - // this function is only used when one address use dominates the - // other, which means that they'll always either have the same - // value or one of them will have an undefined value. - if (isa(A) || isa(A) || - isa(A) || isa(A)) - if (const Instruction *BI = dyn_cast(B)) - if (cast(A)->isIdenticalToWhenDefined(BI)) - return true; - - // Otherwise they may not be equivalent. - return false; -} - -/// FindAvailableLoadedValue - Scan the ScanBB block backwards (starting at the -/// instruction before ScanFrom) checking to see if we have the value at the -/// memory address *Ptr locally available within a small number of instructions. -/// If the value is available, return it. -/// -/// If not, return the iterator for the last validated instruction that the -/// value would be live through. If we scanned the entire block and didn't find -/// something that invalidates *Ptr or provides it, ScanFrom would be left at -/// begin() and this returns null. ScanFrom could also be left -/// -/// MaxInstsToScan specifies the maximum instructions to scan in the block. If -/// it is set to 0, it will scan the whole block. You can also optionally -/// specify an alias analysis implementation, which makes this more precise. -Value *llvm::FindAvailableLoadedValue(Value *Ptr, BasicBlock *ScanBB, - BasicBlock::iterator &ScanFrom, - unsigned MaxInstsToScan, - AliasAnalysis *AA) { - if (MaxInstsToScan == 0) MaxInstsToScan = ~0U; - - // If we're using alias analysis to disambiguate get the size of *Ptr. - unsigned AccessSize = 0; - if (AA) { - const Type *AccessTy = cast(Ptr->getType())->getElementType(); - AccessSize = AA->getTypeStoreSize(AccessTy); - } - - while (ScanFrom != ScanBB->begin()) { - // We must ignore debug info directives when counting (otherwise they - // would affect codegen). - Instruction *Inst = --ScanFrom; - if (isa(Inst)) - continue; - - // Restore ScanFrom to expected value in case next test succeeds - ScanFrom++; - - // Don't scan huge blocks. - if (MaxInstsToScan-- == 0) return 0; - - --ScanFrom; - // If this is a load of Ptr, the loaded value is available. - if (LoadInst *LI = dyn_cast(Inst)) - if (AreEquivalentAddressValues(LI->getOperand(0), Ptr)) - return LI; - - if (StoreInst *SI = dyn_cast(Inst)) { - // If this is a store through Ptr, the value is available! - if (AreEquivalentAddressValues(SI->getOperand(1), Ptr)) - return SI->getOperand(0); - - // If Ptr is an alloca and this is a store to a different alloca, ignore - // the store. This is a trivial form of alias analysis that is important - // for reg2mem'd code. - if ((isa(Ptr) || isa(Ptr)) && - (isa(SI->getOperand(1)) || - isa(SI->getOperand(1)))) - continue; - - // If we have alias analysis and it says the store won't modify the loaded - // value, ignore the store. - if (AA && - (AA->getModRefInfo(SI, Ptr, AccessSize) & AliasAnalysis::Mod) == 0) - continue; - - // Otherwise the store that may or may not alias the pointer, bail out. - ++ScanFrom; - return 0; - } - - // If this is some other instruction that may clobber Ptr, bail out. - if (Inst->mayWriteToMemory()) { - // If alias analysis claims that it really won't modify the load, - // ignore it. - if (AA && - (AA->getModRefInfo(Inst, Ptr, AccessSize) & AliasAnalysis::Mod) == 0) - continue; - - // May modify the pointer, bail out. - ++ScanFrom; - return 0; - } - } - - // Got to the start of the block, we didn't find it, but are done for this - // block. - return 0; -} - Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=104949&r1=104948&r2=104949&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Fri May 28 11:19:17 2010 @@ -35,111 +35,6 @@ using namespace llvm; //===----------------------------------------------------------------------===// -// Local analysis. -// - -/// getUnderlyingObjectWithOffset - Strip off up to MaxLookup GEPs and -/// bitcasts to get back to the underlying object being addressed, keeping -/// track of the offset in bytes from the GEPs relative to the result. -/// This is closely related to Value::getUnderlyingObject but is located -/// here to avoid making VMCore depend on TargetData. -static Value *getUnderlyingObjectWithOffset(Value *V, const TargetData *TD, - uint64_t &ByteOffset, - unsigned MaxLookup = 6) { - if (!V->getType()->isPointerTy()) - return V; - for (unsigned Count = 0; MaxLookup == 0 || Count < MaxLookup; ++Count) { - if (GEPOperator *GEP = dyn_cast(V)) { - if (!GEP->hasAllConstantIndices()) - return V; - SmallVector Indices(GEP->op_begin() + 1, GEP->op_end()); - ByteOffset += TD->getIndexedOffset(GEP->getPointerOperandType(), - &Indices[0], Indices.size()); - V = GEP->getPointerOperand(); - } else if (Operator::getOpcode(V) == Instruction::BitCast) { - V = cast(V)->getOperand(0); - } else if (GlobalAlias *GA = dyn_cast(V)) { - if (GA->mayBeOverridden()) - return V; - V = GA->getAliasee(); - } else { - return V; - } - assert(V->getType()->isPointerTy() && "Unexpected operand type!"); - } - return V; -} - -/// isSafeToLoadUnconditionally - Return true if we know that executing a load -/// from this value cannot trap. If it is not obviously safe to load from the -/// specified pointer, we do a quick local scan of the basic block containing -/// ScanFrom, to determine if the address is already accessed. -bool llvm::isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom, - unsigned Align, const TargetData *TD) { - uint64_t ByteOffset = 0; - Value *Base = V; - if (TD) - Base = getUnderlyingObjectWithOffset(V, TD, ByteOffset); - - const Type *BaseType = 0; - unsigned BaseAlign = 0; - if (const AllocaInst *AI = dyn_cast(Base)) { - // An alloca is safe to load from as load as it is suitably aligned. - BaseType = AI->getAllocatedType(); - BaseAlign = AI->getAlignment(); - } else if (const GlobalValue *GV = dyn_cast(Base)) { - // Global variables are safe to load from but their size cannot be - // guaranteed if they are overridden. - if (!isa(GV) && !GV->mayBeOverridden()) { - BaseType = GV->getType()->getElementType(); - BaseAlign = GV->getAlignment(); - } - } - - if (BaseType && BaseType->isSized()) { - if (TD && BaseAlign == 0) - BaseAlign = TD->getPrefTypeAlignment(BaseType); - - if (Align <= BaseAlign) { - if (!TD) - return true; // Loading directly from an alloca or global is OK. - - // Check if the load is within the bounds of the underlying object. - const PointerType *AddrTy = cast(V->getType()); - uint64_t LoadSize = TD->getTypeStoreSize(AddrTy->getElementType()); - if (ByteOffset + LoadSize <= TD->getTypeAllocSize(BaseType) && - (Align == 0 || (ByteOffset % Align) == 0)) - return true; - } - } - - // Otherwise, be a little bit aggressive by scanning the local block where we - // want to check to see if the pointer is already being loaded or stored - // from/to. If so, the previous load or store would have already trapped, - // so there is no harm doing an extra load (also, CSE will later eliminate - // the load entirely). - BasicBlock::iterator BBI = ScanFrom, E = ScanFrom->getParent()->begin(); - - while (BBI != E) { - --BBI; - - // If we see a free or a call which may write to memory (i.e. which might do - // a free) the pointer could be marked invalid. - if (isa(BBI) && BBI->mayWriteToMemory() && - !isa(BBI)) - return false; - - if (LoadInst *LI = dyn_cast(BBI)) { - if (LI->getOperand(0) == V) return true; - } else if (StoreInst *SI = dyn_cast(BBI)) { - if (SI->getOperand(1) == V) return true; - } - } - return false; -} - - -//===----------------------------------------------------------------------===// // Local constant propagation. // From gohman at apple.com Fri May 28 11:21:24 2010 From: gohman at apple.com (Dan Gohman) Date: Fri, 28 May 2010 16:21:24 -0000 Subject: [llvm-commits] [llvm] r104950 - in /llvm/trunk: lib/Analysis/Lint.cpp test/Other/lint.ll Message-ID: <20100528162125.00148312800A@llvm.org> Author: djg Date: Fri May 28 11:21:24 2010 New Revision: 104950 URL: http://llvm.org/viewvc/llvm-project?rev=104950&view=rev Log: Teach lint how to look through simple store+load pairs and other effective no-op constructs, to make it more effective on unoptimized IR. Modified: llvm/trunk/lib/Analysis/Lint.cpp llvm/trunk/test/Other/lint.ll Modified: llvm/trunk/lib/Analysis/Lint.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/Lint.cpp?rev=104950&r1=104949&r2=104950&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/Lint.cpp (original) +++ llvm/trunk/lib/Analysis/Lint.cpp Fri May 28 11:21:24 2010 @@ -35,7 +35,11 @@ #include "llvm/Analysis/Passes.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/InstructionSimplify.h" +#include "llvm/Analysis/ConstantFolding.h" +#include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/Lint.h" +#include "llvm/Analysis/Loads.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/Assembly/Writer.h" #include "llvm/Target/TargetData.h" @@ -88,9 +92,12 @@ void visitInsertElementInst(InsertElementInst &I); void visitUnreachableInst(UnreachableInst &I); + Value *findValue(Value *V, bool OffsetOk) const; + public: Module *Mod; AliasAnalysis *AA; + DominatorTree *DT; TargetData *TD; std::string Messages; @@ -104,6 +111,7 @@ virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); AU.addRequired(); + AU.addRequired(); } virtual void print(raw_ostream &O, const Module *M) const {} @@ -176,6 +184,7 @@ bool Lint::runOnFunction(Function &F) { Mod = F.getParent(); AA = &getAnalysis(); + DT = &getAnalysis(); TD = getAnalysisIfAvailable(); visit(F); dbgs() << MessagesStr.str(); @@ -196,7 +205,7 @@ visitMemoryReference(I, Callee, 0, 0, MemRef::Callee); - if (Function *F = dyn_cast(Callee->stripPointerCasts())) { + if (Function *F = dyn_cast(findValue(Callee, /*OffsetOk=*/false))) { Assert1(CS.getCallingConv() == F->getCallingConv(), "Undefined behavior: Caller and callee calling convention differ", &I); @@ -222,7 +231,7 @@ if (CS.isCall() && cast(CS.getInstruction())->isTailCall()) for (CallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end(); AI != AE; ++AI) { - Value *Obj = (*AI)->getUnderlyingObject(); + Value *Obj = findValue(*AI, /*OffsetOk=*/true); Assert1(!isa(Obj) && !isa(Obj), "Undefined behavior: Call with \"tail\" keyword references " "alloca or va_arg", &I); @@ -247,7 +256,8 @@ // overlap is not distinguished from the case where nothing is known. unsigned Size = 0; if (const ConstantInt *Len = - dyn_cast(MCI->getLength()->stripPointerCasts())) + dyn_cast(findValue(MCI->getLength(), + /*OffsetOk=*/false))) if (Len->getValue().isIntN(32)) Size = Len->getValue().getZExtValue(); Assert1(AA->alias(MCI->getSource(), Size, MCI->getDest(), Size) != @@ -312,7 +322,7 @@ &I); if (Value *V = I.getReturnValue()) { - Value *Obj = V->getUnderlyingObject(); + Value *Obj = findValue(V, /*OffsetOk=*/true); Assert1(!isa(Obj) && !isa(Obj), "Unusual: Returning alloca or va_arg value", &I); } @@ -322,7 +332,7 @@ void Lint::visitMemoryReference(Instruction &I, Value *Ptr, unsigned Align, const Type *Ty, unsigned Flags) { - Value *UnderlyingObject = Ptr->getUnderlyingObject(); + Value *UnderlyingObject = findValue(Ptr, /*OffsetOk=*/true); Assert1(!isa(UnderlyingObject), "Undefined behavior: Null pointer dereference", &I); Assert1(!isa(UnderlyingObject), @@ -390,21 +400,21 @@ void Lint::visitLShr(BinaryOperator &I) { if (ConstantInt *CI = - dyn_cast(I.getOperand(1)->stripPointerCasts())) + dyn_cast(findValue(I.getOperand(1), /*OffsetOk=*/false))) Assert1(CI->getValue().ult(cast(I.getType())->getBitWidth()), "Undefined result: Shift count out of range", &I); } void Lint::visitAShr(BinaryOperator &I) { if (ConstantInt *CI = - dyn_cast(I.getOperand(1)->stripPointerCasts())) + dyn_cast(findValue(I.getOperand(1), /*OffsetOk=*/false))) Assert1(CI->getValue().ult(cast(I.getType())->getBitWidth()), "Undefined result: Shift count out of range", &I); } void Lint::visitShl(BinaryOperator &I) { if (ConstantInt *CI = - dyn_cast(I.getOperand(1)->stripPointerCasts())) + dyn_cast(findValue(I.getOperand(1), /*OffsetOk=*/false))) Assert1(CI->getValue().ult(cast(I.getType())->getBitWidth()), "Undefined result: Shift count out of range", &I); } @@ -458,14 +468,16 @@ void Lint::visitExtractElementInst(ExtractElementInst &I) { if (ConstantInt *CI = - dyn_cast(I.getIndexOperand()->stripPointerCasts())) + dyn_cast(findValue(I.getIndexOperand(), + /*OffsetOk=*/false))) Assert1(CI->getValue().ult(I.getVectorOperandType()->getNumElements()), "Undefined result: extractelement index out of range", &I); } void Lint::visitInsertElementInst(InsertElementInst &I) { if (ConstantInt *CI = - dyn_cast(I.getOperand(2)->stripPointerCasts())) + dyn_cast(findValue(I.getOperand(2), + /*OffsetOk=*/false))) Assert1(CI->getValue().ult(I.getType()->getNumElements()), "Undefined result: insertelement index out of range", &I); } @@ -478,6 +490,59 @@ "side effects", &I); } +/// findValue - Look through bitcasts and simple memory reference patterns +/// to identify an equivalent, but more informative, value. If OffsetOk +/// is true, look through getelementptrs with non-zero offsets too. +/// +/// Most analysis passes don't require this logic, because instcombine +/// will simplify most of these kinds of things away. But it's a goal of +/// this Lint pass to be useful even on non-optimized IR. +Value *Lint::findValue(Value *V, bool OffsetOk) const { + // TODO: Look through sext or zext cast, when the result is known to + // be interpreted as signed or unsigned, respectively. + // TODO: Look through calls with unique return values. + // TODO: Look through vector insert/extract/shuffle. + V = OffsetOk ? V->getUnderlyingObject() : V->stripPointerCasts(); + if (LoadInst *L = dyn_cast(V)) { + BasicBlock::iterator BBI = L; + BasicBlock *BB = L->getParent(); + for (;;) { + if (Value *U = FindAvailableLoadedValue(L->getPointerOperand(), + BB, BBI, 6, AA)) + return findValue(U, OffsetOk); + BB = L->getParent()->getUniquePredecessor(); + if (!BB) break; + BBI = BB->end(); + } + } else if (CastInst *CI = dyn_cast(V)) { + if (CI->isNoopCast(TD ? TD->getIntPtrType(V->getContext()) : + Type::getInt64Ty(V->getContext()))) + return findValue(CI->getOperand(0), OffsetOk); + } else if (PHINode *PN = dyn_cast(V)) { + if (Value *W = PN->hasConstantValue(DT)) + return findValue(W, OffsetOk); + } else if (ExtractValueInst *Ex = dyn_cast(V)) { + if (Value *W = FindInsertedValue(Ex->getAggregateOperand(), + Ex->idx_begin(), + Ex->idx_end())) + if (W != V) + return findValue(W, OffsetOk); + } + + // As a last resort, try SimplifyInstruction or constant folding. + if (Instruction *Inst = dyn_cast(V)) { + if (Value *W = SimplifyInstruction(Inst, TD)) + if (W != Inst) + return findValue(W, OffsetOk); + } else if (ConstantExpr *CE = dyn_cast(V)) { + if (Value *W = ConstantFoldConstantExpression(CE, TD)) + if (W != V) + return findValue(W, OffsetOk); + } + + return V; +} + //===----------------------------------------------------------------------===// // Implement the public interfaces to this file... //===----------------------------------------------------------------------===// Modified: llvm/trunk/test/Other/lint.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/lint.ll?rev=104950&r1=104949&r2=104950&view=diff ============================================================================== --- llvm/trunk/test/Other/lint.ll (original) +++ llvm/trunk/test/Other/lint.ll Fri May 28 11:21:24 2010 @@ -104,3 +104,24 @@ %s = getelementptr i8* %t, i32 %m ret i8* %s } + +; CHECK: Unusual: Returning alloca or va_arg value +define i32* @return_obscured_local() { +entry: + %retval = alloca i32* + %x = alloca i32 + store i32* %x, i32** %retval + br label %next +next: + %t0 = load i32** %retval + %t1 = insertvalue { i32, i32, i32* } zeroinitializer, i32* %t0, 2 + %t2 = extractvalue { i32, i32, i32* } %t1, 2 + br label %exit +exit: + %t3 = phi i32* [ %t2, %next ] + %t4 = bitcast i32* %t3 to i32* + %t5 = ptrtoint i32* %t4 to i64 + %t6 = add i64 %t5, 0 + %t7 = inttoptr i64 %t6 to i32* + ret i32* %t7 +} From gohman at apple.com Fri May 28 11:34:49 2010 From: gohman at apple.com (Dan Gohman) Date: Fri, 28 May 2010 16:34:49 -0000 Subject: [llvm-commits] [llvm] r104951 - in /llvm/trunk: lib/Analysis/Lint.cpp test/Other/lint.ll Message-ID: <20100528163449.C15EB312800A@llvm.org> Author: djg Date: Fri May 28 11:34:49 2010 New Revision: 104951 URL: http://llvm.org/viewvc/llvm-project?rev=104951&view=rev Log: Eli pointed out that va_arg instruction result values don't reference the stack. Modified: llvm/trunk/lib/Analysis/Lint.cpp llvm/trunk/test/Other/lint.ll Modified: llvm/trunk/lib/Analysis/Lint.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/Lint.cpp?rev=104951&r1=104950&r2=104951&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/Lint.cpp (original) +++ llvm/trunk/lib/Analysis/Lint.cpp Fri May 28 11:34:49 2010 @@ -232,9 +232,9 @@ for (CallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end(); AI != AE; ++AI) { Value *Obj = findValue(*AI, /*OffsetOk=*/true); - Assert1(!isa(Obj) && !isa(Obj), + Assert1(!isa(Obj), "Undefined behavior: Call with \"tail\" keyword references " - "alloca or va_arg", &I); + "alloca", &I); } @@ -323,8 +323,8 @@ if (Value *V = I.getReturnValue()) { Value *Obj = findValue(V, /*OffsetOk=*/true); - Assert1(!isa(Obj) && !isa(Obj), - "Unusual: Returning alloca or va_arg value", &I); + Assert1(!isa(Obj), + "Unusual: Returning alloca value", &I); } } Modified: llvm/trunk/test/Other/lint.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/lint.ll?rev=104951&r1=104950&r2=104951&view=diff ============================================================================== --- llvm/trunk/test/Other/lint.ll (original) +++ llvm/trunk/test/Other/lint.ll Fri May 28 11:34:49 2010 @@ -87,8 +87,8 @@ unreachable } -; CHECK: Undefined behavior: Call with "tail" keyword references alloca or va_arg -; CHECK: Undefined behavior: Call with "tail" keyword references alloca or va_arg +; CHECK: Undefined behavior: Call with "tail" keyword references alloca +; CHECK: Undefined behavior: Call with "tail" keyword references alloca declare void @tailcallee(i8*) define void @use_tail(i8* %valist) { %t = alloca i8 @@ -98,14 +98,14 @@ ret void } -; CHECK: Unusual: Returning alloca or va_arg value +; CHECK: Unusual: Returning alloca value define i8* @return_local(i32 %n, i32 %m) { %t = alloca i8, i32 %n %s = getelementptr i8* %t, i32 %m ret i8* %s } -; CHECK: Unusual: Returning alloca or va_arg value +; CHECK: Unusual: Returning alloca value define i32* @return_obscured_local() { entry: %retval = alloca i32* From stuart at apple.com Fri May 28 11:41:07 2010 From: stuart at apple.com (Stuart Hastings) Date: Fri, 28 May 2010 16:41:07 -0000 Subject: [llvm-commits] [llvm] r104953 - in /llvm/trunk: lib/Analysis/DebugInfo.cpp lib/CodeGen/AsmPrinter/DwarfDebug.cpp test/FrontendC++/2010-02-17-DbgArtificialArg.cpp test/FrontendC/2010-03-5-LexicalScope.c Message-ID: <20100528164107.D252B312800A@llvm.org> Author: stuart Date: Fri May 28 11:41:07 2010 New Revision: 104953 URL: http://llvm.org/viewvc/llvm-project?rev=104953&view=rev Log: Revert 104841, 104842, 104876 due to buildbot failures. Radar 7424645. Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp llvm/trunk/test/FrontendC++/2010-02-17-DbgArtificialArg.cpp llvm/trunk/test/FrontendC/2010-03-5-LexicalScope.c Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DebugInfo.cpp?rev=104953&r1=104952&r2=104953&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/DebugInfo.cpp (original) +++ llvm/trunk/lib/Analysis/DebugInfo.cpp Fri May 28 11:41:07 2010 @@ -1110,6 +1110,18 @@ return DILocation(MDNode::get(VMContext, &Elts[0], 4)); } +/// CreateLocation - Creates a debug info location. +DILocation DIFactory::CreateLocation(unsigned LineNo, unsigned ColumnNo, + DIScope S, MDNode *OrigLoc) { + Value *Elts[] = { + ConstantInt::get(Type::getInt32Ty(VMContext), LineNo), + ConstantInt::get(Type::getInt32Ty(VMContext), ColumnNo), + S, + OrigLoc + }; + return DILocation(MDNode::get(VMContext, &Elts[0], 4)); +} + //===----------------------------------------------------------------------===// // DIFactory: Routines for inserting code into a function //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=104953&r1=104952&r2=104953&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Fri May 28 11:41:07 2010 @@ -866,10 +866,6 @@ } else if (Context.isNameSpace()) { DIE *ContextDIE = getOrCreateNameSpace(DINameSpace(Context)); ContextDIE->addChild(Die); - } else if (Context.isSubprogram()) { - DIE *ContextDIE = createSubprogramDIE(DISubprogram(Context), - /*MakeDecl=*/false); - ContextDIE->addChild(Die); } else if (DIE *ContextDIE = getCompileUnit(Context)->getDIE(Context)) ContextDIE->addChild(Die); else @@ -1059,10 +1055,6 @@ if (DIDescriptor(ContainingType).isCompositeType()) addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, getOrCreateTypeDIE(DIType(ContainingType))); - else { - DIDescriptor Context = CTy.getContext(); - addToContextOwner(&Buffer, Context); - } break; } default: @@ -1337,9 +1329,6 @@ // DW_TAG_inlined_subroutine may refer to this DIE. SPCU->insertDIE(SP, SPDie); - // Add to context owner. - addToContextOwner(SPDie, SP.getContext()); - return SPDie; } Modified: llvm/trunk/test/FrontendC++/2010-02-17-DbgArtificialArg.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendC%2B%2B/2010-02-17-DbgArtificialArg.cpp?rev=104953&r1=104952&r2=104953&view=diff ============================================================================== --- llvm/trunk/test/FrontendC++/2010-02-17-DbgArtificialArg.cpp (original) +++ llvm/trunk/test/FrontendC++/2010-02-17-DbgArtificialArg.cpp Fri May 28 11:41:07 2010 @@ -1,4 +1,4 @@ -// RUN: %llvmgcc -g -S %s -o - | FileCheck %s +// RUN: %llvmgcc -g -S %s -o - | grep DW_TAG_pointer_type | grep "i32 524303, metadata .., metadata ..., metadata .., i32 ., i64 .., i64 .., i64 0, i32 64, metadata ..." // Here, second to last argument "i32 64" indicates that artificial type is set. // Test to artificial attribute attahed to "this" pointer type. // Radar 7655792 and 7655002 @@ -10,7 +10,5 @@ int foo() { A a; - // Matching "i32 64, metadata !} ; [ DW_TAG_pointer_type ]" - // CHECK: i32 64, metadata {{![0-9]+\} ; \[ DW_TAG_pointer_type \]}} return a.fn1(1); } Modified: llvm/trunk/test/FrontendC/2010-03-5-LexicalScope.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendC/2010-03-5-LexicalScope.c?rev=104953&r1=104952&r2=104953&view=diff ============================================================================== --- llvm/trunk/test/FrontendC/2010-03-5-LexicalScope.c (original) +++ llvm/trunk/test/FrontendC/2010-03-5-LexicalScope.c Fri May 28 11:41:07 2010 @@ -1,4 +1,4 @@ -// RUN: %llvmgcc -S -O0 -g %s -o - | grep DW_TAG_lexical_block | count 2 +// RUN: %llvmgcc -S -O0 -g %s -o - | grep DW_TAG_lexical_block | count 3 int foo(int i) { if (i) { int j = 2; From stuart at apple.com Fri May 28 11:42:52 2010 From: stuart at apple.com (Stuart Hastings) Date: Fri, 28 May 2010 16:42:52 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r104954 - in /llvm-gcc-4.2/trunk/gcc: llvm-backend.cpp llvm-convert.cpp llvm-debug.cpp llvm-debug.h llvm-internal.h Message-ID: <20100528164252.86C09312800A@llvm.org> Author: stuart Date: Fri May 28 11:42:52 2010 New Revision: 104954 URL: http://llvm.org/viewvc/llvm-project?rev=104954&view=rev Log: Revert 104841, 104842, 104876 due to buildbot failures. Radar 7424645. Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp llvm-gcc-4.2/trunk/gcc/llvm-debug.h llvm-gcc-4.2/trunk/gcc/llvm-internal.h Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=104954&r1=104953&r2=104954&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Fri May 28 11:42:52 2010 @@ -531,8 +531,6 @@ if (debug_info_level > DINFO_LEVEL_NONE) TheDebugInfo = new DebugInfo(TheModule); - else - TheDebugInfo = 0; } /// performLateBackendInitialization - Set backend options that may only be @@ -1025,7 +1023,7 @@ // Convert the AST to raw/ugly LLVM code. Function *Fn; { - TreeToLLVM *Emitter = new TreeToLLVM(fndecl); + TreeToLLVM Emitter(fndecl); enum symbol_visibility vis = DECL_VISIBILITY (fndecl); if (vis != VISIBILITY_DEFAULT) @@ -1033,8 +1031,7 @@ // visibility that's not supported by the target. targetm.asm_out.visibility(fndecl, vis); - Fn = TheTreeToLLVM->EmitFunction(); - Emitter->~TreeToLLVM(); + Fn = Emitter.EmitFunction(); } #if 0 Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=104954&r1=104953&r2=104954&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Fri May 28 11:42:52 2010 @@ -148,7 +148,7 @@ //===----------------------------------------------------------------------===// /// TheTreeToLLVM - Keep track of the current function being compiled. -TreeToLLVM *TheTreeToLLVM = 0; +static TreeToLLVM *TheTreeToLLVM = 0; const TargetData &getTargetData() { return *TheTarget->getTargetData(); @@ -157,7 +157,7 @@ /// EmitDebugInfo - Return true if debug info is to be emitted for current /// function. bool TreeToLLVM::EmitDebugInfo() { - if (TheDebugInfo && getFUNCTION_DECL() && !DECL_IGNORED_P(getFUNCTION_DECL())) + if (TheDebugInfo && !DECL_IGNORED_P(getFUNCTION_DECL())) return true; return false; } @@ -425,13 +425,13 @@ return (Val = false); } -// Depth-first walk of the GCC BLOCK() tree. Set BLOCK_NUMBER() to -// the depth of each block; this is necessary for lexical block debug -// info. Visit all the BLOCK_VARS(), and add them to the set s. -// Since the unexpanded_var_list seems to be a superset of all the -// scoped variables in every lexical BLOCK(), this facilitates -// allocating the scoped variables in their blocks, and the rest at -// the outermost scope of the function. +// Walk the GCC BLOCK() tree. Set BLOCK_NUMBER() to the depth of each +// block; this is necessary for lexical block debug info. Visit all +// the BLOCK_VARS(), and add them to the set s. Since the +// unexpanded_var_list seems to be a superset of all the scoped +// variables in every lexical BLOCK(), this facilitates allocating the +// scoped variables in their blocks, and the rest at the outermost +// scope of the function. void TreeToLLVM::setLexicalBlockDepths(tree t, treeset &s, unsigned level) { tree bstep, step; switch (TREE_CODE(t)) { @@ -616,7 +616,7 @@ SeenBlocks.clear(); if (EmitDebugInfo()) - TheDebugInfo->EmitFunctionStart(FnDecl); + TheDebugInfo->EmitFunctionStart(FnDecl, Fn, Builder.GetInsertBlock()); // Loop over all of the arguments to the function, setting Argument names and // creating argument alloca's for the PARM_DECLs in case their address is @@ -631,7 +631,7 @@ ABIConverter.HandleReturnType(TREE_TYPE(TREE_TYPE(FnDecl)), FnDecl, DECL_BUILT_IN(FnDecl)); // Remember this for use by FinishFunctionBody. - ReturnOffset = Client.Offset; + TheTreeToLLVM->ReturnOffset = Client.Offset; // Prepend the static chain (if any) to the list of arguments. tree Args = static_chain ? static_chain : DECL_ARGUMENTS(FnDecl); Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp?rev=104954&r1=104953&r2=104954&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Fri May 28 11:42:52 2010 @@ -263,8 +263,6 @@ "expected 'desired' to be a GCC BLOCK or FUNCTION_DECL"); assert ((TREE_CODE(grand) == BLOCK || TREE_CODE(grand) == FUNCTION_DECL) && "expected 'grand' to be a GCC BLOCK or FUNCTION_DECL"); - // Call myself to recursively walk back to the grandparent BLOCK; - // I'll push the RegionStack[] at every level on the way back here: if (grand != desired) push_regions(BLOCK_SUPERCONTEXT(desired), grand); // FIXME: push_regions is currently never called with desired == @@ -279,40 +277,39 @@ // regions to arrive at 'desired'. This was inspired (cribbed from) // by GCC's cfglayout.c:change_scope(). void DebugInfo::change_regions(tree desired, tree grand) { - tree current_lexical_block; + tree current_lexical_block = getCurrentLexicalBlock(); // FIXME: change_regions is currently never called with desired == // grand, but it should be fixed so nothing weird happens if they're // equal. - for( current_lexical_block = getCurrentLexicalBlock(); - current_lexical_block != grand; - current_lexical_block = BLOCK_SUPERCONTEXT(current_lexical_block)) { + while (current_lexical_block != grand) { assert(BLOCK_SUPERCONTEXT(getCurrentLexicalBlock()) && "lost BLOCK context!"); + current_lexical_block = BLOCK_SUPERCONTEXT(current_lexical_block); RegionStack.pop_back(); } DebugInfo::push_regions(desired, grand); - setCurrentLexicalBlock(current_lexical_block); + setCurrentLexicalBlock(desired); } -/// CreateSubprogramFromFnDecl - Constructs the debug code for -/// entering a function - "llvm.dbg.func.start." -DISubprogram DebugInfo::CreateSubprogramFromFnDecl(tree FnDecl) { - DISubprogram SPDecl; - bool SPDeclIsSet = false; - // True if we're currently generating LLVM for this function. - bool definition = llvm_set_decl_p(FnDecl); +/// EmitFunctionStart - Constructs the debug code for entering a function. +void DebugInfo::EmitFunctionStart(tree FnDecl, Function *Fn, + BasicBlock *CurBB) { + setCurrentLexicalBlock(FnDecl); + DIType FNType = getOrCreateType(TREE_TYPE(FnDecl)); std::map::iterator I = SPCache.find(FnDecl); if (I != SPCache.end()) { - SPDecl = DISubprogram(cast(I->second)); - SPDeclIsSet = true; - // If we've already created the defining instance, OR this - // invocation won't create the defining instance, return what we - // already have. - if (SPDecl.isDefinition() || !definition) - return SPDecl; - } + DISubprogram SPDecl(cast(I->second)); + DISubprogram SP = + DebugFactory.CreateSubprogramDefinition(SPDecl); + SPDecl->replaceAllUsesWith(SP); + + // Push function on region stack. + RegionStack.push_back(WeakVH(SP)); + RegionMap[FnDecl] = WeakVH(SP); + return; + } bool ArtificialFnWithAbstractOrigin = false; // If this artificial function has abstract origin then put this function @@ -326,19 +323,11 @@ getOrCreateFile(main_input_filename) : findRegion (DECL_CONTEXT(FnDecl)); - // The region/scope returned above can be arbitrarily deep. - // Sometimes GCC reports the true nested scoping of a function, but - // GCC usually places functions at module scope, ignoring their real - // context. Here we arbitrarily declare "__foo_block_invoke_3" - // functions at module scope for GDB sanity. - if (BLOCK_SYNTHESIZED_FUNC(FnDecl)) - SPContext = findRegion(NULL_TREE); - // Creating context may have triggered creation of this SP descriptor. So // check the cache again. I = SPCache.find(FnDecl); - if (!SPDeclIsSet && I != SPCache.end()) { - SPDecl = DISubprogram(cast(I->second)); + if (I != SPCache.end()) { + DISubprogram SPDecl(cast(I->second)); DISubprogram SP = DebugFactory.CreateSubprogramDefinition(SPDecl); SPDecl->replaceAllUsesWith(SP); @@ -346,14 +335,14 @@ // Push function on region stack. RegionStack.push_back(WeakVH(SP)); RegionMap[FnDecl] = WeakVH(SP); - return SP; + return; } // Gather location information. expanded_location Loc = GetNodeLocation(FnDecl, false); StringRef LinkageName = getLinkageName(FnDecl); - unsigned lineno = LOCATION_LINE(Loc); + unsigned lineno = CurLineNo; if (isCopyOrDestroyHelper(FnDecl)) lineno = 0; @@ -368,37 +357,23 @@ } StringRef FnName = getFunctionName(FnDecl); - // If the Function * hasn't been created yet, use a bogus value for - // the debug internal linkage bit. - bool hasInternalLinkage = true; - if (GET_DECL_LLVM_INDEX(FnDecl)) { - Function *Fn = castDECL_LLVM(FnDecl); - hasInternalLinkage = Fn->hasInternalLinkage(); - } + DISubprogram SP = DebugFactory.CreateSubprogram(SPContext, FnName, FnName, LinkageName, getOrCreateFile(Loc.file), lineno, FNType, - hasInternalLinkage, - definition, + Fn->hasInternalLinkage(), + true /*definition*/, Virtuality, VIndex, ContainingType, DECL_ARTIFICIAL (FnDecl), optimize); SPCache[FnDecl] = WeakVH(SP); - RegionMap[FnDecl] = WeakVH(SP); - if (SPDeclIsSet && SPDecl != SP) - SPDecl->replaceAllUsesWith(SP); - return SP; -} -/// EmitFunctionStart - Constructs the debug code for entering a function. -void DebugInfo::EmitFunctionStart(tree FnDecl) { - setCurrentLexicalBlock(FnDecl); - DISubprogram SP = CreateSubprogramFromFnDecl(FnDecl); // Push function on region stack. RegionStack.push_back(WeakVH(SP)); + RegionMap[FnDecl] = WeakVH(SP); } /// getOrCreateNameSpace - Get name space descriptor for the tree node. @@ -431,61 +406,20 @@ DIType Ty = getOrCreateType(Node); return DIDescriptor(Ty); } else if (DECL_P (Node)) { - switch (TREE_CODE(Node)) { - default: - /// What kind of DECL is this? - return findRegion (DECL_CONTEXT (Node)); - case NAMESPACE_DECL: { + if (TREE_CODE (Node) == NAMESPACE_DECL) { DIDescriptor NSContext = findRegion(DECL_CONTEXT(Node)); DINameSpace NS = getOrCreateNameSpace(Node, NSContext); return DIDescriptor(NS); } - case FUNCTION_DECL: { - DISubprogram SP = CreateSubprogramFromFnDecl(Node); - return SP; - } - } + return findRegion (DECL_CONTEXT (Node)); } else if (TREE_CODE(Node) == BLOCK) { // TREE_BLOCK is GCC's lexical block. - tree nonempty_block, nonempty_supercontext=NULL_TREE; - // Find the nearest non-empty (has variables) BLOCK. This is what - // we'll declare, assumming we don't omit it entirely. - for (nonempty_block = Node; - TREE_CODE(nonempty_block) == BLOCK && !BLOCK_VARS(nonempty_block); - nonempty_block = BLOCK_SUPERCONTEXT(nonempty_block)) - ; - // Find a parent BLOCK that declares variables, and isn't the - // FUNCTION_DECL. If such a parent BLOCK exists, we'll omit it - // and declare its variables at the function scope. - if (TREE_CODE(nonempty_block) == BLOCK) - for (nonempty_supercontext = BLOCK_SUPERCONTEXT(nonempty_block); - TREE_CODE(nonempty_supercontext) == BLOCK && - !BLOCK_VARS(nonempty_supercontext); - nonempty_supercontext = BLOCK_SUPERCONTEXT(nonempty_supercontext)) - ; - // If the nearest non-empty context is the FUNCTION_DECL, that's - // our region; declare it. Otherwise, carefully avoid declaring - // the outermost lexical block. If this block hangs directly - // underneath the FUNCTION_DECL and has no siblings, we skip it; - // return the FUNCTION_DECL scope instead. Child BLOCKS will be - // emitted normally. While technically incorrect, this is what - // GCC does and GDB expects. - if (nonempty_supercontext) { - // O.K., this nonempty_block isn't the topmost BLOCK; declare it. - DIDescriptor context = findRegion(BLOCK_SUPERCONTEXT(nonempty_block)); - DILexicalBlock lexical_block = - DebugFactory.CreateLexicalBlock(context, CurLineNo); - RegionMap[Node] = WeakVH(lexical_block); - return DIDescriptor(lexical_block); - } - tree function_decl; - // Find the enclosing FUNCTION_DECL. - for (function_decl = nonempty_block; - TREE_CODE(function_decl) == BLOCK; - function_decl = BLOCK_SUPERCONTEXT(function_decl)) - ; - DISubprogram SP = CreateSubprogramFromFnDecl(function_decl); - return SP; + // Recursively create all necessary contexts: + DIDescriptor context = findRegion(BLOCK_SUPERCONTEXT(Node)); + DILexicalBlock lexical_block = + DebugFactory.CreateLexicalBlock(context, CurLineNo); + RegionMap[Node] = WeakVH(lexical_block); + return DIDescriptor(lexical_block); } // Otherwise main compile unit covers everything. @@ -717,7 +651,7 @@ sprintf(FwdTypeName, "fwd.type.%d", FwdTypeCount++); llvm::DIType FwdType = DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_subroutine_type, - findRegion(TYPE_CONTEXT(type)), + getOrCreateFile(main_input_filename), FwdTypeName, getOrCreateFile(main_input_filename), 0, 0, 0, 0, 0, @@ -804,7 +738,7 @@ StringRef PName = FromTy.getName(); DIType PTy = - DebugFactory.CreateDerivedType(Tag, findRegion(TYPE_CONTEXT(type)), + DebugFactory.CreateDerivedType(Tag, findRegion(TYPE_CONTEXT(type)), Tag == DW_TAG_pointer_type ? StringRef() : PName, getOrCreateFile(main_input_filename), Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.h?rev=104954&r1=104953&r2=104954&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-debug.h (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-debug.h Fri May 28 11:42:52 2010 @@ -118,13 +118,9 @@ // by GCC's cfglayout.c:change_scope(). void change_regions(tree_node *desired, tree_node *grand); - /// CreateSubprogramFromFnDecl - Constructs the debug code for entering a function - - /// "llvm.dbg.func.start." - DISubprogram CreateSubprogramFromFnDecl(tree_node *FnDecl); - /// EmitFunctionStart - Constructs the debug code for entering a function - - /// "llvm.dbg.func.start", and pushes it onto the RegionStack. - void EmitFunctionStart(tree_node *FnDecl); + /// "llvm.dbg.func.start." + void EmitFunctionStart(tree_node *FnDecl, Function *Fn, BasicBlock *CurBB); /// EmitFunctionEnd - Constructs the debug code for exiting a declarative /// region - "llvm.dbg.region.end." Modified: llvm-gcc-4.2/trunk/gcc/llvm-internal.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-internal.h?rev=104954&r1=104953&r2=104954&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Fri May 28 11:42:52 2010 @@ -75,7 +75,7 @@ extern llvm::Module *TheModule; /// TheDebugInfo - This object is responsible for gather all debug information. -/// If its value is NULL then no debug information should be gathered. +/// If it's value is NULL then no debug information should be gathered. extern llvm::DebugInfo *TheDebugInfo; /// TheTarget - The current target being compiled for. @@ -281,7 +281,6 @@ BasicBlock *ReturnBB; BasicBlock *UnwindBB; unsigned ReturnOffset; - // Lexical BLOCKS that we have previously seen and processed. treeset SeenBlocks; @@ -398,10 +397,6 @@ // allocation would change with -g, and users dislike that. void switchLexicalBlock(tree_node *exp); - /// StartFunctionBody - Start the emission of 'FnDecl', outputing all - /// declarations for parameters and setting things up. - void StartFunctionBody(); - private: // Helper functions. // Walk over the lexical BLOCK() tree of the given FUNCTION_DECL; @@ -410,6 +405,10 @@ // the given set. void setLexicalBlockDepths(tree_node *t, treeset &s, unsigned level); + /// StartFunctionBody - Start the emission of 'fndecl', outputing all + /// declarations for parameters and setting things up. + void StartFunctionBody(); + /// FinishFunctionBody - Once the body of the function has been emitted, this /// cleans up and returns the result function. Function *FinishFunctionBody(); @@ -609,9 +608,6 @@ Constant *EmitLV_LABEL_DECL(tree_node *exp); }; -/// TheTreeToLLVM - Keep track of the current function being compiled. -extern TreeToLLVM *TheTreeToLLVM; - /// TreeConstantToLLVM - An instance of this class is created and used to /// convert tree constant values to LLVM. This is primarily for things like /// global variable initializers. From gohman at apple.com Fri May 28 11:44:04 2010 From: gohman at apple.com (Dan Gohman) Date: Fri, 28 May 2010 16:44:04 -0000 Subject: [llvm-commits] [llvm] r104956 - /llvm/trunk/test/Other/lint.ll Message-ID: <20100528164404.4F149312800A@llvm.org> Author: djg Date: Fri May 28 11:44:04 2010 New Revision: 104956 URL: http://llvm.org/viewvc/llvm-project?rev=104956&view=rev Log: Remove this va_arg test, which is no longer applicable. Modified: llvm/trunk/test/Other/lint.ll Modified: llvm/trunk/test/Other/lint.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/lint.ll?rev=104956&r1=104955&r2=104956&view=diff ============================================================================== --- llvm/trunk/test/Other/lint.ll (original) +++ llvm/trunk/test/Other/lint.ll Fri May 28 11:44:04 2010 @@ -88,13 +88,10 @@ } ; CHECK: Undefined behavior: Call with "tail" keyword references alloca -; CHECK: Undefined behavior: Call with "tail" keyword references alloca declare void @tailcallee(i8*) define void @use_tail(i8* %valist) { %t = alloca i8 tail call void @tailcallee(i8* %t) - %s = va_arg i8* %valist, i8* - tail call void @tailcallee(i8* %s) ret void } From gohman at apple.com Fri May 28 11:45:33 2010 From: gohman at apple.com (Dan Gohman) Date: Fri, 28 May 2010 16:45:33 -0000 Subject: [llvm-commits] [llvm] r104957 - in /llvm/trunk: lib/Analysis/Lint.cpp test/Other/lint.ll Message-ID: <20100528164533.8DA08312800A@llvm.org> Author: djg Date: Fri May 28 11:45:33 2010 New Revision: 104957 URL: http://llvm.org/viewvc/llvm-project?rev=104957&view=rev Log: Detect self-referential values. Modified: llvm/trunk/lib/Analysis/Lint.cpp llvm/trunk/test/Other/lint.ll Modified: llvm/trunk/lib/Analysis/Lint.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/Lint.cpp?rev=104957&r1=104956&r2=104957&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/Lint.cpp (original) +++ llvm/trunk/lib/Analysis/Lint.cpp Fri May 28 11:45:33 2010 @@ -93,6 +93,8 @@ void visitUnreachableInst(UnreachableInst &I); Value *findValue(Value *V, bool OffsetOk) const; + Value *findValueImpl(Value *V, bool OffsetOk, + SmallPtrSet &Visited) const; public: Module *Mod; @@ -498,6 +500,17 @@ /// will simplify most of these kinds of things away. But it's a goal of /// this Lint pass to be useful even on non-optimized IR. Value *Lint::findValue(Value *V, bool OffsetOk) const { + SmallPtrSet Visited; + return findValueImpl(V, OffsetOk, Visited); +} + +/// findValueImpl - Implementation helper for findValue. +Value *Lint::findValueImpl(Value *V, bool OffsetOk, + SmallPtrSet &Visited) const { + // Detect self-referential values. + if (!Visited.insert(V)) + return UndefValue::get(V->getType()); + // TODO: Look through sext or zext cast, when the result is known to // be interpreted as signed or unsigned, respectively. // TODO: Look through calls with unique return values. @@ -509,7 +522,7 @@ for (;;) { if (Value *U = FindAvailableLoadedValue(L->getPointerOperand(), BB, BBI, 6, AA)) - return findValue(U, OffsetOk); + return findValueImpl(U, OffsetOk, Visited); BB = L->getParent()->getUniquePredecessor(); if (!BB) break; BBI = BB->end(); @@ -517,27 +530,27 @@ } else if (CastInst *CI = dyn_cast(V)) { if (CI->isNoopCast(TD ? TD->getIntPtrType(V->getContext()) : Type::getInt64Ty(V->getContext()))) - return findValue(CI->getOperand(0), OffsetOk); + return findValueImpl(CI->getOperand(0), OffsetOk, Visited); } else if (PHINode *PN = dyn_cast(V)) { if (Value *W = PN->hasConstantValue(DT)) - return findValue(W, OffsetOk); + return findValueImpl(W, OffsetOk, Visited); } else if (ExtractValueInst *Ex = dyn_cast(V)) { if (Value *W = FindInsertedValue(Ex->getAggregateOperand(), Ex->idx_begin(), Ex->idx_end())) if (W != V) - return findValue(W, OffsetOk); + return findValueImpl(W, OffsetOk, Visited); } // As a last resort, try SimplifyInstruction or constant folding. if (Instruction *Inst = dyn_cast(V)) { if (Value *W = SimplifyInstruction(Inst, TD)) if (W != Inst) - return findValue(W, OffsetOk); + return findValueImpl(W, OffsetOk, Visited); } else if (ConstantExpr *CE = dyn_cast(V)) { if (Value *W = ConstantFoldConstantExpression(CE, TD)) if (W != V) - return findValue(W, OffsetOk); + return findValueImpl(W, OffsetOk, Visited); } return V; Modified: llvm/trunk/test/Other/lint.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/lint.ll?rev=104957&r1=104956&r2=104957&view=diff ============================================================================== --- llvm/trunk/test/Other/lint.ll (original) +++ llvm/trunk/test/Other/lint.ll Fri May 28 11:45:33 2010 @@ -122,3 +122,14 @@ %t7 = inttoptr i64 %t6 to i32* ret i32* %t7 } + +; CHECK: Undefined behavior: Undef pointer dereference +define i32* @self_reference() { +entry: + unreachable +exit: + %t3 = phi i32* [ %t4, %exit ] + %t4 = bitcast i32* %t3 to i32* + %x = volatile load i32* %t3 + br label %exit +} From tobias at platen-software.de Fri May 28 07:23:59 2010 From: tobias at platen-software.de (Tobias Platen) Date: Fri, 28 May 2010 14:23:59 +0200 Subject: [llvm-commits] patch for cocotron support in clang Message-ID: Hello, I wrote a patch for clang to support the Cocotron Objective C runtime. The Cocotron Runtime is similar to the GNU runtime but does not support typed selectors. Tobias -------------- next part -------------- A non-text attachment was scrubbed... Name: clang-cocotron-support.patch Type: application/octet-stream Size: 6595 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100528/6c932332/attachment.obj -------------- next part -------------- From gohman at apple.com Fri May 28 11:50:01 2010 From: gohman at apple.com (Dan Gohman) Date: Fri, 28 May 2010 16:50:01 -0000 Subject: [llvm-commits] [llvm] r104958 - /llvm/trunk/lib/Support/raw_ostream.cpp Message-ID: <20100528165001.4E9A5312800A@llvm.org> Author: djg Date: Fri May 28 11:50:01 2010 New Revision: 104958 URL: http://llvm.org/viewvc/llvm-project?rev=104958&view=rev Log: Fix a redundant-return warning. Modified: llvm/trunk/lib/Support/raw_ostream.cpp Modified: llvm/trunk/lib/Support/raw_ostream.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/raw_ostream.cpp?rev=104958&r1=104957&r2=104958&view=diff ============================================================================== --- llvm/trunk/lib/Support/raw_ostream.cpp (original) +++ llvm/trunk/lib/Support/raw_ostream.cpp Fri May 28 11:50:01 2010 @@ -496,8 +496,9 @@ return 0; // Return the preferred block size. return statbuf.st_blksize; -#endif +#else return raw_ostream::preferred_buffer_size(); +#endif } raw_ostream &raw_fd_ostream::changeColor(enum Colors colors, bool bold, From gohman at apple.com Fri May 28 11:50:24 2010 From: gohman at apple.com (Dan Gohman) Date: Fri, 28 May 2010 16:50:24 -0000 Subject: [llvm-commits] [llvm] r104959 - /llvm/trunk/lib/Support/raw_ostream.cpp Message-ID: <20100528165024.13356312800A@llvm.org> Author: djg Date: Fri May 28 11:50:23 2010 New Revision: 104959 URL: http://llvm.org/viewvc/llvm-project?rev=104959&view=rev Log: Minor code simplification. Modified: llvm/trunk/lib/Support/raw_ostream.cpp Modified: llvm/trunk/lib/Support/raw_ostream.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/raw_ostream.cpp?rev=104959&r1=104958&r2=104959&view=diff ============================================================================== --- llvm/trunk/lib/Support/raw_ostream.cpp (original) +++ llvm/trunk/lib/Support/raw_ostream.cpp Fri May 28 11:50:23 2010 @@ -427,10 +427,9 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) { assert(FD >= 0 && "File already closed."); pos += Size; - ssize_t ret; do { - ret = ::write(FD, Ptr, Size); + ssize_t ret = ::write(FD, Ptr, Size); if (ret < 0) { // If it's a recoverable error, swallow it and retry the write. From stoklund at 2pi.dk Fri May 28 12:06:30 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Fri, 28 May 2010 17:06:30 -0000 Subject: [llvm-commits] [llvm] r104961 - in /llvm/trunk/test/CodeGen/X86: object-size.ll volatile.ll Message-ID: <20100528170630.9B0D1312800A@llvm.org> Author: stoklund Date: Fri May 28 12:06:30 2010 New Revision: 104961 URL: http://llvm.org/viewvc/llvm-project?rev=104961&view=rev Log: Fix more tests that depended on the default register allocator choice. Modified: llvm/trunk/test/CodeGen/X86/object-size.ll llvm/trunk/test/CodeGen/X86/volatile.ll Modified: llvm/trunk/test/CodeGen/X86/object-size.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/object-size.ll?rev=104961&r1=104960&r2=104961&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/object-size.ll (original) +++ llvm/trunk/test/CodeGen/X86/object-size.ll Fri May 28 12:06:30 2010 @@ -1,4 +1,4 @@ -; RUN: llc -O0 < %s -march=x86-64 | FileCheck %s -check-prefix=X64 +; RUN: llc -O0 -regalloc=linearscan < %s -march=x86-64 | FileCheck %s -check-prefix=X64 ; ModuleID = 'ts.c' target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" Modified: llvm/trunk/test/CodeGen/X86/volatile.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/volatile.ll?rev=104961&r1=104960&r2=104961&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/volatile.ll (original) +++ llvm/trunk/test/CodeGen/X86/volatile.ll Fri May 28 12:06:30 2010 @@ -1,5 +1,5 @@ ; RUN: llc < %s -march=x86 -mattr=sse2 | grep movsd | count 5 -; RUN: llc < %s -march=x86 -mattr=sse2 -O0 | grep movsd | count 5 +; RUN: llc < %s -march=x86 -mattr=sse2 -O0 | grep -v esp | grep movsd | count 5 @x = external global double From gohman at apple.com Fri May 28 12:07:41 2010 From: gohman at apple.com (Dan Gohman) Date: Fri, 28 May 2010 17:07:41 -0000 Subject: [llvm-commits] [llvm] r104962 - in /llvm/trunk/docs: ExceptionHandling.html FAQ.html LangRef.html SourceLevelDebugging.html tutorial/LangImpl3.html tutorial/LangImpl4.html tutorial/LangImpl5.html tutorial/LangImpl7.html tutorial/OCamlLangImpl3.html tutorial/OCamlLangImpl4.html tutorial/OCamlLangImpl5.html tutorial/OCamlLangImpl7.html Message-ID: <20100528170742.4E479312800A@llvm.org> Author: djg Date: Fri May 28 12:07:41 2010 New Revision: 104962 URL: http://llvm.org/viewvc/llvm-project?rev=104962&view=rev Log: Fix whitespace to be more consistent with AsmPrinter's style. Modified: llvm/trunk/docs/ExceptionHandling.html llvm/trunk/docs/FAQ.html llvm/trunk/docs/LangRef.html llvm/trunk/docs/SourceLevelDebugging.html llvm/trunk/docs/tutorial/LangImpl3.html llvm/trunk/docs/tutorial/LangImpl4.html llvm/trunk/docs/tutorial/LangImpl5.html llvm/trunk/docs/tutorial/LangImpl7.html llvm/trunk/docs/tutorial/OCamlLangImpl3.html llvm/trunk/docs/tutorial/OCamlLangImpl4.html llvm/trunk/docs/tutorial/OCamlLangImpl5.html llvm/trunk/docs/tutorial/OCamlLangImpl7.html Modified: llvm/trunk/docs/ExceptionHandling.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/ExceptionHandling.html?rev=104962&r1=104961&r2=104962&view=diff ============================================================================== --- llvm/trunk/docs/ExceptionHandling.html (original) +++ llvm/trunk/docs/ExceptionHandling.html Fri May 28 12:07:41 2010 @@ -404,7 +404,7 @@
    -  i8* %llvm.eh.exception( )
    +  i8* %llvm.eh.exception()
     

    This intrinsic returns a pointer to the exception structure.

    @@ -518,7 +518,7 @@
    -  i8* %llvm.eh.sjlj.lsda( )
    +  i8* %llvm.eh.sjlj.lsda()
     

    Used for SJLJ based exception handling, the Modified: llvm/trunk/docs/FAQ.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/FAQ.html?rev=104962&r1=104961&r2=104962&view=diff ============================================================================== --- llvm/trunk/docs/FAQ.html (original) +++ llvm/trunk/docs/FAQ.html Fri May 28 12:07:41 2010 @@ -803,7 +803,7 @@ ret void } define void @bar() { - call void @foo( ) + call void @foo() ret void } Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=104962&r1=104961&r2=104962&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Fri May 28 12:07:41 2010 @@ -2475,104 +2475,104 @@ supported). The following is the syntax for constant expressions:

    -
    trunc ( CST to TYPE )
    +
    trunc (CST to TYPE)
    Truncate a constant to another type. The bit size of CST must be larger than the bit size of TYPE. Both types must be integers.
    -
    zext ( CST to TYPE )
    +
    zext (CST to TYPE)
    Zero extend a constant to another type. The bit size of CST must be smaller or equal to the bit size of TYPE. Both types must be integers.
    -
    sext ( CST to TYPE )
    +
    sext (CST to TYPE)
    Sign extend a constant to another type. The bit size of CST must be smaller or equal to the bit size of TYPE. Both types must be integers.
    -
    fptrunc ( CST to TYPE )
    +
    fptrunc (CST to TYPE)
    Truncate a floating point constant to another floating point type. The size of CST must be larger than the size of TYPE. Both types must be floating point.
    -
    fpext ( CST to TYPE )
    +
    fpext (CST to TYPE)
    Floating point extend a constant to another type. The size of CST must be smaller or equal to the size of TYPE. Both types must be floating point.
    -
    fptoui ( CST to TYPE )
    +
    fptoui (CST to TYPE)
    Convert a floating point constant to the corresponding unsigned integer constant. TYPE must be a scalar or vector integer type. CST must be of scalar or vector floating point type. Both CST and TYPE must be scalars, or vectors of the same number of elements. If the value won't fit in the integer type, the results are undefined.
    -
    fptosi ( CST to TYPE )
    +
    fptosi (CST to TYPE)
    Convert a floating point constant to the corresponding signed integer constant. TYPE must be a scalar or vector integer type. CST must be of scalar or vector floating point type. Both CST and TYPE must be scalars, or vectors of the same number of elements. If the value won't fit in the integer type, the results are undefined.
    -
    uitofp ( CST to TYPE )
    +
    uitofp (CST to TYPE)
    Convert an unsigned integer constant to the corresponding floating point constant. TYPE must be a scalar or vector floating point type. CST must be of scalar or vector integer type. Both CST and TYPE must be scalars, or vectors of the same number of elements. If the value won't fit in the floating point type, the results are undefined.
    -
    sitofp ( CST to TYPE )
    +
    sitofp (CST to TYPE)
    Convert a signed integer constant to the corresponding floating point constant. TYPE must be a scalar or vector floating point type. CST must be of scalar or vector integer type. Both CST and TYPE must be scalars, or vectors of the same number of elements. If the value won't fit in the floating point type, the results are undefined.
    -
    ptrtoint ( CST to TYPE )
    +
    ptrtoint (CST to TYPE)
    Convert a pointer typed constant to the corresponding integer constant TYPE must be an integer type. CST must be of pointer type. The CST value is zero extended, truncated, or unchanged to make it fit in TYPE.
    -
    inttoptr ( CST to TYPE )
    +
    inttoptr (CST to TYPE)
    Convert a integer constant to a pointer constant. TYPE must be a pointer type. CST must be of integer type. The CST value is zero extended, truncated, or unchanged to make it fit in a pointer size. This one is really dangerous!
    -
    bitcast ( CST to TYPE )
    +
    bitcast (CST to TYPE)
    Convert a constant, CST, to another TYPE. The constraints of the operands are the same as those for the bitcast instruction.
    -
    getelementptr ( CSTPTR, IDX0, IDX1, ... )
    -
    getelementptr inbounds ( CSTPTR, IDX0, IDX1, ... )
    +
    getelementptr (CSTPTR, IDX0, IDX1, ...)
    +
    getelementptr inbounds (CSTPTR, IDX0, IDX1, ...)
    Perform the getelementptr operation on constants. As with the getelementptr instruction, the index list may have zero or more indexes, which are required to make sense for the type of "CSTPTR".
    -
    select ( COND, VAL1, VAL2 )
    +
    select (COND, VAL1, VAL2)
    Perform the select operation on constants.
    -
    icmp COND ( VAL1, VAL2 )
    +
    icmp COND (VAL1, VAL2)
    Performs the icmp operation on constants.
    -
    fcmp COND ( VAL1, VAL2 )
    +
    fcmp COND (VAL1, VAL2)
    Performs the fcmp operation on constants.
    -
    extractelement ( VAL, IDX )
    +
    extractelement (VAL, IDX)
    Perform the extractelement operation on constants.
    -
    insertelement ( VAL, ELT, IDX )
    +
    insertelement (VAL, ELT, IDX)
    Perform the insertelement operation on constants.
    -
    shufflevector ( VEC1, VEC2, IDXMASK )
    +
    shufflevector (VEC1, VEC2, IDXMASK)
    Perform the shufflevector operation on constants.
    -
    OPCODE ( LHS, RHS )
    +
    OPCODE (LHS, RHS)
    Perform the specified operation of the LHS and RHS constants. OPCODE may be any of the binary or bitwise binary operations. The constraints @@ -5992,7 +5992,7 @@
    Syntax:
    -  declare i64 @llvm.readcyclecounter( )
    +  declare i64 @llvm.readcyclecounter()
     
    Overview:
    @@ -6938,13 +6938,13 @@
       %tramp = alloca [10 x i8], align 4 ; size and alignment only correct for X86
       %tramp1 = getelementptr [10 x i8]* %tramp, i32 0, i32 0
    -  %p = call i8* @llvm.init.trampoline( i8* %tramp1, i8* bitcast (i32 (i8* nest , i32, i32)* @f to i8*), i8* %nval )
    +  %p = call i8* @llvm.init.trampoline(i8* %tramp1, i8* bitcast (i32 (i8* nest , i32, i32)* @f to i8*), i8* %nval)
       %fp = bitcast i8* %p to i32 (i32, i32)*
     
    -

    The call %val = call i32 %fp( i32 %x, i32 %y ) is then equivalent - to %val = call i32 %f( i8* %nval, i32 %x, i32 %y ).

    +

    The call %val = call i32 %fp(i32 %x, i32 %y) is then equivalent + to %val = call i32 %f(i8* %nval, i32 %x, i32 %y).

    @@ -7024,7 +7024,7 @@
    Syntax:
    -  declare void @llvm.memory.barrier( i1 <ll>, i1 <ls>, i1 <sl>, i1 <ss>, i1 <device> )
    +  declare void @llvm.memory.barrier(i1 <ll>, i1 <ls>, i1 <sl>, i1 <ss>, i1 <device>)
     
    Overview:
    @@ -7081,7 +7081,7 @@ store i32 4, %ptr %result1 = load i32* %ptr ; yields {i32}:result1 = 4 - call void @llvm.memory.barrier( i1 false, i1 true, i1 false, i1 false ) + call void @llvm.memory.barrier(i1 false, i1 true, i1 false, i1 false) ; guarantee the above finishes store i32 8, %ptr ; before this begins @@ -7101,10 +7101,10 @@ support all bit widths however.

    -  declare i8 @llvm.atomic.cmp.swap.i8.p0i8( i8* <ptr>, i8 <cmp>, i8 <val> )
    -  declare i16 @llvm.atomic.cmp.swap.i16.p0i16( i16* <ptr>, i16 <cmp>, i16 <val> )
    -  declare i32 @llvm.atomic.cmp.swap.i32.p0i32( i32* <ptr>, i32 <cmp>, i32 <val> )
    -  declare i64 @llvm.atomic.cmp.swap.i64.p0i64( i64* <ptr>, i64 <cmp>, i64 <val> )
    +  declare i8 @llvm.atomic.cmp.swap.i8.p0i8(i8* <ptr>, i8 <cmp>, i8 <val>)
    +  declare i16 @llvm.atomic.cmp.swap.i16.p0i16(i16* <ptr>, i16 <cmp>, i16 <val>)
    +  declare i32 @llvm.atomic.cmp.swap.i32.p0i32(i32* <ptr>, i32 <cmp>, i32 <val>)
    +  declare i64 @llvm.atomic.cmp.swap.i64.p0i64(i64* <ptr>, i64 <cmp>, i64 <val>)
     
    Overview:
    @@ -7133,13 +7133,13 @@ store i32 4, %ptr %val1 = add i32 4, 4 -%result1 = call i32 @llvm.atomic.cmp.swap.i32.p0i32( i32* %ptr, i32 4, %val1 ) +%result1 = call i32 @llvm.atomic.cmp.swap.i32.p0i32(i32* %ptr, i32 4, %val1) ; yields {i32}:result1 = 4 %stored1 = icmp eq i32 %result1, 4 ; yields {i1}:stored1 = true %memval1 = load i32* %ptr ; yields {i32}:memval1 = 8 %val2 = add i32 1, 1 -%result2 = call i32 @llvm.atomic.cmp.swap.i32.p0i32( i32* %ptr, i32 5, %val2 ) +%result2 = call i32 @llvm.atomic.cmp.swap.i32.p0i32(i32* %ptr, i32 5, %val2) ; yields {i32}:result2 = 8 %stored2 = icmp eq i32 %result2, 5 ; yields {i1}:stored2 = false @@ -7159,10 +7159,10 @@ integer bit width. Not all targets support all bit widths however.

    -  declare i8 @llvm.atomic.swap.i8.p0i8( i8* <ptr>, i8 <val> )
    -  declare i16 @llvm.atomic.swap.i16.p0i16( i16* <ptr>, i16 <val> )
    -  declare i32 @llvm.atomic.swap.i32.p0i32( i32* <ptr>, i32 <val> )
    -  declare i64 @llvm.atomic.swap.i64.p0i64( i64* <ptr>, i64 <val> )
    +  declare i8 @llvm.atomic.swap.i8.p0i8(i8* <ptr>, i8 <val>)
    +  declare i16 @llvm.atomic.swap.i16.p0i16(i16* <ptr>, i16 <val>)
    +  declare i32 @llvm.atomic.swap.i32.p0i32(i32* <ptr>, i32 <val>)
    +  declare i64 @llvm.atomic.swap.i64.p0i64(i64* <ptr>, i64 <val>)
     
    Overview:
    @@ -7189,13 +7189,13 @@ store i32 4, %ptr %val1 = add i32 4, 4 -%result1 = call i32 @llvm.atomic.swap.i32.p0i32( i32* %ptr, i32 %val1 ) +%result1 = call i32 @llvm.atomic.swap.i32.p0i32(i32* %ptr, i32 %val1) ; yields {i32}:result1 = 4 %stored1 = icmp eq i32 %result1, 4 ; yields {i1}:stored1 = true %memval1 = load i32* %ptr ; yields {i32}:memval1 = 8 %val2 = add i32 1, 1 -%result2 = call i32 @llvm.atomic.swap.i32.p0i32( i32* %ptr, i32 %val2 ) +%result2 = call i32 @llvm.atomic.swap.i32.p0i32(i32* %ptr, i32 %val2) ; yields {i32}:result2 = 8 %stored2 = icmp eq i32 %result2, 8 ; yields {i1}:stored2 = true @@ -7217,10 +7217,10 @@ any integer bit width. Not all targets support all bit widths however.

    -  declare i8 @llvm.atomic.load.add.i8.p0i8( i8* <ptr>, i8 <delta> )
    -  declare i16 @llvm.atomic.load.add.i16.p0i16( i16* <ptr>, i16 <delta> )
    -  declare i32 @llvm.atomic.load.add.i32.p0i32( i32* <ptr>, i32 <delta> )
    -  declare i64 @llvm.atomic.load.add.i64.p0i64( i64* <ptr>, i64 <delta> )
    +  declare i8 @llvm.atomic.load.add.i8.p0i8(i8* <ptr>, i8 <delta>)
    +  declare i16 @llvm.atomic.load.add.i16.p0i16(i16* <ptr>, i16 <delta>)
    +  declare i32 @llvm.atomic.load.add.i32.p0i32(i32* <ptr>, i32 <delta>)
    +  declare i64 @llvm.atomic.load.add.i64.p0i64(i64* <ptr>, i64 <delta>)
     
    Overview:
    @@ -7243,11 +7243,11 @@ %mallocP = tail call i8* @malloc(i32 ptrtoint (i32* getelementptr (i32* null, i32 1) to i32)) %ptr = bitcast i8* %mallocP to i32* store i32 4, %ptr -%result1 = call i32 @llvm.atomic.load.add.i32.p0i32( i32* %ptr, i32 4 ) +%result1 = call i32 @llvm.atomic.load.add.i32.p0i32(i32* %ptr, i32 4) ; yields {i32}:result1 = 4 -%result2 = call i32 @llvm.atomic.load.add.i32.p0i32( i32* %ptr, i32 2 ) +%result2 = call i32 @llvm.atomic.load.add.i32.p0i32(i32* %ptr, i32 2) ; yields {i32}:result2 = 8 -%result3 = call i32 @llvm.atomic.load.add.i32.p0i32( i32* %ptr, i32 5 ) +%result3 = call i32 @llvm.atomic.load.add.i32.p0i32(i32* %ptr, i32 5) ; yields {i32}:result3 = 10 %memval1 = load i32* %ptr ; yields {i32}:memval1 = 15 @@ -7268,10 +7268,10 @@ support all bit widths however.

    -  declare i8 @llvm.atomic.load.sub.i8.p0i32( i8* <ptr>, i8 <delta> )
    -  declare i16 @llvm.atomic.load.sub.i16.p0i32( i16* <ptr>, i16 <delta> )
    -  declare i32 @llvm.atomic.load.sub.i32.p0i32( i32* <ptr>, i32 <delta> )
    -  declare i64 @llvm.atomic.load.sub.i64.p0i32( i64* <ptr>, i64 <delta> )
    +  declare i8 @llvm.atomic.load.sub.i8.p0i32(i8* <ptr>, i8 <delta>)
    +  declare i16 @llvm.atomic.load.sub.i16.p0i32(i16* <ptr>, i16 <delta>)
    +  declare i32 @llvm.atomic.load.sub.i32.p0i32(i32* <ptr>, i32 <delta>)
    +  declare i64 @llvm.atomic.load.sub.i64.p0i32(i64* <ptr>, i64 <delta>)
     
    Overview:
    @@ -7295,11 +7295,11 @@ %mallocP = tail call i8* @malloc(i32 ptrtoint (i32* getelementptr (i32* null, i32 1) to i32)) %ptr = bitcast i8* %mallocP to i32* store i32 8, %ptr -%result1 = call i32 @llvm.atomic.load.sub.i32.p0i32( i32* %ptr, i32 4 ) +%result1 = call i32 @llvm.atomic.load.sub.i32.p0i32(i32* %ptr, i32 4) ; yields {i32}:result1 = 8 -%result2 = call i32 @llvm.atomic.load.sub.i32.p0i32( i32* %ptr, i32 2 ) +%result2 = call i32 @llvm.atomic.load.sub.i32.p0i32(i32* %ptr, i32 2) ; yields {i32}:result2 = 4 -%result3 = call i32 @llvm.atomic.load.sub.i32.p0i32( i32* %ptr, i32 5 ) +%result3 = call i32 @llvm.atomic.load.sub.i32.p0i32(i32* %ptr, i32 5) ; yields {i32}:result3 = 2 %memval1 = load i32* %ptr ; yields {i32}:memval1 = -3 @@ -7324,31 +7324,31 @@ widths however.

    -  declare i8 @llvm.atomic.load.and.i8.p0i8( i8* <ptr>, i8 <delta> )
    -  declare i16 @llvm.atomic.load.and.i16.p0i16( i16* <ptr>, i16 <delta> )
    -  declare i32 @llvm.atomic.load.and.i32.p0i32( i32* <ptr>, i32 <delta> )
    -  declare i64 @llvm.atomic.load.and.i64.p0i64( i64* <ptr>, i64 <delta> )
    +  declare i8 @llvm.atomic.load.and.i8.p0i8(i8* <ptr>, i8 <delta>)
    +  declare i16 @llvm.atomic.load.and.i16.p0i16(i16* <ptr>, i16 <delta>)
    +  declare i32 @llvm.atomic.load.and.i32.p0i32(i32* <ptr>, i32 <delta>)
    +  declare i64 @llvm.atomic.load.and.i64.p0i64(i64* <ptr>, i64 <delta>)
     
    -  declare i8 @llvm.atomic.load.or.i8.p0i8( i8* <ptr>, i8 <delta> )
    -  declare i16 @llvm.atomic.load.or.i16.p0i16( i16* <ptr>, i16 <delta> )
    -  declare i32 @llvm.atomic.load.or.i32.p0i32( i32* <ptr>, i32 <delta> )
    -  declare i64 @llvm.atomic.load.or.i64.p0i64( i64* <ptr>, i64 <delta> )
    +  declare i8 @llvm.atomic.load.or.i8.p0i8(i8* <ptr>, i8 <delta>)
    +  declare i16 @llvm.atomic.load.or.i16.p0i16(i16* <ptr>, i16 <delta>)
    +  declare i32 @llvm.atomic.load.or.i32.p0i32(i32* <ptr>, i32 <delta>)
    +  declare i64 @llvm.atomic.load.or.i64.p0i64(i64* <ptr>, i64 <delta>)
     
    -  declare i8 @llvm.atomic.load.nand.i8.p0i32( i8* <ptr>, i8 <delta> )
    -  declare i16 @llvm.atomic.load.nand.i16.p0i32( i16* <ptr>, i16 <delta> )
    -  declare i32 @llvm.atomic.load.nand.i32.p0i32( i32* <ptr>, i32 <delta> )
    -  declare i64 @llvm.atomic.load.nand.i64.p0i32( i64* <ptr>, i64 <delta> )
    +  declare i8 @llvm.atomic.load.nand.i8.p0i32(i8* <ptr>, i8 <delta>)
    +  declare i16 @llvm.atomic.load.nand.i16.p0i32(i16* <ptr>, i16 <delta>)
    +  declare i32 @llvm.atomic.load.nand.i32.p0i32(i32* <ptr>, i32 <delta>)
    +  declare i64 @llvm.atomic.load.nand.i64.p0i32(i64* <ptr>, i64 <delta>)
     
    -  declare i8 @llvm.atomic.load.xor.i8.p0i32( i8* <ptr>, i8 <delta> )
    -  declare i16 @llvm.atomic.load.xor.i16.p0i32( i16* <ptr>, i16 <delta> )
    -  declare i32 @llvm.atomic.load.xor.i32.p0i32( i32* <ptr>, i32 <delta> )
    -  declare i64 @llvm.atomic.load.xor.i64.p0i32( i64* <ptr>, i64 <delta> )
    +  declare i8 @llvm.atomic.load.xor.i8.p0i32(i8* <ptr>, i8 <delta>)
    +  declare i16 @llvm.atomic.load.xor.i16.p0i32(i16* <ptr>, i16 <delta>)
    +  declare i32 @llvm.atomic.load.xor.i32.p0i32(i32* <ptr>, i32 <delta>)
    +  declare i64 @llvm.atomic.load.xor.i64.p0i32(i64* <ptr>, i64 <delta>)
     
    Overview:
    @@ -7373,13 +7373,13 @@ %mallocP = tail call i8* @malloc(i32 ptrtoint (i32* getelementptr (i32* null, i32 1) to i32)) %ptr = bitcast i8* %mallocP to i32* store i32 0x0F0F, %ptr -%result0 = call i32 @llvm.atomic.load.nand.i32.p0i32( i32* %ptr, i32 0xFF ) +%result0 = call i32 @llvm.atomic.load.nand.i32.p0i32(i32* %ptr, i32 0xFF) ; yields {i32}:result0 = 0x0F0F -%result1 = call i32 @llvm.atomic.load.and.i32.p0i32( i32* %ptr, i32 0xFF ) +%result1 = call i32 @llvm.atomic.load.and.i32.p0i32(i32* %ptr, i32 0xFF) ; yields {i32}:result1 = 0xFFFFFFF0 -%result2 = call i32 @llvm.atomic.load.or.i32.p0i32( i32* %ptr, i32 0F ) +%result2 = call i32 @llvm.atomic.load.or.i32.p0i32(i32* %ptr, i32 0F) ; yields {i32}:result2 = 0xF0 -%result3 = call i32 @llvm.atomic.load.xor.i32.p0i32( i32* %ptr, i32 0F ) +%result3 = call i32 @llvm.atomic.load.xor.i32.p0i32(i32* %ptr, i32 0F) ; yields {i32}:result3 = FF %memval1 = load i32* %ptr ; yields {i32}:memval1 = F0 @@ -7403,31 +7403,31 @@ address spaces. Not all targets support all bit widths however.

    -  declare i8 @llvm.atomic.load.max.i8.p0i8( i8* <ptr>, i8 <delta> )
    -  declare i16 @llvm.atomic.load.max.i16.p0i16( i16* <ptr>, i16 <delta> )
    -  declare i32 @llvm.atomic.load.max.i32.p0i32( i32* <ptr>, i32 <delta> )
    -  declare i64 @llvm.atomic.load.max.i64.p0i64( i64* <ptr>, i64 <delta> )
    +  declare i8 @llvm.atomic.load.max.i8.p0i8(i8* <ptr>, i8 <delta>)
    +  declare i16 @llvm.atomic.load.max.i16.p0i16(i16* <ptr>, i16 <delta>)
    +  declare i32 @llvm.atomic.load.max.i32.p0i32(i32* <ptr>, i32 <delta>)
    +  declare i64 @llvm.atomic.load.max.i64.p0i64(i64* <ptr>, i64 <delta>)
     
    -  declare i8 @llvm.atomic.load.min.i8.p0i8( i8* <ptr>, i8 <delta> )
    -  declare i16 @llvm.atomic.load.min.i16.p0i16( i16* <ptr>, i16 <delta> )
    -  declare i32 @llvm.atomic.load.min.i32.p0i32( i32* <ptr>, i32 <delta> )
    -  declare i64 @llvm.atomic.load.min.i64.p0i64( i64* <ptr>, i64 <delta> )
    +  declare i8 @llvm.atomic.load.min.i8.p0i8(i8* <ptr>, i8 <delta>)
    +  declare i16 @llvm.atomic.load.min.i16.p0i16(i16* <ptr>, i16 <delta>)
    +  declare i32 @llvm.atomic.load.min.i32.p0i32(i32* <ptr>, i32 <delta>)
    +  declare i64 @llvm.atomic.load.min.i64.p0i64(i64* <ptr>, i64 <delta>)
     
    -  declare i8 @llvm.atomic.load.umax.i8.p0i8( i8* <ptr>, i8 <delta> )
    -  declare i16 @llvm.atomic.load.umax.i16.p0i16( i16* <ptr>, i16 <delta> )
    -  declare i32 @llvm.atomic.load.umax.i32.p0i32( i32* <ptr>, i32 <delta> )
    -  declare i64 @llvm.atomic.load.umax.i64.p0i64( i64* <ptr>, i64 <delta> )
    +  declare i8 @llvm.atomic.load.umax.i8.p0i8(i8* <ptr>, i8 <delta>)
    +  declare i16 @llvm.atomic.load.umax.i16.p0i16(i16* <ptr>, i16 <delta>)
    +  declare i32 @llvm.atomic.load.umax.i32.p0i32(i32* <ptr>, i32 <delta>)
    +  declare i64 @llvm.atomic.load.umax.i64.p0i64(i64* <ptr>, i64 <delta>)
     
    -  declare i8 @llvm.atomic.load.umin.i8.p0i8( i8* <ptr>, i8 <delta> )
    -  declare i16 @llvm.atomic.load.umin.i16.p0i16( i16* <ptr>, i16 <delta> )
    -  declare i32 @llvm.atomic.load.umin.i32.p0i32( i32* <ptr>, i32 <delta> )
    -  declare i64 @llvm.atomic.load.umin.i64.p0i64( i64* <ptr>, i64 <delta> )
    +  declare i8 @llvm.atomic.load.umin.i8.p0i8(i8* <ptr>, i8 <delta>)
    +  declare i16 @llvm.atomic.load.umin.i16.p0i16(i16* <ptr>, i16 <delta>)
    +  declare i32 @llvm.atomic.load.umin.i32.p0i32(i32* <ptr>, i32 <delta>)
    +  declare i64 @llvm.atomic.load.umin.i64.p0i64(i64* <ptr>, i64 <delta>)
     
    Overview:
    @@ -7452,13 +7452,13 @@ %mallocP = tail call i8* @malloc(i32 ptrtoint (i32* getelementptr (i32* null, i32 1) to i32)) %ptr = bitcast i8* %mallocP to i32* store i32 7, %ptr -%result0 = call i32 @llvm.atomic.load.min.i32.p0i32( i32* %ptr, i32 -2 ) +%result0 = call i32 @llvm.atomic.load.min.i32.p0i32(i32* %ptr, i32 -2) ; yields {i32}:result0 = 7 -%result1 = call i32 @llvm.atomic.load.max.i32.p0i32( i32* %ptr, i32 8 ) +%result1 = call i32 @llvm.atomic.load.max.i32.p0i32(i32* %ptr, i32 8) ; yields {i32}:result1 = -2 -%result2 = call i32 @llvm.atomic.load.umin.i32.p0i32( i32* %ptr, i32 10 ) +%result2 = call i32 @llvm.atomic.load.umin.i32.p0i32(i32* %ptr, i32 10) ; yields {i32}:result2 = 8 -%result3 = call i32 @llvm.atomic.load.umax.i32.p0i32( i32* %ptr, i32 30 ) +%result3 = call i32 @llvm.atomic.load.umax.i32.p0i32(i32* %ptr, i32 30) ; yields {i32}:result3 = 8 %memval1 = load i32* %ptr ; yields {i32}:memval1 = 30 @@ -7613,7 +7613,7 @@
    Syntax:
    -  declare void @llvm.var.annotation(i8* <val>, i8* <str>, i8* <str>, i32  <int> )
    +  declare void @llvm.var.annotation(i8* <val>, i8* <str>, i8* <str>, i32  <int>)
     
    Overview:
    @@ -7644,11 +7644,11 @@ any integer bit width.

    -  declare i8 @llvm.annotation.i8(i8 <val>, i8* <str>, i8* <str>, i32  <int> )
    -  declare i16 @llvm.annotation.i16(i16 <val>, i8* <str>, i8* <str>, i32  <int> )
    -  declare i32 @llvm.annotation.i32(i32 <val>, i8* <str>, i8* <str>, i32  <int> )
    -  declare i64 @llvm.annotation.i64(i64 <val>, i8* <str>, i8* <str>, i32  <int> )
    -  declare i256 @llvm.annotation.i256(i256 <val>, i8* <str>, i8* <str>, i32  <int> )
    +  declare i8 @llvm.annotation.i8(i8 <val>, i8* <str>, i8* <str>, i32  <int>)
    +  declare i16 @llvm.annotation.i16(i16 <val>, i8* <str>, i8* <str>, i32  <int>)
    +  declare i32 @llvm.annotation.i32(i32 <val>, i8* <str>, i8* <str>, i32  <int>)
    +  declare i64 @llvm.annotation.i64(i64 <val>, i8* <str>, i8* <str>, i32  <int>)
    +  declare i256 @llvm.annotation.i256(i256 <val>, i8* <str>, i8* <str>, i32  <int>)
     
    Overview:
    @@ -7702,7 +7702,7 @@
    Syntax:
    -  declare void @llvm.stackprotector( i8* <guard>, i8** <slot> )
    +  declare void @llvm.stackprotector(i8* <guard>, i8** <slot>)
     
    Overview:
    @@ -7736,8 +7736,8 @@
    Syntax:
    -  declare i32 @llvm.objectsize.i32( i8* <object>, i1 <type> )
    -  declare i64 @llvm.objectsize.i64( i8* <object>, i1 <type> )
    +  declare i32 @llvm.objectsize.i32(i8* <object>, i1 <type>)
    +  declare i64 @llvm.objectsize.i64(i8* <object>, i1 <type>)
     
    Overview:
    Modified: llvm/trunk/docs/SourceLevelDebugging.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/SourceLevelDebugging.html?rev=104962&r1=104961&r2=104962&view=diff ============================================================================== --- llvm/trunk/docs/SourceLevelDebugging.html (original) +++ llvm/trunk/docs/SourceLevelDebugging.html Fri May 28 12:07:41 2010 @@ -782,7 +782,7 @@
    -  void %llvm.dbg.declare( { } *, metadata )
    +  void %llvm.dbg.declare({ }*, metadata)
     

    This intrinsic provides information about a local element (ex. variable.) The @@ -800,7 +800,7 @@

    -  void %llvm.dbg.value( metadata, i64, metadata )
    +  void %llvm.dbg.value(metadata, i64, metadata)
     

    This intrinsic provides information when a user source variable is set to a Modified: llvm/trunk/docs/tutorial/LangImpl3.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl3.html?rev=104962&r1=104961&r2=104962&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl3.html (original) +++ llvm/trunk/docs/tutorial/LangImpl3.html Fri May 28 12:07:41 2010 @@ -574,8 +574,8 @@ Read function definition: define double @bar(double %a) { entry: - %calltmp = call double @foo( double %a, double 4.000000e+00 ) - %calltmp1 = call double @bar( double 3.133700e+04 ) + %calltmp = call double @foo(double %a, double 4.000000e+00) + %calltmp1 = call double @bar(double 3.133700e+04) %addtmp = fadd double %calltmp, %calltmp1 ret double %addtmp } @@ -596,7 +596,7 @@ Read top-level expression: define double @""() { entry: - %calltmp = call double @cos( double 1.234000e+00 ) + %calltmp = call double @cos(double 1.234000e+00) ret double %calltmp } @@ -629,8 +629,8 @@ define double @bar(double %a) { entry: - %calltmp = call double @foo( double %a, double 4.000000e+00 ) - %calltmp1 = call double @bar( double 3.133700e+04 ) + %calltmp = call double @foo(double %a, double 4.000000e+00) + %calltmp1 = call double @bar(double 3.133700e+04) %addtmp = fadd double %calltmp, %calltmp1 ret double %addtmp } @@ -639,7 +639,7 @@ define double @""() { entry: - %calltmp = call double @cos( double 1.234000e+00 ) + %calltmp = call double @cos(double 1.234000e+00) ret double %calltmp } Modified: llvm/trunk/docs/tutorial/LangImpl4.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl4.html?rev=104962&r1=104961&r2=104962&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl4.html (original) +++ llvm/trunk/docs/tutorial/LangImpl4.html Fri May 28 12:07:41 2010 @@ -371,7 +371,7 @@ ready> testfunc(4, 10); define double @""() { entry: - %calltmp = call double @testfunc( double 4.000000e+00, double 1.000000e+01 ) + %calltmp = call double @testfunc(double 4.000000e+00, double 1.000000e+01) ret double %calltmp } @@ -410,9 +410,9 @@ Read function definition: define double @foo(double %x) { entry: - %calltmp = call double @sin( double %x ) + %calltmp = call double @sin(double %x) %multmp = fmul double %calltmp, %calltmp - %calltmp2 = call double @cos( double %x ) + %calltmp2 = call double @cos(double %x) %multmp4 = fmul double %calltmp2, %calltmp2 %addtmp = fadd double %multmp, %multmp4 ret double %addtmp Modified: llvm/trunk/docs/tutorial/LangImpl5.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl5.html?rev=104962&r1=104961&r2=104962&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl5.html (original) +++ llvm/trunk/docs/tutorial/LangImpl5.html Fri May 28 12:07:41 2010 @@ -676,7 +676,7 @@ loop: ; preds = %loop, %entry %i = phi double [ 1.000000e+00, %entry ], [ %nextvar, %loop ] ; body - %calltmp = call double @putchard( double 4.200000e+01 ) + %calltmp = call double @putchard(double 4.200000e+01) ; increment %nextvar = fadd double %i, 1.000000e+00 Modified: llvm/trunk/docs/tutorial/LangImpl7.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl7.html?rev=104962&r1=104961&r2=104962&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl7.html (original) +++ llvm/trunk/docs/tutorial/LangImpl7.html Fri May 28 12:07:41 2010 @@ -558,10 +558,10 @@ else: ; preds = %entry %x3 = load double* %x1 %subtmp = fsub double %x3, 1.000000e+00 - %calltmp = call double @fib( double %subtmp ) + %calltmp = call double @fib(double %subtmp) %x4 = load double* %x1 %subtmp5 = fsub double %x4, 2.000000e+00 - %calltmp6 = call double @fib( double %subtmp5 ) + %calltmp6 = call double @fib(double %subtmp5) %addtmp = fadd double %calltmp, %calltmp6 br label %ifcont @@ -596,9 +596,9 @@ else: %subtmp = fsub double %x, 1.000000e+00 - %calltmp = call double @fib( double %subtmp ) + %calltmp = call double @fib(double %subtmp) %subtmp5 = fsub double %x, 2.000000e+00 - %calltmp6 = call double @fib( double %subtmp5 ) + %calltmp6 = call double @fib(double %subtmp5) %addtmp = fadd double %calltmp, %calltmp6 br label %ifcont @@ -626,9 +626,9 @@ else: %subtmp = fsub double %x, 1.000000e+00 - %calltmp = call double @fib( double %subtmp ) + %calltmp = call double @fib(double %subtmp) %subtmp5 = fsub double %x, 2.000000e+00 - %calltmp6 = call double @fib( double %subtmp5 ) + %calltmp6 = call double @fib(double %subtmp5) %addtmp = fadd double %calltmp, %calltmp6 ret double %addtmp Modified: llvm/trunk/docs/tutorial/OCamlLangImpl3.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/OCamlLangImpl3.html?rev=104962&r1=104961&r2=104962&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/OCamlLangImpl3.html (original) +++ llvm/trunk/docs/tutorial/OCamlLangImpl3.html Fri May 28 12:07:41 2010 @@ -524,8 +524,8 @@ Read function definition: define double @bar(double %a) { entry: - %calltmp = call double @foo( double %a, double 4.000000e+00 ) - %calltmp1 = call double @bar( double 3.133700e+04 ) + %calltmp = call double @foo(double %a, double 4.000000e+00) + %calltmp1 = call double @bar(double 3.133700e+04) %addtmp = fadd double %calltmp, %calltmp1 ret double %addtmp } @@ -546,7 +546,7 @@ Read top-level expression: define double @""() { entry: - %calltmp = call double @cos( double 1.234000e+00 ) + %calltmp = call double @cos(double 1.234000e+00) ret double %calltmp } @@ -579,8 +579,8 @@ define double @bar(double %a) { entry: - %calltmp = call double @foo( double %a, double 4.000000e+00 ) - %calltmp1 = call double @bar( double 3.133700e+04 ) + %calltmp = call double @foo(double %a, double 4.000000e+00) + %calltmp1 = call double @bar(double 3.133700e+04) %addtmp = fadd double %calltmp, %calltmp1 ret double %addtmp } @@ -589,7 +589,7 @@ define double @""() { entry: - %calltmp = call double @cos( double 1.234000e+00 ) + %calltmp = call double @cos(double 1.234000e+00) ret double %calltmp } Modified: llvm/trunk/docs/tutorial/OCamlLangImpl4.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/OCamlLangImpl4.html?rev=104962&r1=104961&r2=104962&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/OCamlLangImpl4.html (original) +++ llvm/trunk/docs/tutorial/OCamlLangImpl4.html Fri May 28 12:07:41 2010 @@ -387,7 +387,7 @@ ready> testfunc(4, 10); define double @""() { entry: - %calltmp = call double @testfunc( double 4.000000e+00, double 1.000000e+01 ) + %calltmp = call double @testfunc(double 4.000000e+00, double 1.000000e+01) ret double %calltmp } @@ -426,9 +426,9 @@ Read function definition: define double @foo(double %x) { entry: - %calltmp = call double @sin( double %x ) + %calltmp = call double @sin(double %x) %multmp = fmul double %calltmp, %calltmp - %calltmp2 = call double @cos( double %x ) + %calltmp2 = call double @cos(double %x) %multmp4 = fmul double %calltmp2, %calltmp2 %addtmp = fadd double %multmp, %multmp4 ret double %addtmp Modified: llvm/trunk/docs/tutorial/OCamlLangImpl5.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/OCamlLangImpl5.html?rev=104962&r1=104961&r2=104962&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/OCamlLangImpl5.html (original) +++ llvm/trunk/docs/tutorial/OCamlLangImpl5.html Fri May 28 12:07:41 2010 @@ -651,7 +651,7 @@ loop: ; preds = %loop, %entry %i = phi double [ 1.000000e+00, %entry ], [ %nextvar, %loop ] ; body - %calltmp = call double @putchard( double 4.200000e+01 ) + %calltmp = call double @putchard(double 4.200000e+01) ; increment %nextvar = fadd double %i, 1.000000e+00 Modified: llvm/trunk/docs/tutorial/OCamlLangImpl7.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/OCamlLangImpl7.html?rev=104962&r1=104961&r2=104962&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/OCamlLangImpl7.html (original) +++ llvm/trunk/docs/tutorial/OCamlLangImpl7.html Fri May 28 12:07:41 2010 @@ -582,10 +582,10 @@ else: ; preds = %entry %x3 = load double* %x1 %subtmp = fsub double %x3, 1.000000e+00 - %calltmp = call double @fib( double %subtmp ) + %calltmp = call double @fib(double %subtmp) %x4 = load double* %x1 %subtmp5 = fsub double %x4, 2.000000e+00 - %calltmp6 = call double @fib( double %subtmp5 ) + %calltmp6 = call double @fib(double %subtmp5) %addtmp = fadd double %calltmp, %calltmp6 br label %ifcont @@ -620,9 +620,9 @@ else: %subtmp = fsub double %x, 1.000000e+00 - %calltmp = call double @fib( double %subtmp ) + %calltmp = call double @fib(double %subtmp) %subtmp5 = fsub double %x, 2.000000e+00 - %calltmp6 = call double @fib( double %subtmp5 ) + %calltmp6 = call double @fib(double %subtmp5) %addtmp = fadd double %calltmp, %calltmp6 br label %ifcont @@ -650,9 +650,9 @@ else: %subtmp = fsub double %x, 1.000000e+00 - %calltmp = call double @fib( double %subtmp ) + %calltmp = call double @fib(double %subtmp) %subtmp5 = fsub double %x, 2.000000e+00 - %calltmp6 = call double @fib( double %subtmp5 ) + %calltmp6 = call double @fib(double %subtmp5) %addtmp = fadd double %calltmp, %calltmp6 ret double %addtmp From gohman at apple.com Fri May 28 12:13:49 2010 From: gohman at apple.com (Dan Gohman) Date: Fri, 28 May 2010 17:13:49 -0000 Subject: [llvm-commits] [llvm] r104963 - in /llvm/trunk/docs: LangRef.html SourceLevelDebugging.html Message-ID: <20100528171349.CE611312800A@llvm.org> Author: djg Date: Fri May 28 12:13:49 2010 New Revision: 104963 URL: http://llvm.org/viewvc/llvm-project?rev=104963&view=rev Log: Fix more whitespace to be consistent with AsmPrinter. Modified: llvm/trunk/docs/LangRef.html llvm/trunk/docs/SourceLevelDebugging.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=104963&r1=104962&r2=104963&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Fri May 28 12:13:49 2010 @@ -503,15 +503,15 @@ @.LC0 = internal constant [13 x i8] c"hello world\0A\00" ; [13 x i8]* ; External declaration of the puts function -declare i32 @puts(i8 *) ; i32(i8 *)* +declare i32 @puts(i8*) ; i32 (i8*)* ; Definition of main function define i32 @main() { ; i32()* ; Convert [13 x i8]* to i8 *... - %cast210 = getelementptr [13 x i8]* @.LC0, i64 0, i64 0 ; i8 * + %cast210 = getelementptr [13 x i8]* @.LC0, i64 0, i64 0 ; i8* ; Call puts function to write out the string to stdout. - call i32 @puts(i8 * %cast210) ; i32 + call i32 @puts(i8* %cast210) ; i32 ret i32 0
    } ; Named metadata @@ -1900,7 +1900,7 @@ href="#t_array">array of four i32 values. - i32 (i32 *) * + i32 (i32*) * A pointer to a function that takes an i32*, returning an i32. @@ -5406,7 +5406,7 @@

    Example:
       %retval = call i32 @test(i32 %argc)
    -  call i32 (i8 *, ...)* @printf(i8 * %msg, i32 12, i8 42)      ; yields i32
    +  call i32 (i8*, ...)* @printf(i8* %msg, i32 12, i8 42)        ; yields i32
       %X = tail call i32 @foo()                                    ; yields i32
       %Y = tail call fastcc i32 @foo()  ; yields i32
       call void %foo(i8 97 signext)
    @@ -5839,7 +5839,7 @@
     
     
    Syntax:
    -  declare i8 *@llvm.frameaddress(i32 <level>)
    +  declare i8* @llvm.frameaddress(i32 <level>)
     
    Overview:
    @@ -5873,7 +5873,7 @@
    Syntax:
    -  declare i8 *@llvm.stacksave()
    +  declare i8* @llvm.stacksave()
     
    Overview:
    @@ -5903,7 +5903,7 @@
    Syntax:
    -  declare void @llvm.stackrestore(i8 * %ptr)
    +  declare void @llvm.stackrestore(i8* %ptr)
     
    Overview:
    @@ -6037,9 +6037,9 @@ all bit widths however.

    -  declare void @llvm.memcpy.p0i8.p0i8.i32(i8 * <dest>, i8 * <src>,
    +  declare void @llvm.memcpy.p0i8.p0i8.i32(i8* <dest>, i8* <src>,
                                               i32 <len>, i32 <align>, i1 <isvolatile>)
    -  declare void @llvm.memcpy.p0i8.p0i8.i64(i8 * <dest>, i8 * <src>,
    +  declare void @llvm.memcpy.p0i8.p0i8.i64(i8* <dest>, i8* <src>,
                                               i64 <len>, i32 <align>, i1 <isvolatile>)
     
    @@ -6091,9 +6091,9 @@ widths however.

    -  declare void @llvm.memmove.p0i8.p0i8.i32(i8 * <dest>, i8 * <src>,
    +  declare void @llvm.memmove.p0i8.p0i8.i32(i8* <dest>, i8* <src>,
                                                i32 <len>, i32 <align>, i1 <isvolatile>)
    -  declare void @llvm.memmove.p0i8.p0i8.i64(i8 * <dest>, i8 * <src>,
    +  declare void @llvm.memmove.p0i8.p0i8.i64(i8* <dest>, i8* <src>,
                                                i64 <len>, i32 <align>, i1 <isvolatile>)
     
    @@ -6147,9 +6147,9 @@ widths however.

    -  declare void @llvm.memset.p0i8.i32(i8 * <dest>, i8 <val>,
    +  declare void @llvm.memset.p0i8.i32(i8* <dest>, i8 <val>,
                                          i32 <len>, i32 <align>, i1 <isvolatile>)
    -  declare void @llvm.memset.p0i8.i64(i8 * <dest>, i8 <val>,
    +  declare void @llvm.memset.p0i8.i64(i8* <dest>, i8 <val>,
                                          i64 <len>, i32 <align>, i1 <isvolatile>)
     
    Modified: llvm/trunk/docs/SourceLevelDebugging.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/SourceLevelDebugging.html?rev=104963&r1=104962&r2=104963&view=diff ============================================================================== --- llvm/trunk/docs/SourceLevelDebugging.html (original) +++ llvm/trunk/docs/SourceLevelDebugging.html Fri May 28 12:13:49 2010 @@ -401,7 +401,7 @@ metadata, ;; Reference to type descriptor i1, ;; True if the global is local to compile unit (static) i1, ;; True if the global is defined in the compile unit (not extern) - { }* ;; Reference to the global variable + {}* ;; Reference to the global variable }
    @@ -782,11 +782,11 @@
    -  void %llvm.dbg.declare({ }*, metadata)
    +  void %llvm.dbg.declare({}*, metadata)
     

    This intrinsic provides information about a local element (ex. variable.) The - first argument is the alloca for the variable, cast to a { }*. The + first argument is the alloca for the variable, cast to a {}*. The second argument is the %llvm.dbg.variable containing the description of the variable.

    @@ -854,14 +854,14 @@ %X = alloca i32, align 4 ; <i32*> [#uses=4] %Y = alloca i32, align 4 ; <i32*> [#uses=4] %Z = alloca i32, align 4 ; <i32*> [#uses=3] - %0 = bitcast i32* %X to { }* ; <{ }*> [#uses=1] - call void @llvm.dbg.declare({ }* %0, metadata !0), !dbg !7 + %0 = bitcast i32* %X to {}* ; <{}*> [#uses=1] + call void @llvm.dbg.declare({}* %0, metadata !0), !dbg !7 store i32 21, i32* %X, !dbg !8 - %1 = bitcast i32* %Y to { }* ; <{ }*> [#uses=1] - call void @llvm.dbg.declare({ }* %1, metadata !9), !dbg !10 + %1 = bitcast i32* %Y to {}* ; <{}*> [#uses=1] + call void @llvm.dbg.declare({}* %1, metadata !9), !dbg !10 store i32 22, i32* %Y, !dbg !11 - %2 = bitcast i32* %Z to { }* ; <{ }*> [#uses=1] - call void @llvm.dbg.declare({ }* %2, metadata !12), !dbg !14 + %2 = bitcast i32* %Z to {}* ; <{}*> [#uses=1] + call void @llvm.dbg.declare({}* %2, metadata !12), !dbg !14 store i32 23, i32* %Z, !dbg !15 %tmp = load i32* %X, !dbg !16 ; <i32> [#uses=1] %tmp1 = load i32* %Y, !dbg !16 ; <i32> [#uses=1] @@ -872,7 +872,7 @@ ret void, !dbg !18 } -declare void @llvm.dbg.declare({ }*, metadata) nounwind readnone +declare void @llvm.dbg.declare({}*, metadata) nounwind readnone !0 = metadata !{i32 459008, metadata !1, metadata !"X", metadata !3, i32 2, metadata !6}; [ DW_TAG_auto_variable ] @@ -914,7 +914,7 @@
    -call void @llvm.dbg.declare({ }* %0, metadata !0), !dbg !7   
    +call void @llvm.dbg.declare({}* %0, metadata !0), !dbg !7   
     
    @@ -949,7 +949,7 @@
    -call void @llvm.dbg.declare({ }* %2, metadata !12), !dbg !14
    +call void @llvm.dbg.declare({}* %2, metadata !12), !dbg !14
     
    From fjahanian at apple.com Fri May 28 12:35:04 2010 From: fjahanian at apple.com (Fariborz Jahanian) Date: Fri, 28 May 2010 17:35:04 -0000 Subject: [llvm-commits] [test-suite] r104965 - /test-suite/trunk/SingleSource/UnitTests/ObjC/exceptions-3.m Message-ID: <20100528173504.8B5BE312800A@llvm.org> Author: fjahanian Date: Fri May 28 12:35:04 2010 New Revision: 104965 URL: http://llvm.org/viewvc/llvm-project?rev=104965&view=rev Log: Test for radar 8037512. Added: test-suite/trunk/SingleSource/UnitTests/ObjC/exceptions-3.m Added: test-suite/trunk/SingleSource/UnitTests/ObjC/exceptions-3.m URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/ObjC/exceptions-3.m?rev=104965&view=auto ============================================================================== --- test-suite/trunk/SingleSource/UnitTests/ObjC/exceptions-3.m (added) +++ test-suite/trunk/SingleSource/UnitTests/ObjC/exceptions-3.m Fri May 28 12:35:04 2010 @@ -0,0 +1,45 @@ +#include +// rdar: // 8037512 + +int main() +{ + int state = 0; + [NSAutoreleasePool new]; + + @try { + state++; + @try { + state++; + @throw [NSObject new]; + } + @catch (...) { + state--; + @throw; + } + } + + @catch (...) { + state--; + } + + if (state) + abort(); + + @try { + state++; + @try { + state++; + @throw [NSObject new]; + } + @catch (id e) { + state--; + @throw; + } + } + @catch (id e) { + state--; + } + if (state) + abort(); + return 0; +} From daniel at zuster.org Fri May 28 12:36:23 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Fri, 28 May 2010 17:36:23 -0000 Subject: [llvm-commits] [zorg] r104966 - /zorg/trunk/lnt/lnt/tests/nt.py Message-ID: <20100528173623.0B8DF312800A@llvm.org> Author: ddunbar Date: Fri May 28 12:36:22 2010 New Revision: 104966 URL: http://llvm.org/viewvc/llvm-project?rev=104966&view=rev Log: LNT/runtest nt: Add --optimize-option, for setting the OPTFLAGS, LLC_OPTFLAGS, and LLI_OPTFLAGS options to nightly test makefiles. Modified: zorg/trunk/lnt/lnt/tests/nt.py Modified: zorg/trunk/lnt/lnt/tests/nt.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/tests/nt.py?rev=104966&r1=104965&r2=104966&view=diff ============================================================================== --- zorg/trunk/lnt/lnt/tests/nt.py (original) +++ zorg/trunk/lnt/lnt/tests/nt.py Fri May 28 12:36:22 2010 @@ -49,6 +49,15 @@ 'ENABLE_OPTIMIZED' : '1', } + # Set the optimization level options. + make_variables['OPTFLAGS'] = opts.optimize_option + if opts.optimize_option == '-Os': + make_variables['LLI_OPTFLAGS'] = '-O3' + make_variables['LLC_OPTFLAGS'] = '-O3' + else: + make_variables['LLI_OPTFLAGS'] = opts.optimize_option + make_variables['LLC_OPTFLAGS'] = opts.optimize_option + # Set test selection variables. make_variables['TARGET_CXX'] = opts.cxx_reference if opts.test_cxx: @@ -440,6 +449,9 @@ help=("Set -disable-fp-elim in TARGET_LLCFLAGS"), action="store_true", default=False) + group.add_option("", "--optimize-option", dest="optimize_option", + help="Set optimization level for {LLC_,LLI_,}OPTFLAGS", + choices=('-O0','-O1','-O2','-O3'), default='-O3') group.add_option("", "--cflag", dest="cflags", help="Additional flags to set in TARGET_FLAGS", action="append", type=str, default=[], metavar="FLAG") From grosbach at apple.com Fri May 28 12:37:40 2010 From: grosbach at apple.com (Jim Grosbach) Date: Fri, 28 May 2010 17:37:40 -0000 Subject: [llvm-commits] [llvm] r104967 - in /llvm/trunk/lib/Target/ARM: ARMInstrInfo.td ARMInstrThumb.td ARMInstrThumb2.td Message-ID: <20100528173740.A3289312800A@llvm.org> Author: grosbach Date: Fri May 28 12:37:40 2010 New Revision: 104967 URL: http://llvm.org/viewvc/llvm-project?rev=104967&view=rev Log: make sure accesses to set up the jmpbuf don't get moved after it by the scheduler. Add a missing \n. Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td llvm/trunk/lib/Target/ARM/ARMInstrThumb.td llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=104967&r1=104966&r2=104967&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Fri May 28 12:37:40 2010 @@ -2530,11 +2530,11 @@ [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30, - D31 ] in { + D31 ], hasSideEffects = 1, isBarrier = 1 in { def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val), AddrModeNone, SizeSpecial, IndexModeNone, Pseudo, NoItinerary, - "add\t$val, pc, #8\t${:comment} eh_setjmp begin\t" + "add\t$val, pc, #4\t${:comment} eh_setjmp begin\n\t" "str\t$val, [$src, #+4]\n\t" "mov\tr0, #0\n\t" "add\tpc, pc, #0\n\t" @@ -2544,11 +2544,12 @@ } let Defs = - [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ] in { + [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ], + hasSideEffects = 1, isBarrier = 1 in { def Int_eh_sjlj_setjmp_nofp : XI<(outs), (ins GPR:$src, GPR:$val), AddrModeNone, SizeSpecial, IndexModeNone, Pseudo, NoItinerary, - "add\t$val, pc, #8\n ${:comment} eh_setjmp begin\t" + "add\t$val, pc, #4\n ${:comment} eh_setjmp begin\n\t" "str\t$val, [$src, #+4]\n\t" "mov\tr0, #0\n\t" "add\tpc, pc, #0\n\t" Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=104967&r1=104966&r2=104967&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Fri May 28 12:37:40 2010 @@ -925,7 +925,8 @@ // all of the callee-saved resgisters, which is exactly what we want. // $val is a scratch register for our use. let Defs = - [ R0, R1, R2, R3, R4, R5, R6, R7, R12 ] in { + [ R0, R1, R2, R3, R4, R5, R6, R7, R12 ], hasSideEffects = 1, + isBarrier = 1 in { def tInt_eh_sjlj_setjmp : ThumbXI<(outs),(ins tGPR:$src, tGPR:$val), AddrModeNone, SizeSpecial, NoItinerary, "mov\t$val, pc\t${:comment} begin eh.setjmp\n" Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=104967&r1=104966&r2=104967&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Fri May 28 12:37:40 2010 @@ -2394,7 +2394,7 @@ [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30, - D31 ] in { + D31 ], hasSideEffects = 1, isBarrier = 1 in { def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins GPR:$src, tGPR:$val), AddrModeNone, SizeSpecial, NoItinerary, "mov\t$val, pc\t${:comment} begin eh.setjmp\n" @@ -2409,7 +2409,8 @@ } let Defs = - [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ] in { + [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ], + hasSideEffects = 1, isBarrier = 1 in { def t2Int_eh_sjlj_setjmp_nofp : Thumb2XI<(outs), (ins GPR:$src, tGPR:$val), AddrModeNone, SizeSpecial, NoItinerary, "mov\t$val, pc\t${:comment} begin eh.setjmp\n" From gohman at apple.com Fri May 28 12:44:00 2010 From: gohman at apple.com (Dan Gohman) Date: Fri, 28 May 2010 17:44:00 -0000 Subject: [llvm-commits] [llvm] r104970 - in /llvm/trunk: lib/Analysis/Lint.cpp test/Other/lint.ll Message-ID: <20100528174400.E1397312800A@llvm.org> Author: djg Date: Fri May 28 12:44:00 2010 New Revision: 104970 URL: http://llvm.org/viewvc/llvm-project?rev=104970&view=rev Log: Fix lint's memcpy and memmove checks, and its basic block traversal. Modified: llvm/trunk/lib/Analysis/Lint.cpp llvm/trunk/test/Other/lint.ll Modified: llvm/trunk/lib/Analysis/Lint.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/Lint.cpp?rev=104970&r1=104969&r2=104970&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/Lint.cpp (original) +++ llvm/trunk/lib/Analysis/Lint.cpp Fri May 28 12:44:00 2010 @@ -248,9 +248,9 @@ case Intrinsic::memcpy: { MemCpyInst *MCI = cast(&I); - visitMemoryReference(I, MCI->getSource(), MCI->getAlignment(), 0, - MemRef::Write); visitMemoryReference(I, MCI->getDest(), MCI->getAlignment(), 0, + MemRef::Write); + visitMemoryReference(I, MCI->getSource(), MCI->getAlignment(), 0, MemRef::Read); // Check that the memcpy arguments don't overlap. The AliasAnalysis API @@ -269,9 +269,9 @@ } case Intrinsic::memmove: { MemMoveInst *MMI = cast(&I); - visitMemoryReference(I, MMI->getSource(), MMI->getAlignment(), 0, - MemRef::Write); visitMemoryReference(I, MMI->getDest(), MMI->getAlignment(), 0, + MemRef::Write); + visitMemoryReference(I, MMI->getSource(), MMI->getAlignment(), 0, MemRef::Read); break; } @@ -519,11 +519,14 @@ if (LoadInst *L = dyn_cast(V)) { BasicBlock::iterator BBI = L; BasicBlock *BB = L->getParent(); + SmallPtrSet VisitedBlocks; for (;;) { + if (!VisitedBlocks.insert(BB)) break; if (Value *U = FindAvailableLoadedValue(L->getPointerOperand(), BB, BBI, 6, AA)) return findValueImpl(U, OffsetOk, Visited); - BB = L->getParent()->getUniquePredecessor(); + if (BBI != BB->begin()) break; + BB = BB->getUniquePredecessor(); if (!BB) break; BBI = BB->end(); } Modified: llvm/trunk/test/Other/lint.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/lint.ll?rev=104970&r1=104969&r2=104970&view=diff ============================================================================== --- llvm/trunk/test/Other/lint.ll (original) +++ llvm/trunk/test/Other/lint.ll Fri May 28 12:44:00 2010 @@ -3,6 +3,7 @@ declare fastcc void @bar() declare void @llvm.stackrestore(i8*) +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind @CG = constant i32 7 @@ -54,6 +55,9 @@ ; CHECK: Undefined behavior: Null pointer dereference call void @llvm.stackrestore(i8* null) +; CHECK: Write to read-only memory + call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast (i32* @CG to i8*), i8* bitcast (i32* @CG to i8*), i64 1, i32 1, i1 0) + br label %next next: From daniel at zuster.org Fri May 28 12:49:10 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Fri, 28 May 2010 17:49:10 -0000 Subject: [llvm-commits] [zorg] r104973 - /zorg/trunk/lnt/lnt/tests/nt.py Message-ID: <20100528174910.CD21D312800A@llvm.org> Author: ddunbar Date: Fri May 28 12:49:10 2010 New Revision: 104973 URL: http://llvm.org/viewvc/llvm-project?rev=104973&view=rev Log: LNT/runtest nt: --optimize-option -Os should set -O2 for LLC, not -O3. Modified: zorg/trunk/lnt/lnt/tests/nt.py Modified: zorg/trunk/lnt/lnt/tests/nt.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/tests/nt.py?rev=104973&r1=104972&r2=104973&view=diff ============================================================================== --- zorg/trunk/lnt/lnt/tests/nt.py (original) +++ zorg/trunk/lnt/lnt/tests/nt.py Fri May 28 12:49:10 2010 @@ -52,8 +52,8 @@ # Set the optimization level options. make_variables['OPTFLAGS'] = opts.optimize_option if opts.optimize_option == '-Os': - make_variables['LLI_OPTFLAGS'] = '-O3' - make_variables['LLC_OPTFLAGS'] = '-O3' + make_variables['LLI_OPTFLAGS'] = '-O2' + make_variables['LLC_OPTFLAGS'] = '-O2' else: make_variables['LLI_OPTFLAGS'] = opts.optimize_option make_variables['LLC_OPTFLAGS'] = opts.optimize_option From grosbach at apple.com Fri May 28 12:51:20 2010 From: grosbach at apple.com (Jim Grosbach) Date: Fri, 28 May 2010 17:51:20 -0000 Subject: [llvm-commits] [llvm] r104974 - in /llvm/trunk/lib/Target/ARM: ARMInstrThumb.td ARMInstrThumb2.td Message-ID: <20100528175120.CE030312800A@llvm.org> Author: grosbach Date: Fri May 28 12:51:20 2010 New Revision: 104974 URL: http://llvm.org/viewvc/llvm-project?rev=104974&view=rev Log: Cosmetic cleanup. No functional change. Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=104974&r1=104973&r2=104974&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Fri May 28 12:51:20 2010 @@ -929,12 +929,12 @@ isBarrier = 1 in { def tInt_eh_sjlj_setjmp : ThumbXI<(outs),(ins tGPR:$src, tGPR:$val), AddrModeNone, SizeSpecial, NoItinerary, - "mov\t$val, pc\t${:comment} begin eh.setjmp\n" - "\tadds\t$val, #7\n" - "\tstr\t$val, [$src, #4]\n" - "\tmovs\tr0, #0\n" - "\tb\t1f\n" - "\tmovs\tr0, #1\t${:comment} end eh.setjmp\n" + "mov\t$val, pc\t${:comment} begin eh.setjmp\n\t" + "adds\t$val, #7\n\t" + "str\t$val, [$src, #4]\n\t" + "movs\tr0, #0\n\t" + "b\t1f\n\t" + "movs\tr0, #1\t${:comment} end eh.setjmp\n\t" "1:", "", [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>; } Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=104974&r1=104973&r2=104974&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Fri May 28 12:51:20 2010 @@ -2397,12 +2397,12 @@ D31 ], hasSideEffects = 1, isBarrier = 1 in { def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins GPR:$src, tGPR:$val), AddrModeNone, SizeSpecial, NoItinerary, - "mov\t$val, pc\t${:comment} begin eh.setjmp\n" - "\tadds\t$val, #7\n" - "\tstr\t$val, [$src, #4]\n" - "\tmovs\tr0, #0\n" - "\tb\t1f\n" - "\tmovs\tr0, #1\t${:comment} end eh.setjmp\n" + "mov\t$val, pc\t${:comment} begin eh.setjmp\n\t" + "adds\t$val, #7\n\t" + "str\t$val, [$src, #4]\n\t" + "movs\tr0, #0\n\t" + "b\t1f\n\t" + "movs\tr0, #1\t${:comment} end eh.setjmp\n\t" "1:", "", [(set R0, (ARMeh_sjlj_setjmp GPR:$src, tGPR:$val))]>, Requires<[IsThumb2, HasVFP2]>; @@ -2413,12 +2413,12 @@ hasSideEffects = 1, isBarrier = 1 in { def t2Int_eh_sjlj_setjmp_nofp : Thumb2XI<(outs), (ins GPR:$src, tGPR:$val), AddrModeNone, SizeSpecial, NoItinerary, - "mov\t$val, pc\t${:comment} begin eh.setjmp\n" - "\tadds\t$val, #7\n" - "\tstr\t$val, [$src, #4]\n" - "\tmovs\tr0, #0\n" - "\tb\t1f\n" - "\tmovs\tr0, #1\t${:comment} end eh.setjmp\n" + "mov\t$val, pc\t${:comment} begin eh.setjmp\n\t" + "adds\t$val, #7\n\t" + "str\t$val, [$src, #4]\n\t" + "movs\tr0, #0\n\t" + "b\t1f\n\t" + "movs\tr0, #1\t${:comment} end eh.setjmp\n\t" "1:", "", [(set R0, (ARMeh_sjlj_setjmp GPR:$src, tGPR:$val))]>, Requires<[IsThumb2, NoVFP]>; From grosbach at apple.com Fri May 28 13:03:48 2010 From: grosbach at apple.com (Jim Grosbach) Date: Fri, 28 May 2010 18:03:48 -0000 Subject: [llvm-commits] [llvm] r104980 - /llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Message-ID: <20100528180348.73910312800A@llvm.org> Author: grosbach Date: Fri May 28 13:03:48 2010 New Revision: 104980 URL: http://llvm.org/viewvc/llvm-project?rev=104980&view=rev Log: correct retattr Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=104980&r1=104979&r2=104980&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Fri May 28 13:03:48 2010 @@ -2534,7 +2534,7 @@ def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src, GPR:$val), AddrModeNone, SizeSpecial, IndexModeNone, Pseudo, NoItinerary, - "add\t$val, pc, #4\t${:comment} eh_setjmp begin\n\t" + "add\t$val, pc, #8\t${:comment} eh_setjmp begin\n\t" "str\t$val, [$src, #+4]\n\t" "mov\tr0, #0\n\t" "add\tpc, pc, #0\n\t" @@ -2549,7 +2549,7 @@ def Int_eh_sjlj_setjmp_nofp : XI<(outs), (ins GPR:$src, GPR:$val), AddrModeNone, SizeSpecial, IndexModeNone, Pseudo, NoItinerary, - "add\t$val, pc, #4\n ${:comment} eh_setjmp begin\n\t" + "add\t$val, pc, #8\n ${:comment} eh_setjmp begin\n\t" "str\t$val, [$src, #+4]\n\t" "mov\tr0, #0\n\t" "add\tpc, pc, #0\n\t" From stoklund at 2pi.dk Fri May 28 13:18:53 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Fri, 28 May 2010 18:18:53 -0000 Subject: [llvm-commits] [llvm] r104985 - in /llvm/trunk: include/llvm/CodeGen/MachineOperand.h include/llvm/Target/TargetRegisterInfo.h lib/CodeGen/MachineInstr.cpp Message-ID: <20100528181853.AD88D312800A@llvm.org> Author: stoklund Date: Fri May 28 13:18:53 2010 New Revision: 104985 URL: http://llvm.org/viewvc/llvm-project?rev=104985&view=rev Log: Add a TargetRegisterInfo::composeSubRegIndices hook with a default implementation that is correct for most targets. Tablegen will override where needed. Add MachineOperand::subst{Virt,Phys}Reg methods that correctly handle existing subreg indices when sustituting registers. Modified: llvm/trunk/include/llvm/CodeGen/MachineOperand.h llvm/trunk/include/llvm/Target/TargetRegisterInfo.h llvm/trunk/lib/CodeGen/MachineInstr.cpp Modified: llvm/trunk/include/llvm/CodeGen/MachineOperand.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineOperand.h?rev=104985&r1=104984&r2=104985&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineOperand.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineOperand.h Fri May 28 13:18:53 2010 @@ -27,6 +27,7 @@ class MachineRegisterInfo; class MDNode; class TargetMachine; +class TargetRegisterInfo; class raw_ostream; class MCSymbol; @@ -246,7 +247,20 @@ assert(isReg() && "Wrong MachineOperand accessor"); SubReg = (unsigned char)subReg; } - + + /// substVirtReg - Substitute the current register with the virtual + /// subregister Reg:SubReg. Take any existing SubReg index into account, + /// using TargetRegisterInfo to compose the subreg indices if necessary. + /// Reg must be a virtual register, SubIdx can be 0. + /// + void substVirtReg(unsigned Reg, unsigned SubIdx, const TargetRegisterInfo&); + + /// substPhysReg - Substitute the current register with the physical register + /// Reg, taking any existing SubReg into account. For instance, + /// substPhysReg(%EAX) will change %reg1024:sub_8bit to %AL. + /// + void substPhysReg(unsigned Reg, const TargetRegisterInfo&); + void setIsUse(bool Val = true) { assert(isReg() && "Wrong MachineOperand accessor"); assert((Val || !isDebug()) && "Marking a debug operation as def"); Modified: llvm/trunk/include/llvm/Target/TargetRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetRegisterInfo.h?rev=104985&r1=104984&r2=104985&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetRegisterInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetRegisterInfo.h Fri May 28 13:18:53 2010 @@ -490,6 +490,23 @@ return 0; } + /// composeSubRegIndices - Return the subregister index you get from composing + /// two subregister indices. + /// + /// If R:a:b is the same register as R:c, then composeSubRegIndices(a, b) + /// returns c. Note that composeSubRegIndices does not tell you about illegal + /// compositions. If R does not have a subreg a, or R:a does not have a subreg + /// b, composeSubRegIndices doesn't tell you. + /// + /// The ARM register Q0 has two D subregs dsub_0:D0 and dsub_1:D1. It also has + /// ssub_0:S0 - ssub_3:S3 subregs. + /// If you compose subreg indices dsub_1, ssub_0 you get ssub_2. + /// + virtual unsigned composeSubRegIndices(unsigned a, unsigned b) const { + // This default implementation is correct for most targets. + return b; + } + //===--------------------------------------------------------------------===// // Register Class Information // Modified: llvm/trunk/lib/CodeGen/MachineInstr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineInstr.cpp?rev=104985&r1=104984&r2=104985&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineInstr.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineInstr.cpp Fri May 28 13:18:53 2010 @@ -111,6 +111,25 @@ Contents.Reg.RegNo = Reg; } +void MachineOperand::substVirtReg(unsigned Reg, unsigned SubIdx, + const TargetRegisterInfo &TRI) { + assert(TargetRegisterInfo::isVirtualRegister(Reg)); + if (SubIdx && getSubReg()) + SubIdx = TRI.composeSubRegIndices(SubIdx, getSubReg()); + setReg(Reg); + setSubReg(SubIdx); +} + +void MachineOperand::substPhysReg(unsigned Reg, const TargetRegisterInfo &TRI) { + assert(TargetRegisterInfo::isPhysicalRegister(Reg)); + if (getSubReg()) { + Reg = TRI.getSubReg(Reg, getSubReg()); + assert(Reg && "Invalid SubReg for physical register"); + setSubReg(0); + } + setReg(Reg); +} + /// ChangeToImmediate - Replace this operand with a new immediate operand of /// the specified value. If an operand is known to be an immediate already, /// the setImm method should be used. From sabre at nondot.org Fri May 28 13:20:56 2010 From: sabre at nondot.org (Chris Lattner) Date: Fri, 28 May 2010 18:20:56 -0000 Subject: [llvm-commits] [www] r104986 - /www/trunk/devmtg/2009-10/index.html Message-ID: <20100528182056.89330312800A@llvm.org> Author: lattner Date: Fri May 28 13:20:56 2010 New Revision: 104986 URL: http://llvm.org/viewvc/llvm-project?rev=104986&view=rev Log: add the missing videos. Modified: www/trunk/devmtg/2009-10/index.html Modified: www/trunk/devmtg/2009-10/index.html URL: http://llvm.org/viewvc/llvm-project/www/trunk/devmtg/2009-10/index.html?rev=104986&r1=104985&r2=104986&view=diff ============================================================================== --- www/trunk/devmtg/2009-10/index.html (original) +++ www/trunk/devmtg/2009-10/index.html Fri May 28 13:20:56 2010 @@ -56,7 +56,7 @@ [Slides]
    - [No Video] + [Video] Doug Gregor, Chris Lattner, Ted Kremenek
    @@ -116,7 +116,7 @@ [Slides]
    - [No Video] + [Video] Dan Gohman
    ScalarEvolution and Loop Optimization - LLVM's ScalarEvolution framework has undergone some major changes and now sports some cool new features. I'll give an overview of what ScalarEvolution can do, illustrate the new features, and discuss the infrastructure behind the functionality. @@ -186,7 +186,7 @@ [Slides]
    - [No Videos]
    + [Videos]
    Lang Hames
    Future Works in LLVM Register Allocation - About the future of register allocation in LLVM. @@ -209,7 +209,7 @@ [Slides]
    - [No Videos]
    + [Videos]
    Nate Begeman
    OpenCL From sabre at nondot.org Fri May 28 13:21:43 2010 From: sabre at nondot.org (Chris Lattner) Date: Fri, 28 May 2010 18:21:43 -0000 Subject: [llvm-commits] [www] r104987 - /www/trunk/devmtg/2009-10/index.html Message-ID: <20100528182144.1A88D312800A@llvm.org> Author: lattner Date: Fri May 28 13:21:43 2010 New Revision: 104987 URL: http://llvm.org/viewvc/llvm-project?rev=104987&view=rev Log: depluralize Modified: www/trunk/devmtg/2009-10/index.html Modified: www/trunk/devmtg/2009-10/index.html URL: http://llvm.org/viewvc/llvm-project/www/trunk/devmtg/2009-10/index.html?rev=104987&r1=104986&r2=104987&view=diff ============================================================================== --- www/trunk/devmtg/2009-10/index.html (original) +++ www/trunk/devmtg/2009-10/index.html Fri May 28 13:21:43 2010 @@ -186,7 +186,7 @@ [Slides]
    - [Videos]
    + [Video]
    Lang Hames
    Future Works in LLVM Register Allocation - About the future of register allocation in LLVM. @@ -209,7 +209,7 @@ [Slides]
    - [Videos]
    + [Video]
    Nate Begeman
    OpenCL From dalej at apple.com Fri May 28 13:45:59 2010 From: dalej at apple.com (Dale Johannesen) Date: Fri, 28 May 2010 18:45:59 -0000 Subject: [llvm-commits] [llvm] r104992 - /llvm/trunk/test/Transforms/Mem2Reg/ConvertDebugInfo2.ll Message-ID: <20100528184559.2BE0C312800A@llvm.org> Author: johannes Date: Fri May 28 13:45:59 2010 New Revision: 104992 URL: http://llvm.org/viewvc/llvm-project?rev=104992&view=rev Log: Add missing space; works for me. Modified: llvm/trunk/test/Transforms/Mem2Reg/ConvertDebugInfo2.ll Modified: llvm/trunk/test/Transforms/Mem2Reg/ConvertDebugInfo2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Mem2Reg/ConvertDebugInfo2.ll?rev=104992&r1=104991&r2=104992&view=diff ============================================================================== --- llvm/trunk/test/Transforms/Mem2Reg/ConvertDebugInfo2.ll (original) +++ llvm/trunk/test/Transforms/Mem2Reg/ConvertDebugInfo2.ll Fri May 28 13:45:59 2010 @@ -1,4 +1,4 @@ -; RUN: opt -mem2reg < %s | llvm-dis | grep ".dbg "| count 6 +; RUN: opt -mem2reg < %s | llvm-dis | grep ".dbg " | count 6 declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone From dalej at apple.com Fri May 28 13:54:47 2010 From: dalej at apple.com (Dale Johannesen) Date: Fri, 28 May 2010 18:54:47 -0000 Subject: [llvm-commits] [llvm] r104993 - /llvm/trunk/docs/LangRef.html Message-ID: <20100528185448.216FB312800A@llvm.org> Author: johannes Date: Fri May 28 13:54:47 2010 New Revision: 104993 URL: http://llvm.org/viewvc/llvm-project?rev=104993&view=rev Log: Fix Data Layout description of floating point. Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=104993&r1=104992&r2=104993&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Fri May 28 13:54:47 2010 @@ -1283,8 +1283,10 @@
    fsize:abi:pref
    This specifies the alignment for a floating point type of a given bit - size. The value of size must be either 32 (float) or 64 - (double).
    + size. Only values of size that are supported by the target + will work. 32 (float) and 64 (double) are supported on all targets; + 80 or 128 (different flavors of long double) are also supported on some + targets.
    asize:abi:pref
    This specifies the alignment for an aggregate type of a given bit From enderby at apple.com Fri May 28 14:01:28 2010 From: enderby at apple.com (Kevin Enderby) Date: Fri, 28 May 2010 19:01:28 -0000 Subject: [llvm-commits] [llvm] r104994 - in /llvm/trunk: lib/Target/X86/X86RegisterInfo.cpp test/MC/AsmParser/X86/x86_32-new-encoder.s Message-ID: <20100528190128.166F1312800A@llvm.org> Author: enderby Date: Fri May 28 14:01:27 2010 New Revision: 104994 URL: http://llvm.org/viewvc/llvm-project?rev=104994&view=rev Log: Fix the use of x86 control and debug registers so that the assertion failure in getX86RegNum() does not happen. Patch by Shantonu Sen! Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp?rev=104994&r1=104993&r2=104994&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Fri May 28 14:01:27 2010 @@ -157,6 +157,34 @@ case X86::GS: return 5; + case X86::CR0: + return 0; + case X86::CR1: + return 1; + case X86::CR2: + return 2; + case X86::CR3: + return 3; + case X86::CR4: + return 4; + + case X86::DR0: + return 0; + case X86::DR1: + return 1; + case X86::DR2: + return 2; + case X86::DR3: + return 3; + case X86::DR4: + return 4; + case X86::DR5: + return 5; + case X86::DR6: + return 6; + case X86::DR7: + return 7; + default: assert(isVirtualRegister(RegNo) && "Unknown physical register!"); llvm_unreachable("Register allocator hasn't allocated reg correctly yet!"); Modified: llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s?rev=104994&r1=104993&r2=104994&view=diff ============================================================================== --- llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s (original) +++ llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s Fri May 28 14:01:27 2010 @@ -331,3 +331,60 @@ // CHECK: movw (%eax), %cs // CHECK: encoding: [0x66,0x8e,0x08] movw (%eax), %cs + +// radr://8033374 +// CHECK: movl %cr0, %eax +// CHECK: encoding: [0x0f,0x20,0xc0] + movl %cr0,%eax + +// CHECK: movl %cr1, %eax +// CHECK: encoding: [0x0f,0x20,0xc8] + movl %cr1,%eax + +// CHECK: movl %cr2, %eax +// CHECK: encoding: [0x0f,0x20,0xd0] + movl %cr2,%eax + +// CHECK: movl %cr3, %eax +// CHECK: encoding: [0x0f,0x20,0xd8] + movl %cr3,%eax + +// CHECK: movl %cr4, %eax +// CHECK: encoding: [0x0f,0x20,0xe0] + movl %cr4,%eax + +// CHECK: movl %dr0, %eax +// CHECK: encoding: [0x0f,0x21,0xc0] + movl %dr0,%eax + +// CHECK: movl %dr1, %eax +// CHECK: encoding: [0x0f,0x21,0xc8] + movl %dr1,%eax + +// CHECK: movl %dr1, %eax +// CHECK: encoding: [0x0f,0x21,0xc8] + movl %dr1,%eax + +// CHECK: movl %dr2, %eax +// CHECK: encoding: [0x0f,0x21,0xd0] + movl %dr2,%eax + +// CHECK: movl %dr3, %eax +// CHECK: encoding: [0x0f,0x21,0xd8] + movl %dr3,%eax + +// CHECK: movl %dr4, %eax +// CHECK: encoding: [0x0f,0x21,0xe0] + movl %dr4,%eax + +// CHECK: movl %dr5, %eax +// CHECK: encoding: [0x0f,0x21,0xe8] + movl %dr5,%eax + +// CHECK: movl %dr6, %eax +// CHECK: encoding: [0x0f,0x21,0xf0] + movl %dr6,%eax + +// CHECK: movl %dr7, %eax +// CHECK: encoding: [0x0f,0x21,0xf8] + movl %dr7,%eax From criswell at uiuc.edu Fri May 28 14:09:07 2010 From: criswell at uiuc.edu (John Criswell) Date: Fri, 28 May 2010 19:09:07 -0000 Subject: [llvm-commits] [poolalloc] r104995 - /poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Message-ID: <20100528190907.A851B312800A@llvm.org> Author: criswell Date: Fri May 28 14:09:07 2010 New Revision: 104995 URL: http://llvm.org/viewvc/llvm-project?rev=104995&view=rev Log: Added comments. Improved some formatting. No functionality changes. Modified: poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Modified: poolalloc/trunk/lib/DSA/BottomUpClosure.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/BottomUpClosure.cpp?rev=104995&r1=104994&r2=104995&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/BottomUpClosure.cpp (original) +++ poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Fri May 28 14:09:07 2010 @@ -67,7 +67,9 @@ // callgraph.dump(); - //merge SCCs + // + // Merge the DSGraphs of functions belonging to an SCC. + // mergeSCCs(); //Post order traversal: @@ -102,6 +104,10 @@ // Mark external globals incomplete. GlobalsGraph->markIncompleteNodes(DSGraph::IgnoreGlobals); + // + // Create equivalence classes for aliasing globals so that we only need to + // record one global per DSNode. + // formGlobalECs(); // Merge the globals variables (not the calls) from the globals graph back @@ -122,6 +128,14 @@ return false; } +// +// Method: mergeSCCs() +// +// Description: +// For every Strongly Connected Component (SCC) in the callgraph, this method +// iterates through every function in the SCC and merges its DSGraph into a +// single DSGraph for the SCC. +// void BUDataStructures::mergeSCCs() { for (DSCallGraph::flat_key_iterator ii = callgraph.flat_key_begin(), @@ -154,6 +168,20 @@ } } +// +// Method: postOrder() +// +// Description: +// I have no idea. +// +// Inputs: +// F - The function on which to do whatever. +// marked - A reference to a set containing all values processed by +// previous invocation (this method is recursive). +// +// Outputs: +// marked - Updated to contain function F. +// DSGraph* BUDataStructures::postOrder(const Function* F, svset& marked) { callgraph.assertSCCRoot(F); @@ -204,20 +232,52 @@ } +// +// Method: CloneAuxIntoGlobal() +// +// Description: +// This method takes the specified graph and processes each unresolved call +// site (a call site for which all targets are not yet known). For each +// unresolved call site, it adds it to the globals graph and merges +// information about the call site if the globals graph already had the call +// site in its own list of unresolved call sites. +// void BUDataStructures::CloneAuxIntoGlobal(DSGraph* G) { DSGraph* GG = G->getGlobalsGraph(); ReachabilityCloner RC(GG, G, 0); - for(DSGraph::afc_iterator ii = G->afc_begin(), ee = G->afc_end(); - ii != ee; ++ii) { - //cerr << "Pushing " << ii->getCallSite().getInstruction()->getOperand(0) << "\n"; - //If we can, merge with an existing call site for this instruction - if (GG->hasNodeForValue(ii->getCallSite().getInstruction()->getOperand(0))) { + // + // Scan through all unresolved call sites (call sites for which we do not yet + // know all of the callees) in the specified graph and see if the globals + // graph also has an unresolved call site for the same function pointer. If + // it does, merge them together; otherwise, just bring the unresolved call + // site into the global graph's set of unresolved call sites. + // + for (DSGraph::afc_iterator ii = G->afc_begin(), ee = G->afc_end(); + ii != ee; + ++ii) { +#if 0 + cerr << "Pushing " << ii->getCallSite().getInstruction()->getOperand(0) << "\n"; +#endif + + // + // If we can, merge with an existing call site for this instruction. + // + if (GG->hasNodeForValue(ii->getCallSite().getCalledValue())) { + // + // Determine whether the globals graph knows about this call site and + // consider it to be unresolved. + // DSGraph::afc_iterator GGii; for(GGii = GG->afc_begin(); GGii != GG->afc_end(); ++GGii) - if (GGii->getCallSite().getInstruction()->getOperand(0) == - ii->getCallSite().getInstruction()->getOperand(0)) + if (GGii->getCallSite().getCalledValue() == + ii->getCallSite().getCalledValue()) break; + + // + // If the globals graph knows about the call site, merge it in. + // Otherwise, just record it as an unresolved call site. + // if (GGii != GG->afc_end()) RC.cloneCallSite(*ii).mergeWith(*GGii); else @@ -228,9 +288,11 @@ } } - -//Inline all graphs in the callgraph, remove callsites that are completely dealt -//with +// +// Description: +// Inline all graphs in the callgraph and remove callsites that are completely +// dealt with +// void BUDataStructures::calculateGraph(DSGraph* Graph) { DEBUG(Graph->AssertGraphOK(); Graph->getGlobalsGraph()->AssertGraphOK()); @@ -252,13 +314,18 @@ continue; } + // + // Find all called functions called by this call site. Remove from the + // list all calls to external functions (functions with no bodies). + // std::vector CalledFuncs; - //Get the callees from the callgraph { + // Get the callees from the callgraph std::copy(callgraph.callee_begin(CS.getCallSite()), callgraph.callee_end(CS.getCallSite()), std::back_inserter(CalledFuncs)); + // Remove calls to external functions std::vector::iterator ErasePoint = std::remove_if(CalledFuncs.begin(), CalledFuncs.end(), std::mem_fun(&Function::isDeclaration)); @@ -272,12 +339,12 @@ continue; } - //Direct calls are always inlined and removed from AuxCalls - //Indirect calls are removed if the callnode is complete and the callnode's - //functions set is a subset of the Calls from the callgraph - //We only inline from the callgraph (which is immutable during this phase - //of bu) so as to not introduce SCCs and still be able to inline - //aggressively + // Direct calls are always inlined and removed from AuxCalls + // Indirect calls are removed if the callnode is complete and the callnode's + // functions set is a subset of the Calls from the callgraph + // We only inline from the callgraph (which is immutable during this phase + // of bu) so as to not introduce SCCs and still be able to inline + // aggressively bool eraseCS = true; if (CS.isIndirectCall()) { eraseCS = false; @@ -310,6 +377,13 @@ << GI->getAuxFunctionCalls().size() << "] into '" << Graph->getFunctionNames() << "' [" << Graph->getGraphSize() <<"+" << Graph->getAuxFunctionCalls().size() << "]\n"); + + // + // Merge in the DSGraph of the called function. + // + // TODO: + // Why are the strip alloca bit and don't clone call nodes bit set? + // Graph->mergeInGraph(CS, *Callee, *GI, DSGraph::StripAllocaBit|DSGraph::DontCloneCallNodes); ++NumInlines; From eli.friedman at gmail.com Fri May 28 15:44:45 2010 From: eli.friedman at gmail.com (Eli Friedman) Date: Fri, 28 May 2010 13:44:45 -0700 Subject: [llvm-commits] patch for cocotron support in clang In-Reply-To: References: Message-ID: On Fri, May 28, 2010 at 5:23 AM, Tobias Platen wrote: > Hello, > I wrote a patch for clang to support the Cocotron Objective C runtime. > The Cocotron Runtime is similar to the GNU runtime but does not support > typed selectors. > Tobias Wrong mailing list; please send this to cfe-commits. -Eli From enderby at apple.com Fri May 28 15:59:10 2010 From: enderby at apple.com (Kevin Enderby) Date: Fri, 28 May 2010 20:59:10 -0000 Subject: [llvm-commits] [llvm] r105001 - in /llvm/trunk: lib/Target/X86/AsmParser/X86AsmParser.cpp test/MC/AsmParser/X86/x86_32-new-encoder.s Message-ID: <20100528205910.D9C08312800A@llvm.org> Author: enderby Date: Fri May 28 15:59:10 2010 New Revision: 105001 URL: http://llvm.org/viewvc/llvm-project?rev=105001&view=rev Log: MC/X86: Add alias for fwait. Modified: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s Modified: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp?rev=105001&r1=105000&r2=105001&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp (original) +++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp Fri May 28 15:59:10 2010 @@ -644,6 +644,7 @@ .Case("cmovnlel", "cmovgl") .Case("cmovnzl", "cmovnel") .Case("cmovzl", "cmovel") + .Case("fwait", "wait") .Default(Name); // FIXME: Hack to recognize cmp{ss,sd,ps,pd}. Modified: llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s?rev=105001&r1=105000&r2=105001&view=diff ============================================================================== --- llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s (original) +++ llvm/trunk/test/MC/AsmParser/X86/x86_32-new-encoder.s Fri May 28 15:59:10 2010 @@ -388,3 +388,8 @@ // CHECK: movl %dr7, %eax // CHECK: encoding: [0x0f,0x21,0xf8] movl %dr7,%eax + +// radr://8017522 +// CHECK: wait +// CHECK: encoding: [0x9b] + fwait From stoklund at 2pi.dk Fri May 28 16:14:01 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Fri, 28 May 2010 21:14:01 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r105003 - /llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Message-ID: <20100528211401.BE0B2312800A@llvm.org> Author: stoklund Date: Fri May 28 16:14:01 2010 New Revision: 105003 URL: http://llvm.org/viewvc/llvm-project?rev=105003&view=rev Log: Let LLVMTargetMachine decide which register allocator to use. Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=105003&r1=105002&r2=105003&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Fri May 28 16:14:01 2010 @@ -524,11 +524,6 @@ TheModule->setDataLayout(TheTarget->getTargetData()-> getStringRepresentation()); - if (optimize) - RegisterRegAlloc::setDefault(createLinearScanRegisterAllocator); - else - RegisterRegAlloc::setDefault(createLocalRegisterAllocator); - if (debug_info_level > DINFO_LEVEL_NONE) TheDebugInfo = new DebugInfo(TheModule); } From baldrick at free.fr Fri May 28 16:20:02 2010 From: baldrick at free.fr (Duncan Sands) Date: Fri, 28 May 2010 21:20:02 -0000 Subject: [llvm-commits] [dragonegg] r105004 - /dragonegg/trunk/llvm-backend.cpp Message-ID: <20100528212002.7A606312800A@llvm.org> Author: baldrick Date: Fri May 28 16:20:02 2010 New Revision: 105004 URL: http://llvm.org/viewvc/llvm-project?rev=105004&view=rev Log: Port commit 105003 (stoklund) from llvm-gcc: Let LLVMTargetMachine decide which register allocator to use. Modified: dragonegg/trunk/llvm-backend.cpp Modified: dragonegg/trunk/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-backend.cpp?rev=105004&r1=105003&r2=105004&view=diff ============================================================================== --- dragonegg/trunk/llvm-backend.cpp (original) +++ dragonegg/trunk/llvm-backend.cpp Fri May 28 16:20:02 2010 @@ -428,11 +428,6 @@ Args.push_back(0); // Null terminator. int pseudo_argc = Args.size()-1; llvm::cl::ParseCommandLineOptions(pseudo_argc, const_cast(&Args[0])); - - if (optimize) - RegisterRegAlloc::setDefault(createLinearScanRegisterAllocator); - else - RegisterRegAlloc::setDefault(createLocalRegisterAllocator); } /// ComputeTargetTriple - Determine the target triple to use. From enderby at apple.com Fri May 28 16:20:21 2010 From: enderby at apple.com (Kevin Enderby) Date: Fri, 28 May 2010 21:20:21 -0000 Subject: [llvm-commits] [llvm] r105005 - in /llvm/trunk: lib/Target/X86/AsmParser/X86AsmParser.cpp test/MC/AsmParser/X86/x86_64-new-encoder.s Message-ID: <20100528212021.A33BE312800A@llvm.org> Author: enderby Date: Fri May 28 16:20:21 2010 New Revision: 105005 URL: http://llvm.org/viewvc/llvm-project?rev=105005&view=rev Log: MC/X86: Add alias for movzx. Modified: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp llvm/trunk/test/MC/AsmParser/X86/x86_64-new-encoder.s Modified: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp?rev=105005&r1=105004&r2=105005&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp (original) +++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp Fri May 28 16:20:21 2010 @@ -645,6 +645,7 @@ .Case("cmovnzl", "cmovnel") .Case("cmovzl", "cmovel") .Case("fwait", "wait") + .Case("movzx", "movzb") .Default(Name); // FIXME: Hack to recognize cmp{ss,sd,ps,pd}. Modified: llvm/trunk/test/MC/AsmParser/X86/x86_64-new-encoder.s URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/X86/x86_64-new-encoder.s?rev=105005&r1=105004&r2=105005&view=diff ============================================================================== --- llvm/trunk/test/MC/AsmParser/X86/x86_64-new-encoder.s (original) +++ llvm/trunk/test/MC/AsmParser/X86/x86_64-new-encoder.s Fri May 28 16:20:21 2010 @@ -131,3 +131,16 @@ btq $0x01,%rdx // CHECK: btq $1, %rdx // CHECK: encoding: [0x48,0x0f,0xba,0xe2,0x01] + +//rdar://8017633 +// CHECK: movzbl %al, %esi +// CHECK: encoding: [0x0f,0xb6,0xf0] + movzx %al, %esi + +// CHECK: movzbq %al, %rsi +// CHECK: encoding: [0x48,0x0f,0xb6,0xf0] + movzx %al, %rsi + +// CHECK: movzbq (%rsp), %rsi +// CHECK: encoding: [0x48,0x0f,0xb6,0x34,0x24] + movzx 0(%rsp), %rsi From gohman at apple.com Fri May 28 16:22:45 2010 From: gohman at apple.com (Dan Gohman) Date: Fri, 28 May 2010 21:22:45 -0000 Subject: [llvm-commits] [llvm] r105006 - /llvm/trunk/include/llvm/InstrTypes.h Message-ID: <20100528212245.9D11C312800A@llvm.org> Author: djg Date: Fri May 28 16:22:45 2010 New Revision: 105006 URL: http://llvm.org/viewvc/llvm-project?rev=105006&view=rev Log: Fix a comment; vectors are not a special case here. Modified: llvm/trunk/include/llvm/InstrTypes.h Modified: llvm/trunk/include/llvm/InstrTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InstrTypes.h?rev=105006&r1=105005&r2=105006&view=diff ============================================================================== --- llvm/trunk/include/llvm/InstrTypes.h (original) +++ llvm/trunk/include/llvm/InstrTypes.h Fri May 28 16:22:45 2010 @@ -612,7 +612,7 @@ /// A lossless cast is one that does not alter the basic value. It implies /// a no-op cast but is more stringent, preventing things like int->float, - /// long->double, int->ptr, or vector->anything. + /// long->double, or int->ptr. /// @returns true iff the cast is lossless. /// @brief Determine if this is a lossless cast. bool isLosslessCast() const; From gohman at apple.com Fri May 28 16:41:37 2010 From: gohman at apple.com (Dan Gohman) Date: Fri, 28 May 2010 21:41:37 -0000 Subject: [llvm-commits] [llvm] r105008 - in /llvm/trunk: include/llvm/InstrTypes.h lib/VMCore/Instructions.cpp Message-ID: <20100528214138.10AF1312800A@llvm.org> Author: djg Date: Fri May 28 16:41:37 2010 New Revision: 105008 URL: http://llvm.org/viewvc/llvm-project?rev=105008&view=rev Log: Split the logic behind CastInst::isNoopCast into a separate static function, as is done with most other cast opcode predicates. Modified: llvm/trunk/include/llvm/InstrTypes.h llvm/trunk/lib/VMCore/Instructions.cpp Modified: llvm/trunk/include/llvm/InstrTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InstrTypes.h?rev=105008&r1=105007&r2=105008&view=diff ============================================================================== --- llvm/trunk/include/llvm/InstrTypes.h (original) +++ llvm/trunk/include/llvm/InstrTypes.h Fri May 28 16:41:37 2010 @@ -625,6 +625,14 @@ /// platform. Generally, the result of TargetData::getIntPtrType() should be /// passed in. If that's not available, use Type::Int64Ty, which will make /// the isNoopCast call conservative. + /// @brief Determine if the described cast is a no-op cast. + static bool isNoopCast( + Instruction::CastOps Opcode, ///< Opcode of cast + const Type *SrcTy, ///< SrcTy of cast + const Type *DstTy, ///< DstTy of cast + const Type *IntPtrTy ///< Integer type corresponding to Ptr types, or null + ); + /// @brief Determine if this cast is a no-op cast. bool isNoopCast( const Type *IntPtrTy ///< Integer type corresponding to pointer Modified: llvm/trunk/lib/VMCore/Instructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=105008&r1=105007&r2=105008&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instructions.cpp (original) +++ llvm/trunk/lib/VMCore/Instructions.cpp Fri May 28 16:41:37 2010 @@ -1911,9 +1911,12 @@ /// # bitcast i32* %x to i8* /// # bitcast <2 x i32> %x to <4 x i16> /// # ptrtoint i32* %x to i32 ; on 32-bit plaforms only -/// @brief Determine if a cast is a no-op. -bool CastInst::isNoopCast(const Type *IntPtrTy) const { - switch (getOpcode()) { +/// @brief Determine if the described cast is a no-op. +bool CastInst::isNoopCast(Instruction::CastOps Opcode, + const Type *SrcTy, + const Type *DestTy, + const Type *IntPtrTy) { + switch (Opcode) { default: assert(!"Invalid CastOp"); case Instruction::Trunc: @@ -1930,13 +1933,18 @@ return true; // BitCast never modifies bits. case Instruction::PtrToInt: return IntPtrTy->getScalarSizeInBits() == - getType()->getScalarSizeInBits(); + DestTy->getScalarSizeInBits(); case Instruction::IntToPtr: return IntPtrTy->getScalarSizeInBits() == - getOperand(0)->getType()->getScalarSizeInBits(); + SrcTy->getScalarSizeInBits(); } } +/// @brief Determine if a cast is a no-op. +bool CastInst::isNoopCast(const Type *IntPtrTy) const { + return isNoopCast(getOpcode(), getOperand(0)->getType(), getType(), IntPtrTy); +} + /// This function determines if a pair of casts can be eliminated and what /// opcode should be used in the elimination. This assumes that there are two /// instructions like this: From gohman at apple.com Fri May 28 16:43:58 2010 From: gohman at apple.com (Dan Gohman) Date: Fri, 28 May 2010 21:43:58 -0000 Subject: [llvm-commits] [llvm] r105009 - in /llvm/trunk: lib/Analysis/Lint.cpp test/Other/lint.ll Message-ID: <20100528214358.2527C312800A@llvm.org> Author: djg Date: Fri May 28 16:43:57 2010 New Revision: 105009 URL: http://llvm.org/viewvc/llvm-project?rev=105009&view=rev Log: Add lint checks for function attributes. Modified: llvm/trunk/lib/Analysis/Lint.cpp llvm/trunk/test/Other/lint.ll Modified: llvm/trunk/lib/Analysis/Lint.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/Lint.cpp?rev=105009&r1=105008&r2=105009&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/Lint.cpp (original) +++ llvm/trunk/lib/Analysis/Lint.cpp Fri May 28 16:43:57 2010 @@ -68,7 +68,8 @@ void visitFunction(Function &F); void visitCallSite(CallSite CS); - void visitMemoryReference(Instruction &I, Value *Ptr, unsigned Align, + void visitMemoryReference(Instruction &I, Value *Ptr, + unsigned Size, unsigned Align, const Type *Ty, unsigned Flags); void visitCallInst(CallInst &I); @@ -205,7 +206,7 @@ Instruction &I = *CS.getInstruction(); Value *Callee = CS.getCalledValue(); - visitMemoryReference(I, Callee, 0, 0, MemRef::Callee); + visitMemoryReference(I, Callee, ~0u, 0, 0, MemRef::Callee); if (Function *F = dyn_cast(findValue(Callee, /*OffsetOk=*/false))) { Assert1(CS.getCallingConv() == F->getCallingConv(), @@ -214,20 +215,45 @@ const FunctionType *FT = F->getFunctionType(); unsigned NumActualArgs = unsigned(CS.arg_end()-CS.arg_begin()); + std::vector NoAliasVals; Assert1(FT->isVarArg() ? FT->getNumParams() <= NumActualArgs : FT->getNumParams() == NumActualArgs, "Undefined behavior: Call argument count mismatches callee " "argument count", &I); - - // TODO: Check argument types (in case the callee was casted) - // TODO: Check ABI-significant attributes. - - // TODO: Check noalias attribute. + // Check argument types (in case the callee was casted) and attributes. + Function::arg_iterator PI = F->arg_begin(), PE = F->arg_end(); + CallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end(); + for (; AI != AE; ++AI) { + Value *Actual = *AI; + if (PI != PE) { + Argument *Formal = PI++; + Assert1(Formal->getType() == Actual->getType(), + "Undefined behavior: Call argument type mismatches " + "callee parameter type", &I); + if (Formal->hasNoAliasAttr() && Actual->getType()->isPointerTy()) + NoAliasVals.push_back(Actual); + if (Formal->hasStructRetAttr() && Actual->getType()->isPointerTy()) { + const Type *Ty = + cast(Formal->getType())->getElementType(); + visitMemoryReference(I, Actual, AA->getTypeStoreSize(Ty), + TD ? TD->getABITypeAlignment(Ty) : 0, + Ty, MemRef::Read | MemRef::Write); + } + } + } - // TODO: Check sret attribute. + // Check that the noalias arguments don't overlap. The AliasAnalysis API + // isn't expressive enough for what we really want to do. Known partial + // overlap is not distinguished from the case where nothing is known. + for (CallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end(); + AI != AE; ++AI) + for (std::vector::iterator J = NoAliasVals.begin(), + E = NoAliasVals.end(); J != E; ++J) + Assert1(AA->alias(*J, ~0u, *AI, ~0u) != AliasAnalysis::MustAlias, + "Unusual: noalias argument aliases another argument", &I); } if (CS.isCall() && cast(CS.getInstruction())->isTailCall()) @@ -248,9 +274,10 @@ case Intrinsic::memcpy: { MemCpyInst *MCI = cast(&I); - visitMemoryReference(I, MCI->getDest(), MCI->getAlignment(), 0, + // TODO: If the size is known, use it. + visitMemoryReference(I, MCI->getDest(), ~0u, MCI->getAlignment(), 0, MemRef::Write); - visitMemoryReference(I, MCI->getSource(), MCI->getAlignment(), 0, + visitMemoryReference(I, MCI->getSource(), ~0u, MCI->getAlignment(), 0, MemRef::Read); // Check that the memcpy arguments don't overlap. The AliasAnalysis API @@ -269,15 +296,17 @@ } case Intrinsic::memmove: { MemMoveInst *MMI = cast(&I); - visitMemoryReference(I, MMI->getDest(), MMI->getAlignment(), 0, + // TODO: If the size is known, use it. + visitMemoryReference(I, MMI->getDest(), ~0u, MMI->getAlignment(), 0, MemRef::Write); - visitMemoryReference(I, MMI->getSource(), MMI->getAlignment(), 0, + visitMemoryReference(I, MMI->getSource(), ~0u, MMI->getAlignment(), 0, MemRef::Read); break; } case Intrinsic::memset: { MemSetInst *MSI = cast(&I); - visitMemoryReference(I, MSI->getDest(), MSI->getAlignment(), 0, + // TODO: If the size is known, use it. + visitMemoryReference(I, MSI->getDest(), ~0u, MSI->getAlignment(), 0, MemRef::Write); break; } @@ -287,15 +316,15 @@ "Undefined behavior: va_start called in a non-varargs function", &I); - visitMemoryReference(I, CS.getArgument(0), 0, 0, + visitMemoryReference(I, CS.getArgument(0), ~0u, 0, 0, MemRef::Read | MemRef::Write); break; case Intrinsic::vacopy: - visitMemoryReference(I, CS.getArgument(0), 0, 0, MemRef::Write); - visitMemoryReference(I, CS.getArgument(1), 0, 0, MemRef::Read); + visitMemoryReference(I, CS.getArgument(0), ~0u, 0, 0, MemRef::Write); + visitMemoryReference(I, CS.getArgument(1), ~0u, 0, 0, MemRef::Read); break; case Intrinsic::vaend: - visitMemoryReference(I, CS.getArgument(0), 0, 0, + visitMemoryReference(I, CS.getArgument(0), ~0u, 0, 0, MemRef::Read | MemRef::Write); break; @@ -303,7 +332,7 @@ // Stackrestore doesn't read or write memory, but it sets the // stack pointer, which the compiler may read from or write to // at any time, so check it for both readability and writeability. - visitMemoryReference(I, CS.getArgument(0), 0, 0, + visitMemoryReference(I, CS.getArgument(0), ~0u, 0, 0, MemRef::Read | MemRef::Write); break; } @@ -330,15 +359,26 @@ } } -// TODO: Add a length argument and check that the reference is in bounds +// TODO: Check that the reference is in bounds. void Lint::visitMemoryReference(Instruction &I, - Value *Ptr, unsigned Align, const Type *Ty, - unsigned Flags) { + Value *Ptr, unsigned Size, unsigned Align, + const Type *Ty, unsigned Flags) { + // If no memory is being referenced, it doesn't matter if the pointer + // is valid. + if (Size == 0) + return; + Value *UnderlyingObject = findValue(Ptr, /*OffsetOk=*/true); Assert1(!isa(UnderlyingObject), "Undefined behavior: Null pointer dereference", &I); Assert1(!isa(UnderlyingObject), "Undefined behavior: Undef pointer dereference", &I); + Assert1(!isa(UnderlyingObject) || + !cast(UnderlyingObject)->isAllOnesValue(), + "Unusual: All-ones pointer dereference", &I); + Assert1(!isa(UnderlyingObject) || + !cast(UnderlyingObject)->isOne(), + "Unusual: Address one pointer dereference", &I); if (Flags & MemRef::Write) { if (const GlobalVariable *GV = dyn_cast(UnderlyingObject)) @@ -379,13 +419,16 @@ } void Lint::visitLoadInst(LoadInst &I) { - visitMemoryReference(I, I.getPointerOperand(), I.getAlignment(), I.getType(), - MemRef::Read); + visitMemoryReference(I, I.getPointerOperand(), + AA->getTypeStoreSize(I.getType()), I.getAlignment(), + I.getType(), MemRef::Read); } void Lint::visitStoreInst(StoreInst &I) { - visitMemoryReference(I, I.getPointerOperand(), I.getAlignment(), - I.getOperand(0)->getType(), MemRef::Write); + visitMemoryReference(I, I.getPointerOperand(), + AA->getTypeStoreSize(I.getOperand(0)->getType()), + I.getAlignment(), + I.getOperand(0)->getType(), MemRef::Write); } void Lint::visitXor(BinaryOperator &I) { @@ -460,12 +503,12 @@ } void Lint::visitVAArgInst(VAArgInst &I) { - visitMemoryReference(I, I.getOperand(0), 0, 0, + visitMemoryReference(I, I.getOperand(0), ~0u, 0, 0, MemRef::Read | MemRef::Write); } void Lint::visitIndirectBrInst(IndirectBrInst &I) { - visitMemoryReference(I, I.getAddress(), 0, 0, MemRef::Branchee); + visitMemoryReference(I, I.getAddress(), ~0u, 0, 0, MemRef::Branchee); } void Lint::visitExtractElementInst(ExtractElementInst &I) { @@ -513,6 +556,7 @@ // TODO: Look through sext or zext cast, when the result is known to // be interpreted as signed or unsigned, respectively. + // TODO: Look through eliminable cast pairs. // TODO: Look through calls with unique return values. // TODO: Look through vector insert/extract/shuffle. V = OffsetOk ? V->getUnderlyingObject() : V->stripPointerCasts(); @@ -530,19 +574,36 @@ if (!BB) break; BBI = BB->end(); } + } else if (PHINode *PN = dyn_cast(V)) { + if (Value *W = PN->hasConstantValue(DT)) + return findValueImpl(W, OffsetOk, Visited); } else if (CastInst *CI = dyn_cast(V)) { if (CI->isNoopCast(TD ? TD->getIntPtrType(V->getContext()) : Type::getInt64Ty(V->getContext()))) return findValueImpl(CI->getOperand(0), OffsetOk, Visited); - } else if (PHINode *PN = dyn_cast(V)) { - if (Value *W = PN->hasConstantValue(DT)) - return findValueImpl(W, OffsetOk, Visited); } else if (ExtractValueInst *Ex = dyn_cast(V)) { if (Value *W = FindInsertedValue(Ex->getAggregateOperand(), Ex->idx_begin(), Ex->idx_end())) if (W != V) return findValueImpl(W, OffsetOk, Visited); + } else if (ConstantExpr *CE = dyn_cast(V)) { + // Same as above, but for ConstantExpr instead of Instruction. + if (Instruction::isCast(CE->getOpcode())) { + if (CastInst::isNoopCast(Instruction::CastOps(CE->getOpcode()), + CE->getOperand(0)->getType(), + CE->getType(), + TD ? TD->getIntPtrType(V->getContext()) : + Type::getInt64Ty(V->getContext()))) + return findValueImpl(CE->getOperand(0), OffsetOk, Visited); + } else if (CE->getOpcode() == Instruction::ExtractValue) { + const SmallVector &Indices = CE->getIndices(); + if (Value *W = FindInsertedValue(CE->getOperand(0), + Indices.begin(), + Indices.end())) + if (W != V) + return findValueImpl(W, OffsetOk, Visited); + } } // As a last resort, try SimplifyInstruction or constant folding. Modified: llvm/trunk/test/Other/lint.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/lint.ll?rev=105009&r1=105008&r2=105009&view=diff ============================================================================== --- llvm/trunk/test/Other/lint.ll (original) +++ llvm/trunk/test/Other/lint.ll Fri May 28 16:43:57 2010 @@ -4,6 +4,9 @@ declare fastcc void @bar() declare void @llvm.stackrestore(i8*) declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind +declare void @has_sret(i8* sret %p) +declare void @has_noaliases(i32* noalias %p, i32* %q) +declare void @one_arg(i32) @CG = constant i32 7 @@ -18,6 +21,10 @@ store i32 0, i32* undef ; CHECK: Undef pointer dereference %u = load i32* undef +; CHECK: All-ones pointer dereference + store i32 0, i32* inttoptr (i64 -1 to i32*) +; CHECK: Address one pointer dereference + store i32 0, i32* inttoptr (i64 1 to i32*) ; CHECK: Memory reference address is misaligned %x = inttoptr i32 1 to i32* load i32* %x, align 4 @@ -54,6 +61,16 @@ call void()* bitcast (i8* blockaddress(@foo, %next) to void()*)() ; CHECK: Undefined behavior: Null pointer dereference call void @llvm.stackrestore(i8* null) +; CHECK: Undefined behavior: Null pointer dereference + call void @has_sret(i8* null) +; CHECK: Unusual: noalias argument aliases another argument + call void @has_noaliases(i32* @CG, i32* @CG) +; CHECK: Call argument count mismatches callee argument count + call void (i32, i32)* bitcast (void (i32)* @one_arg to void (i32, i32)*)(i32 0, i32 0) +; CHECK: Call argument count mismatches callee argument count + call void ()* bitcast (void (i32)* @one_arg to void ()*)() +; CHECK: Call argument type mismatches callee parameter type + call void (float)* bitcast (void (i32)* @one_arg to void (float)*)(float 0.0) ; CHECK: Write to read-only memory call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast (i32* @CG to i8*), i8* bitcast (i32* @CG to i8*), i64 1, i32 1, i1 0) From gohman at apple.com Fri May 28 17:31:51 2010 From: gohman at apple.com (Dan Gohman) Date: Fri, 28 May 2010 22:31:51 -0000 Subject: [llvm-commits] [llvm] r105012 - /llvm/trunk/lib/Analysis/AliasDebugger.cpp Message-ID: <20100528223151.8F20D312800A@llvm.org> Author: djg Date: Fri May 28 17:31:51 2010 New Revision: 105012 URL: http://llvm.org/viewvc/llvm-project?rev=105012&view=rev Log: Fix AliasDebugger to be aware of operand values too. Modified: llvm/trunk/lib/Analysis/AliasDebugger.cpp Modified: llvm/trunk/lib/Analysis/AliasDebugger.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/AliasDebugger.cpp?rev=105012&r1=105011&r2=105012&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/AliasDebugger.cpp (original) +++ llvm/trunk/lib/Analysis/AliasDebugger.cpp Fri May 28 17:31:51 2010 @@ -45,8 +45,12 @@ InitializeAliasAnalysis(this); // set up super class for(Module::global_iterator I = M.global_begin(), - E = M.global_end(); I != E; ++I) + E = M.global_end(); I != E; ++I) { Vals.insert(&*I); + for (User::const_op_iterator OI = I->op_begin(), + OE = I->op_end(); OI != OE; ++OI) + Vals.insert(*OI); + } for(Module::iterator I = M.begin(), E = M.end(); I != E; ++I){ @@ -58,8 +62,12 @@ for (Function::const_iterator FI = I->begin(), FE = I->end(); FI != FE; ++FI) for (BasicBlock::const_iterator BI = FI->begin(), BE = FI->end(); - BI != BE; ++BI) + BI != BE; ++BI) { Vals.insert(&*BI); + for (User::const_op_iterator OI = BI->op_begin(), + OE = BI->op_end(); OI != OE; ++OI) + Vals.insert(*OI); + } } } From bruno.cardoso at gmail.com Fri May 28 17:47:03 2010 From: bruno.cardoso at gmail.com (Bruno Cardoso Lopes) Date: Fri, 28 May 2010 22:47:03 -0000 Subject: [llvm-commits] [llvm] r105014 - /llvm/trunk/lib/Target/X86/X86InstrSSE.td Message-ID: <20100528224703.E87A83128018@llvm.org> Author: bruno Date: Fri May 28 17:47:03 2010 New Revision: 105014 URL: http://llvm.org/viewvc/llvm-project?rev=105014&view=rev Log: More SSE 1 & 2 merge, this time with logical instructions Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=105014&r1=105013&r2=105014&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Fri May 28 17:47:03 2010 @@ -598,48 +598,52 @@ "movaps\t{$src, $dst|$dst, $src}", [(set FR32:$dst, (alignedloadfsf32 addr:$src))]>; +/// sse12_fp_alias_pack_logical - SSE 1 & 2 aliased packed FP logical ops +/// +multiclass sse12_fp_alias_pack_logical opc, string OpcodeStr, + SDNode OpNode, int NoPat = 0, + bit MayLoad = 0, bit Commutable = 1> { + def PSrr : PSI, + [(set FR32:$dst, (OpNode FR32:$src1, FR32:$src2))])> { + let isCommutable = Commutable; + } + + def PDrr : PDI, + [(set FR64:$dst, (OpNode FR64:$src1, FR64:$src2))])> { + let isCommutable = Commutable; + } + + def PSrm : PSI, + [(set FR32:$dst, (OpNode FR32:$src1, + (memopfsf32 addr:$src2)))])> { + let mayLoad = MayLoad; + } + + def PDrm : PDI, + [(set FR64:$dst, (OpNode FR64:$src1, + (memopfsf64 addr:$src2)))])> { + let mayLoad = MayLoad; + } +} + // Alias bitwise logical operations using SSE logical ops on packed FP values. let Constraints = "$src1 = $dst" in { -let isCommutable = 1 in { - def FsANDPSrr : PSI<0x54, MRMSrcReg, (outs FR32:$dst), - (ins FR32:$src1, FR32:$src2), - "andps\t{$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (X86fand FR32:$src1, FR32:$src2))]>; - def FsORPSrr : PSI<0x56, MRMSrcReg, (outs FR32:$dst), - (ins FR32:$src1, FR32:$src2), - "orps\t{$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (X86for FR32:$src1, FR32:$src2))]>; - def FsXORPSrr : PSI<0x57, MRMSrcReg, (outs FR32:$dst), - (ins FR32:$src1, FR32:$src2), - "xorps\t{$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (X86fxor FR32:$src1, FR32:$src2))]>; -} - -def FsANDPSrm : PSI<0x54, MRMSrcMem, (outs FR32:$dst), - (ins FR32:$src1, f128mem:$src2), - "andps\t{$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (X86fand FR32:$src1, - (memopfsf32 addr:$src2)))]>; -def FsORPSrm : PSI<0x56, MRMSrcMem, (outs FR32:$dst), - (ins FR32:$src1, f128mem:$src2), - "orps\t{$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (X86for FR32:$src1, - (memopfsf32 addr:$src2)))]>; -def FsXORPSrm : PSI<0x57, MRMSrcMem, (outs FR32:$dst), - (ins FR32:$src1, f128mem:$src2), - "xorps\t{$src2, $dst|$dst, $src2}", - [(set FR32:$dst, (X86fxor FR32:$src1, - (memopfsf32 addr:$src2)))]>; - -let neverHasSideEffects = 1 in { -def FsANDNPSrr : PSI<0x55, MRMSrcReg, - (outs FR32:$dst), (ins FR32:$src1, FR32:$src2), - "andnps\t{$src2, $dst|$dst, $src2}", []>; -let mayLoad = 1 in -def FsANDNPSrm : PSI<0x55, MRMSrcMem, - (outs FR32:$dst), (ins FR32:$src1, f128mem:$src2), - "andnps\t{$src2, $dst|$dst, $src2}", []>; -} + defm FsAND : sse12_fp_alias_pack_logical<0x54, "and", X86fand>; + defm FsOR : sse12_fp_alias_pack_logical<0x56, "or", X86for>; + defm FsXOR : sse12_fp_alias_pack_logical<0x57, "xor", X86fxor>; + + let neverHasSideEffects = 1 in + defm FsANDN : sse12_fp_alias_pack_logical<0x55, "andn", undef, 1, 1, 0>; } /// basic_sse12_fp_binop_rm - SSE 1 & 2 binops come in both scalar and @@ -1067,55 +1071,63 @@ defm RCP : sse1_fp_unop_rm<0x53, "rcp", X86frcp, int_x86_sse_rcp_ss, int_x86_sse_rcp_ps>; +/// sse12_fp_pack_logical - SSE 1 & 2 packed FP logical ops +/// +multiclass sse12_fp_pack_logical opc, string OpcodeStr, + SDNode OpNode, int HasPat = 0, + bit Commutable = 1, + list> Pattern = []> { + def PSrr : PSI + { let isCommutable = Commutable; } + + def PDrr : PDI + { let isCommutable = Commutable; } + + def PSrm : PSI; + + def PDrm : PDI; +} + // Logical let Constraints = "$src1 = $dst" in { - let isCommutable = 1 in { - def ANDPSrr : PSI<0x54, MRMSrcReg, - (outs VR128:$dst), (ins VR128:$src1, VR128:$src2), - "andps\t{$src2, $dst|$dst, $src2}", - [(set VR128:$dst, (v2i64 - (and VR128:$src1, VR128:$src2)))]>; - def ORPSrr : PSI<0x56, MRMSrcReg, - (outs VR128:$dst), (ins VR128:$src1, VR128:$src2), - "orps\t{$src2, $dst|$dst, $src2}", - [(set VR128:$dst, (v2i64 - (or VR128:$src1, VR128:$src2)))]>; - def XORPSrr : PSI<0x57, MRMSrcReg, - (outs VR128:$dst), (ins VR128:$src1, VR128:$src2), - "xorps\t{$src2, $dst|$dst, $src2}", - [(set VR128:$dst, (v2i64 - (xor VR128:$src1, VR128:$src2)))]>; - } - - def ANDPSrm : PSI<0x54, MRMSrcMem, - (outs VR128:$dst), (ins VR128:$src1, f128mem:$src2), - "andps\t{$src2, $dst|$dst, $src2}", - [(set VR128:$dst, (and (bc_v2i64 (v4f32 VR128:$src1)), - (memopv2i64 addr:$src2)))]>; - def ORPSrm : PSI<0x56, MRMSrcMem, - (outs VR128:$dst), (ins VR128:$src1, f128mem:$src2), - "orps\t{$src2, $dst|$dst, $src2}", - [(set VR128:$dst, (or (bc_v2i64 (v4f32 VR128:$src1)), - (memopv2i64 addr:$src2)))]>; - def XORPSrm : PSI<0x57, MRMSrcMem, - (outs VR128:$dst), (ins VR128:$src1, f128mem:$src2), - "xorps\t{$src2, $dst|$dst, $src2}", - [(set VR128:$dst, (xor (bc_v2i64 (v4f32 VR128:$src1)), - (memopv2i64 addr:$src2)))]>; - def ANDNPSrr : PSI<0x55, MRMSrcReg, - (outs VR128:$dst), (ins VR128:$src1, VR128:$src2), - "andnps\t{$src2, $dst|$dst, $src2}", - [(set VR128:$dst, - (v2i64 (and (xor VR128:$src1, - (bc_v2i64 (v4i32 immAllOnesV))), - VR128:$src2)))]>; - def ANDNPSrm : PSI<0x55, MRMSrcMem, - (outs VR128:$dst), (ins VR128:$src1,f128mem:$src2), - "andnps\t{$src2, $dst|$dst, $src2}", - [(set VR128:$dst, - (v2i64 (and (xor (bc_v2i64 (v4f32 VR128:$src1)), - (bc_v2i64 (v4i32 immAllOnesV))), - (memopv2i64 addr:$src2))))]>; + defm AND : sse12_fp_pack_logical<0x54, "and", and>; + defm OR : sse12_fp_pack_logical<0x56, "or", or>; + defm XOR : sse12_fp_pack_logical<0x57, "xor", xor>; + defm ANDN : sse12_fp_pack_logical<0x55, "andn", undef /* dummy */, 1, 0, [ + // single r+r + [(set VR128:$dst, (v2i64 (and (xor VR128:$src1, + (bc_v2i64 (v4i32 immAllOnesV))), + VR128:$src2)))], + // double r+r + [(set VR128:$dst, (and (vnot (bc_v2i64 (v2f64 VR128:$src1))), + (bc_v2i64 (v2f64 VR128:$src2))))], + // single r+m + [(set VR128:$dst, (v2i64 (and (xor (bc_v2i64 (v4f32 VR128:$src1)), + (bc_v2i64 (v4i32 immAllOnesV))), + (memopv2i64 addr:$src2))))], + // double r+m + [(set VR128:$dst, (and (vnot (bc_v2i64 (v2f64 VR128:$src1))), + (memopv2i64 addr:$src2)))]]>; } let Constraints = "$src1 = $dst" in { @@ -1509,50 +1521,6 @@ "movapd\t{$src, $dst|$dst, $src}", [(set FR64:$dst, (alignedloadfsf64 addr:$src))]>; -// Alias bitwise logical operations using SSE logical ops on packed FP values. -let Constraints = "$src1 = $dst" in { -let isCommutable = 1 in { - def FsANDPDrr : PDI<0x54, MRMSrcReg, (outs FR64:$dst), - (ins FR64:$src1, FR64:$src2), - "andpd\t{$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (X86fand FR64:$src1, FR64:$src2))]>; - def FsORPDrr : PDI<0x56, MRMSrcReg, (outs FR64:$dst), - (ins FR64:$src1, FR64:$src2), - "orpd\t{$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (X86for FR64:$src1, FR64:$src2))]>; - def FsXORPDrr : PDI<0x57, MRMSrcReg, (outs FR64:$dst), - (ins FR64:$src1, FR64:$src2), - "xorpd\t{$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (X86fxor FR64:$src1, FR64:$src2))]>; -} - -def FsANDPDrm : PDI<0x54, MRMSrcMem, (outs FR64:$dst), - (ins FR64:$src1, f128mem:$src2), - "andpd\t{$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (X86fand FR64:$src1, - (memopfsf64 addr:$src2)))]>; -def FsORPDrm : PDI<0x56, MRMSrcMem, (outs FR64:$dst), - (ins FR64:$src1, f128mem:$src2), - "orpd\t{$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (X86for FR64:$src1, - (memopfsf64 addr:$src2)))]>; -def FsXORPDrm : PDI<0x57, MRMSrcMem, (outs FR64:$dst), - (ins FR64:$src1, f128mem:$src2), - "xorpd\t{$src2, $dst|$dst, $src2}", - [(set FR64:$dst, (X86fxor FR64:$src1, - (memopfsf64 addr:$src2)))]>; - -let neverHasSideEffects = 1 in { -def FsANDNPDrr : PDI<0x55, MRMSrcReg, - (outs FR64:$dst), (ins FR64:$src1, FR64:$src2), - "andnpd\t{$src2, $dst|$dst, $src2}", []>; -let mayLoad = 1 in -def FsANDNPDrm : PDI<0x55, MRMSrcMem, - (outs FR64:$dst), (ins FR64:$src1, f128mem:$src2), - "andnpd\t{$src2, $dst|$dst, $src2}", []>; -} -} - //===---------------------------------------------------------------------===// // SSE packed FP Instructions @@ -1824,61 +1792,6 @@ // There is no f64 version of the reciprocal approximation instructions. -// Logical -let Constraints = "$src1 = $dst" in { - let isCommutable = 1 in { - def ANDPDrr : PDI<0x54, MRMSrcReg, - (outs VR128:$dst), (ins VR128:$src1, VR128:$src2), - "andpd\t{$src2, $dst|$dst, $src2}", - [(set VR128:$dst, - (and (bc_v2i64 (v2f64 VR128:$src1)), - (bc_v2i64 (v2f64 VR128:$src2))))]>; - def ORPDrr : PDI<0x56, MRMSrcReg, - (outs VR128:$dst), (ins VR128:$src1, VR128:$src2), - "orpd\t{$src2, $dst|$dst, $src2}", - [(set VR128:$dst, - (or (bc_v2i64 (v2f64 VR128:$src1)), - (bc_v2i64 (v2f64 VR128:$src2))))]>; - def XORPDrr : PDI<0x57, MRMSrcReg, - (outs VR128:$dst), (ins VR128:$src1, VR128:$src2), - "xorpd\t{$src2, $dst|$dst, $src2}", - [(set VR128:$dst, - (xor (bc_v2i64 (v2f64 VR128:$src1)), - (bc_v2i64 (v2f64 VR128:$src2))))]>; - } - - def ANDPDrm : PDI<0x54, MRMSrcMem, - (outs VR128:$dst), (ins VR128:$src1, f128mem:$src2), - "andpd\t{$src2, $dst|$dst, $src2}", - [(set VR128:$dst, - (and (bc_v2i64 (v2f64 VR128:$src1)), - (memopv2i64 addr:$src2)))]>; - def ORPDrm : PDI<0x56, MRMSrcMem, - (outs VR128:$dst), (ins VR128:$src1, f128mem:$src2), - "orpd\t{$src2, $dst|$dst, $src2}", - [(set VR128:$dst, - (or (bc_v2i64 (v2f64 VR128:$src1)), - (memopv2i64 addr:$src2)))]>; - def XORPDrm : PDI<0x57, MRMSrcMem, - (outs VR128:$dst), (ins VR128:$src1, f128mem:$src2), - "xorpd\t{$src2, $dst|$dst, $src2}", - [(set VR128:$dst, - (xor (bc_v2i64 (v2f64 VR128:$src1)), - (memopv2i64 addr:$src2)))]>; - def ANDNPDrr : PDI<0x55, MRMSrcReg, - (outs VR128:$dst), (ins VR128:$src1, VR128:$src2), - "andnpd\t{$src2, $dst|$dst, $src2}", - [(set VR128:$dst, - (and (vnot (bc_v2i64 (v2f64 VR128:$src1))), - (bc_v2i64 (v2f64 VR128:$src2))))]>; - def ANDNPDrm : PDI<0x55, MRMSrcMem, - (outs VR128:$dst), (ins VR128:$src1,f128mem:$src2), - "andnpd\t{$src2, $dst|$dst, $src2}", - [(set VR128:$dst, - (and (vnot (bc_v2i64 (v2f64 VR128:$src1))), - (memopv2i64 addr:$src2)))]>; -} - let Constraints = "$src1 = $dst" in { def CMPPDrri : PDIi8<0xC2, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, VR128:$src, SSECC:$cc), From gohman at apple.com Fri May 28 18:00:20 2010 From: gohman at apple.com (Dan Gohman) Date: Fri, 28 May 2010 23:00:20 -0000 Subject: [llvm-commits] [test-suite] r105015 - /test-suite/trunk/MultiSource/Applications/aha/aha.c Message-ID: <20100528230020.782373128018@llvm.org> Author: djg Date: Fri May 28 18:00:20 2010 New Revision: 105015 URL: http://llvm.org/viewvc/llvm-project?rev=105015&view=rev Log: Use static inline instead of inline, to avoid depending on language mode and inline level. Modified: test-suite/trunk/MultiSource/Applications/aha/aha.c Modified: test-suite/trunk/MultiSource/Applications/aha/aha.c URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Applications/aha/aha.c?rev=105015&r1=105014&r2=105015&view=diff ============================================================================== --- test-suite/trunk/MultiSource/Applications/aha/aha.c (original) +++ test-suite/trunk/MultiSource/Applications/aha/aha.c Fri May 28 18:00:20 2010 @@ -70,7 +70,7 @@ // -------------------- simulate_one_instruction ----------------------- -inline void +static inline void simulate_one_instruction(int i) { int arg0, arg1, arg2; @@ -278,7 +278,7 @@ // --------------------------- increment ------------------------------- -inline int +static inline int increment(void) { From dalej at apple.com Fri May 28 18:14:32 2010 From: dalej at apple.com (Dale Johannesen) Date: Fri, 28 May 2010 16:14:32 -0700 Subject: [llvm-commits] [test-suite] r105015 - /test-suite/trunk/MultiSource/Applications/aha/aha.c In-Reply-To: <20100528230020.782373128018@llvm.org> References: <20100528230020.782373128018@llvm.org> Message-ID: On May 28, 2010, at 4:00 PMPDT, Dan Gohman wrote: > Author: djg > Date: Fri May 28 18:00:20 2010 > New Revision: 105015 > > URL: http://llvm.org/viewvc/llvm-project?rev=105015&view=rev > Log: > Use static inline instead of inline, to avoid depending on language mode > and inline level. Why do we want to do this? It should work either way, and if performance comparisons look funny because something is inlined differently, that seems like useful information indicating we should look at the inlining heuristics. > // -------------------- simulate_one_instruction ----------------------- > > -inline void > +static inline void > simulate_one_instruction(int i) > { > int arg0, arg1, arg2; > @@ -278,7 +278,7 @@ > > // --------------------------- increment ------------------------------- > > -inline int > +static inline int > increment(void) > { > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From dalej at apple.com Fri May 28 18:24:28 2010 From: dalej at apple.com (Dale Johannesen) Date: Fri, 28 May 2010 23:24:28 -0000 Subject: [llvm-commits] [llvm] r105059 - /llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Message-ID: <20100528232429.00609312800A@llvm.org> Author: johannes Date: Fri May 28 18:24:28 2010 New Revision: 105059 URL: http://llvm.org/viewvc/llvm-project?rev=105059&view=rev Log: Fix comment typos. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=105059&r1=105058&r2=105059&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri May 28 18:24:28 2010 @@ -2320,8 +2320,8 @@ return false; } - // Look for obvious safe cases to perform tail call optimization that does not - // requite ABI changes. This is what gcc calls sibcall. + // Look for obvious safe cases to perform tail call optimization that do not + // require ABI changes. This is what gcc calls sibcall. // Can't do sibcall if stack needs to be dynamically re-aligned. PEI needs to // emit a special epilogue. From evan.cheng at apple.com Fri May 28 18:25:23 2010 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 28 May 2010 23:25:23 -0000 Subject: [llvm-commits] [llvm] r105060 - /llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Message-ID: <20100528232524.1322E312800A@llvm.org> Author: evancheng Date: Fri May 28 18:25:23 2010 New Revision: 105060 URL: http://llvm.org/viewvc/llvm-project?rev=105060&view=rev Log: Schedule high latency instructions for latency reduction even if they are not vfp / NEON instructions. Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=105060&r1=105059&r2=105060&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Fri May 28 18:25:23 2010 @@ -605,11 +605,29 @@ } Sched::Preference ARMTargetLowering::getSchedulingPreference(SDNode *N) const { - for (unsigned i = 0, e = N->getNumValues(); i != e; ++i) { + unsigned NumVals = N->getNumValues(); + if (!NumVals) + return Sched::RegPressure; + + for (unsigned i = 0; i != NumVals; ++i) { EVT VT = N->getValueType(i); if (VT.isFloatingPoint() || VT.isVector()) return Sched::Latency; } + + if (!N->isMachineOpcode()) + return Sched::RegPressure; + + // Load are scheduled for latency even if there instruction itinerary + // is not available. + const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); + const TargetInstrDesc &TID = TII->get(N->getMachineOpcode()); + if (TID.mayLoad()) + return Sched::Latency; + + const InstrItineraryData &Itins = getTargetMachine().getInstrItineraryData(); + if (!Itins.isEmpty() && Itins.getStageLatency(TID.getSchedClass()) > 2) + return Sched::Latency; return Sched::RegPressure; } From evan.cheng at apple.com Fri May 28 18:26:21 2010 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 28 May 2010 23:26:21 -0000 Subject: [llvm-commits] [llvm] r105061 - in /llvm/trunk: lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp test/CodeGen/ARM/lsr-on-unrolled-loops.ll test/CodeGen/ARM/reg_sequence.ll test/CodeGen/PowerPC/2009-08-17-inline-asm-addr-mode-breakage.ll Message-ID: <20100528232621.E0143312800A@llvm.org> Author: evancheng Date: Fri May 28 18:26:21 2010 New Revision: 105061 URL: http://llvm.org/viewvc/llvm-project?rev=105061&view=rev Log: Fix some latency computation bugs: if the use is not a machine opcode do not just return zero. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp llvm/trunk/test/CodeGen/ARM/lsr-on-unrolled-loops.ll llvm/trunk/test/CodeGen/ARM/reg_sequence.ll llvm/trunk/test/CodeGen/PowerPC/2009-08-17-inline-asm-addr-mode-breakage.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=105061&r1=105060&r2=105061&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Fri May 28 18:26:21 2010 @@ -320,7 +320,7 @@ for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { CapturePred(&*I); - if (I->isAssignedRegDep() && SU->getHeight() == LiveRegCycles[I->getReg()]) { + if (I->isAssignedRegDep() && SU->getHeight() == LiveRegCycles[I->getReg()]){ assert(NumLiveRegs > 0 && "NumLiveRegs is already zero!"); assert(LiveRegDefs[I->getReg()] == I->getSUnit() && "Physical register dependency violated?"); @@ -1275,6 +1275,17 @@ return left->getHeight() > right->getHeight(); } else if (RStall) return false; + + // If either node is scheduling for latency, sort them by height and latency + // first. + if (left->SchedulingPref == Sched::Latency || + right->SchedulingPref == Sched::Latency) { + if (left->getHeight() != right->getHeight()) + return left->getHeight() > right->getHeight(); + if (left->Latency != right->Latency) + return left->Latency > right->Latency; + } + return BURRSort(left, right, SPQ); } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp?rev=105061&r1=105060&r2=105061&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp Fri May 28 18:26:21 2010 @@ -59,7 +59,11 @@ SUnits.back().OrigNode = &SUnits.back(); SUnit *SU = &SUnits.back(); const TargetLowering &TLI = DAG->getTargetLoweringInfo(); - SU->SchedulingPref = TLI.getSchedulingPreference(N); + if (N->isMachineOpcode() && + N->getMachineOpcode() == TargetOpcode::IMPLICIT_DEF) + SU->SchedulingPref = Sched::None; + else + SU->SchedulingPref = TLI.getSchedulingPreference(N); return SU; } @@ -364,8 +368,10 @@ if (Cost >= 0) PhysReg = 0; - const SDep& dep = SDep(OpSU, isChain ? SDep::Order : SDep::Data, - OpSU->Latency, PhysReg); + // If this is a ctrl dep, latency is 1. + unsigned OpLatency = isChain ? 1 : OpSU->Latency; + const SDep &dep = SDep(OpSU, isChain ? SDep::Order : SDep::Data, + OpLatency, PhysReg); if (!isChain && !UnitLatencies) { ComputeOperandLatency(OpN, N, i, const_cast(dep)); ST.adjustSchedDependency(OpSU, SU, const_cast(dep)); @@ -427,15 +433,18 @@ return; unsigned DefIdx = Use->getOperand(OpIdx).getResNo(); - if (Def->isMachineOpcode() && Use->isMachineOpcode()) { + if (Def->isMachineOpcode()) { const TargetInstrDesc &II = TII->get(Def->getMachineOpcode()); if (DefIdx >= II.getNumDefs()) return; int DefCycle = InstrItins.getOperandCycle(II.getSchedClass(), DefIdx); if (DefCycle < 0) return; - const unsigned UseClass = TII->get(Use->getMachineOpcode()).getSchedClass(); - int UseCycle = InstrItins.getOperandCycle(UseClass, OpIdx); + int UseCycle = 1; + if (Use->isMachineOpcode()) { + const unsigned UseClass = TII->get(Use->getMachineOpcode()).getSchedClass(); + UseCycle = InstrItins.getOperandCycle(UseClass, OpIdx); + } if (UseCycle >= 0) { int Latency = DefCycle - UseCycle + 1; if (Latency >= 0) Modified: llvm/trunk/test/CodeGen/ARM/lsr-on-unrolled-loops.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/lsr-on-unrolled-loops.ll?rev=105061&r1=105060&r2=105061&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/lsr-on-unrolled-loops.ll (original) +++ llvm/trunk/test/CodeGen/ARM/lsr-on-unrolled-loops.ll Fri May 28 18:26:21 2010 @@ -4,14 +4,14 @@ ; constant offset addressing, so that each of the following stores ; uses the same register. -; CHECK: vstr.32 s0, [r12, #-128] -; CHECK: vstr.32 s0, [r12, #-96] -; CHECK: vstr.32 s0, [r12, #-64] -; CHECK: vstr.32 s0, [r12, #-32] -; CHECK: vstr.32 s0, [r12] -; CHECK: vstr.32 s0, [r12, #32] -; CHECK: vstr.32 s0, [r12, #64] -; CHECK: vstr.32 s0, [r12, #96] +; CHECK: vstr.32 s0, [r9, #-128] +; CHECK: vstr.32 s0, [r9, #-96] +; CHECK: vstr.32 s0, [r9, #-64] +; CHECK: vstr.32 s0, [r9, #-32] +; CHECK: vstr.32 s0, [r9] +; CHECK: vstr.32 s0, [r9, #32] +; CHECK: vstr.32 s0, [r9, #64] +; CHECK: vstr.32 s0, [r9, #96] target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:32-n32" @@ -626,8 +626,8 @@ ; LSR should use count-down iteration to avoid requiring the trip count ; in a register, and it shouldn't require any reloads here. -; CHECK: sub.w r9, r9, #1 -; CHECK-NEXT: cmp.w r9, #0 +; CHECK: subs r3, #1 +; CHECK-NEXT: cmp r3, #0 ; CHECK-NEXT: bne.w %92 = icmp eq i32 %tmp81, %indvar78 ; [#uses=1] Modified: llvm/trunk/test/CodeGen/ARM/reg_sequence.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/reg_sequence.ll?rev=105061&r1=105060&r2=105061&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/reg_sequence.ll (original) +++ llvm/trunk/test/CodeGen/ARM/reg_sequence.ll Fri May 28 18:26:21 2010 @@ -45,9 +45,9 @@ entry: ; CHECK: t2: ; CHECK: vld1.16 -; CHECK: vld1.16 -; CHECK-NOT: vmov ; CHECK: vmul.i16 +; CHECK-NOT: vmov +; CHECK: vld1.16 ; CHECK: vmul.i16 ; CHECK-NOT: vmov ; CHECK: vst1.16 @@ -238,8 +238,9 @@ define arm_aapcs_vfpcc float @t9(%0* nocapture, %3* nocapture) nounwind { ; CHECK: t9: ; CHECK: vldr.64 +; CHECK-NOT: vmov d{{.*}}, d0 ; CHECK: vmov.i8 d1 -; CHECK-NEXT: vstmia r0, {d2,d3} +; CHECK-NEXT: vstmia r0, {d0,d1} ; CHECK-NEXT: vstmia r0, {d0,d1} %3 = bitcast double 0.000000e+00 to <2 x float> ; <<2 x float>> [#uses=2] %4 = shufflevector <2 x float> %3, <2 x float> undef, <4 x i32> ; <<4 x float>> [#uses=1] Modified: llvm/trunk/test/CodeGen/PowerPC/2009-08-17-inline-asm-addr-mode-breakage.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/2009-08-17-inline-asm-addr-mode-breakage.ll?rev=105061&r1=105060&r2=105061&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/PowerPC/2009-08-17-inline-asm-addr-mode-breakage.ll (original) +++ llvm/trunk/test/CodeGen/PowerPC/2009-08-17-inline-asm-addr-mode-breakage.ll Fri May 28 18:26:21 2010 @@ -10,8 +10,8 @@ define void @foo(i32 %y) nounwind ssp { entry: ; CHECK: foo -; CHECK: add r4 -; CHECK: 0(r4) +; CHECK: add r3 +; CHECK: 0(r3) %y_addr = alloca i32 ; [#uses=2] %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] store i32 %y, i32* %y_addr From stoklund at 2pi.dk Fri May 28 18:48:29 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Fri, 28 May 2010 23:48:29 -0000 Subject: [llvm-commits] [llvm] r105063 - in /llvm/trunk/lib/Target/SystemZ: AsmPrinter/SystemZAsmPrinter.cpp SystemZISelDAGToDAG.cpp SystemZInstrInfo.td SystemZRegisterInfo.td Message-ID: <20100528234829.84E99312800A@llvm.org> Author: stoklund Date: Fri May 28 18:48:29 2010 New Revision: 105063 URL: http://llvm.org/viewvc/llvm-project?rev=105063&view=rev Log: Merge the SystemZ subreg_even32 SubRegIndex into subreg_32bit. The SubRegIndices were overspecified when inheriting sub-subregisters, for instance: R0Q:subreg_even32 = R0Q:subreg_32bit = R0Q:subreg_even:subreg_32bit. This meant that composeSubRegIndices(subreg_even, subreg_32bit) was ambiguous. Modified: llvm/trunk/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp llvm/trunk/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td Modified: llvm/trunk/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp?rev=105063&r1=105062&r2=105063&view=diff ============================================================================== --- llvm/trunk/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp Fri May 28 18:48:29 2010 @@ -124,7 +124,7 @@ unsigned Reg = MO.getReg(); if (Modifier && strncmp(Modifier, "subreg", 6) == 0) { if (strncmp(Modifier + 7, "even", 4) == 0) - Reg = TM.getRegisterInfo()->getSubReg(Reg, SystemZ::subreg_even32); + Reg = TM.getRegisterInfo()->getSubReg(Reg, SystemZ::subreg_32bit); else if (strncmp(Modifier + 7, "odd", 3) == 0) Reg = TM.getRegisterInfo()->getSubReg(Reg, SystemZ::subreg_odd32); else Modified: llvm/trunk/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp?rev=105063&r1=105062&r2=105063&view=diff ============================================================================== --- llvm/trunk/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp Fri May 28 18:48:29 2010 @@ -670,7 +670,7 @@ // Copy the remainder (even subreg) result, if it is needed. if (!SDValue(Node, 1).use_empty()) { unsigned SubRegIdx = (is32Bit ? - SystemZ::subreg_even32 : SystemZ::subreg_even); + SystemZ::subreg_32bit : SystemZ::subreg_even); SDNode *Rem = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, NVT, SDValue(Result, 0), @@ -754,7 +754,7 @@ // Copy the remainder (even subreg) result, if it is needed. if (!SDValue(Node, 1).use_empty()) { unsigned SubRegIdx = (is32Bit ? - SystemZ::subreg_even32 : SystemZ::subreg_even); + SystemZ::subreg_32bit : SystemZ::subreg_even); SDNode *Rem = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, NVT, SDValue(Result, 0), Modified: llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td?rev=105063&r1=105062&r2=105063&view=diff ============================================================================== --- llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td (original) +++ llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td Fri May 28 18:48:29 2010 @@ -1129,13 +1129,13 @@ (EXTRACT_SUBREG (MUL64rrP (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)), GR32:$src1, subreg_odd32), GR32:$src2), - subreg_even32)>; + subreg_32bit)>; def : Pat<(mulhu GR32:$src1, GR32:$src2), (EXTRACT_SUBREG (UMUL64rrP (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)), GR32:$src1, subreg_odd32), GR32:$src2), - subreg_even32)>; + subreg_32bit)>; def : Pat<(mulhu GR64:$src1, GR64:$src2), (EXTRACT_SUBREG (UMUL128rrP (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)), GR64:$src1, subreg_odd), Modified: llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td?rev=105063&r1=105062&r2=105063&view=diff ============================================================================== --- llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td (original) +++ llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td Fri May 28 18:48:29 2010 @@ -55,7 +55,6 @@ let Namespace = "SystemZ" in { def subreg_32bit : SubRegIndex; -def subreg_even32 : SubRegIndex; def subreg_odd32 : SubRegIndex; def subreg_even : SubRegIndex; def subreg_odd : SubRegIndex; @@ -99,7 +98,7 @@ } // Register pairs -let SubRegIndices = [subreg_even32, subreg_odd32] in { +let SubRegIndices = [subreg_32bit, subreg_odd32] in { def R0P : GPR64< 0, "r0", [R0W, R1W], [R0D, R1D]>, DwarfRegNum<[0]>; def R2P : GPR64< 2, "r2", [R2W, R3W], [R2D, R3D]>, DwarfRegNum<[2]>; def R4P : GPR64< 4, "r4", [R4W, R5W], [R4D, R5D]>, DwarfRegNum<[4]>; @@ -111,8 +110,7 @@ } let SubRegIndices = [subreg_even, subreg_odd], - CompositeIndices = [(subreg_even32 subreg_even, subreg_32bit), - (subreg_odd32 subreg_odd, subreg_32bit)] in { + CompositeIndices = [(subreg_odd32 subreg_odd, subreg_32bit)] in { def R0Q : GPR128< 0, "r0", [R0D, R1D], [R0P]>, DwarfRegNum<[0]>; def R2Q : GPR128< 2, "r2", [R2D, R3D], [R2P]>, DwarfRegNum<[2]>; def R4Q : GPR128< 4, "r4", [R4D, R5D], [R4P]>, DwarfRegNum<[4]>; @@ -355,7 +353,7 @@ def GR64P : RegisterClass<"SystemZ", [v2i32], 64, [R0P, R2P, R4P, R6P, R8P, R10P, R12P, R14P]> { - let SubRegClasses = [(GR32 subreg_even32, subreg_odd32)]; + let SubRegClasses = [(GR32 subreg_32bit, subreg_odd32)]; let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; iterator allocation_order_end(const MachineFunction &MF) const; @@ -391,7 +389,7 @@ def GR128 : RegisterClass<"SystemZ", [v2i64], 128, [R0Q, R2Q, R4Q, R6Q, R8Q, R10Q, R12Q, R14Q]> { - let SubRegClasses = [(GR32 subreg_even32, subreg_odd32), + let SubRegClasses = [(GR32 subreg_32bit, subreg_odd32), (GR64 subreg_even, subreg_odd)]; let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; From stoklund at 2pi.dk Fri May 28 18:48:31 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Fri, 28 May 2010 23:48:31 -0000 Subject: [llvm-commits] [llvm] r105064 - /llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <20100528234831.D18333128018@llvm.org> Author: stoklund Date: Fri May 28 18:48:31 2010 New Revision: 105064 URL: http://llvm.org/viewvc/llvm-project?rev=105064&view=rev Log: Emit TargetRegisterInfo::composeSubRegIndices(). Also verify that all subregister indices compose unambiguously. Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp?rev=105064&r1=105063&r2=105064&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Fri May 28 18:48:31 2010 @@ -82,6 +82,7 @@ << " { return false; }\n" << " unsigned getSubReg(unsigned RegNo, unsigned Index) const;\n" << " unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const;\n" + << " unsigned composeSubRegIndices(unsigned, unsigned) const;\n" << "};\n\n"; const std::vector &RegisterClasses = @@ -171,14 +172,28 @@ addSubSuperReg(R, *I, SubRegs, SuperRegs, Aliases); } -// Map SubRegIndex -> Register -typedef std::map SubRegMap; -// Map Register -> SubRegMap -typedef std::map AllSubRegMap; +struct RegisterMaps { + // Map SubRegIndex -> Register + typedef std::map SubRegMap; + // Map Register -> SubRegMap + typedef std::map SubRegMaps; + + SubRegMaps SubReg; + SubRegMap &inferSubRegIndices(Record *Reg); + + // Composite SubRegIndex instances. + // Map (SubRegIndex,SubRegIndex) -> SubRegIndex + typedef DenseMap,Record*> CompositeMap; + CompositeMap Composite; + + // Compute SubRegIndex compositions after inferSubRegIndices has run on all + // registers. + void computeComposites(); +}; // Calculate all subregindices for Reg. Loopy subregs cause infinite recursion. -static SubRegMap &inferSubRegIndices(Record *Reg, AllSubRegMap &ASRM) { - SubRegMap &SRM = ASRM[Reg]; +RegisterMaps::SubRegMap &RegisterMaps::inferSubRegIndices(Record *Reg) { + SubRegMap &SRM = SubReg[Reg]; if (!SRM.empty()) return SRM; std::vector SubRegs = Reg->getValueAsListOfDefs("SubRegs"); @@ -191,7 +206,7 @@ if (!SRM.insert(std::make_pair(Indices[i], SubRegs[i])).second) throw "SubRegIndex " + Indices[i]->getName() + " appears twice in Register " + Reg->getName(); - inferSubRegIndices(SubRegs[i], ASRM); + inferSubRegIndices(SubRegs[i]); } // Keep track of inherited subregs and how they can be reached. @@ -202,7 +217,7 @@ // Clone inherited subregs. Here the order is important - earlier subregs take // precedence. for (unsigned i = 0, e = SubRegs.size(); i != e; ++i) { - SubRegMap &M = ASRM[SubRegs[i]]; + SubRegMap &M = SubReg[SubRegs[i]]; for (SubRegMap::iterator si = M.begin(), se = M.end(); si != se; ++si) if (!SRM.insert(*si).second) Orphans[si->second] = std::make_pair(Indices[i], si->first); @@ -226,8 +241,8 @@ DefInit *IdxInit = dynamic_cast(*di); if (!IdxInit || !IdxInit->getDef()->isSubClassOf("SubRegIndex")) throw "Invalid SubClassIndex in " + Pat->getAsString(); - SubRegMap::const_iterator ni = ASRM[R2].find(IdxInit->getDef()); - if (ni == ASRM[R2].end()) + SubRegMap::const_iterator ni = SubReg[R2].find(IdxInit->getDef()); + if (ni == SubReg[R2].end()) throw "Composite " + Pat->getAsString() + " refers to bad index in " + R2->getName(); R2 = ni->second; @@ -255,6 +270,62 @@ return SRM; } +void RegisterMaps::computeComposites() { + for (SubRegMaps::const_iterator sri = SubReg.begin(), sre = SubReg.end(); + sri != sre; ++sri) { + Record *Reg1 = sri->first; + const SubRegMap &SRM1 = sri->second; + for (SubRegMap::const_iterator i1 = SRM1.begin(), e1 = SRM1.end(); + i1 != e1; ++i1) { + Record *Idx1 = i1->first; + Record *Reg2 = i1->second; + // Ignore identity compositions. + if (Reg1 == Reg2) + continue; + // If Reg2 has no subregs, Idx1 doesn't compose. + if (!SubReg.count(Reg2)) + continue; + const SubRegMap &SRM2 = SubReg[Reg2]; + // Try composing Idx1 with another SubRegIndex. + for (SubRegMap::const_iterator i2 = SRM2.begin(), e2 = SRM2.end(); + i2 != e2; ++i2) { + std::pair IdxPair(Idx1, i2->first); + Record *Reg3 = i2->second; + // OK Reg1:IdxPair == Reg3. Find the index with Reg:Idx == Reg3. + for (SubRegMap::const_iterator i1d = SRM1.begin(), e1d = SRM1.end(); + i1d != e1d; ++i1d) { + // Ignore identity compositions. + if (Reg2 == Reg3) + continue; + if (i1d->second == Reg3) { + std::pair Ins = + Composite.insert(std::make_pair(IdxPair, i1d->first)); + // Conflicting composition? + if (!Ins.second && Ins.first->second != i1d->first) { + errs() << "Error: SubRegIndex " << getQualifiedName(Idx1) + << " and " << getQualifiedName(IdxPair.second) + << " compose ambiguously as " + << getQualifiedName(Ins.first->second) << " or " + << getQualifiedName(i1d->first) << "\n"; + abort(); + } + } + } + } + } + } + + // We don't care about the difference between (Idx1, Idx2) -> Idx2 and invalid + // compositions, so remove any mappings of that form. + for (CompositeMap::iterator i = Composite.begin(), e = Composite.end(); + i != e;) { + CompositeMap::iterator j = i; + ++i; + if (j->first.second == j->second) + Composite.erase(j); + } +} + class RegisterSorter { private: std::map, LessRecord> &RegisterSubRegs; @@ -836,7 +907,7 @@ std::string ClassName = Target.getName() + "GenRegisterInfo"; // Calculate the mapping of subregister+index pairs to physical registers. - AllSubRegMap AllSRM; + RegisterMaps RegMaps; // Emit the subregister + index mapping function based on the information // calculated above. @@ -845,14 +916,14 @@ << " switch (RegNo) {\n" << " default:\n return 0;\n"; for (unsigned i = 0, e = Regs.size(); i != e; ++i) { - SubRegMap &SRM = inferSubRegIndices(Regs[i].TheDef, AllSRM); + RegisterMaps::SubRegMap &SRM = RegMaps.inferSubRegIndices(Regs[i].TheDef); if (SRM.empty()) continue; OS << " case " << getQualifiedName(Regs[i].TheDef) << ":\n"; OS << " switch (Index) {\n"; OS << " default: return 0;\n"; - for (SubRegMap::const_iterator ii = SRM.begin(), ie = SRM.end(); ii != ie; - ++ii) + for (RegisterMaps::SubRegMap::const_iterator ii = SRM.begin(), + ie = SRM.end(); ii != ie; ++ii) OS << " case " << getQualifiedName(ii->first) << ": return " << getQualifiedName(ii->second) << ";\n"; OS << " };\n" << " break;\n"; @@ -866,12 +937,12 @@ << " switch (RegNo) {\n" << " default:\n return 0;\n"; for (unsigned i = 0, e = Regs.size(); i != e; ++i) { - SubRegMap &SRM = AllSRM[Regs[i].TheDef]; + RegisterMaps::SubRegMap &SRM = RegMaps.SubReg[Regs[i].TheDef]; if (SRM.empty()) continue; OS << " case " << getQualifiedName(Regs[i].TheDef) << ":\n"; - for (SubRegMap::const_iterator ii = SRM.begin(), ie = SRM.end(); ii != ie; - ++ii) + for (RegisterMaps::SubRegMap::const_iterator ii = SRM.begin(), + ie = SRM.end(); ii != ie; ++ii) OS << " if (SubRegNo == " << getQualifiedName(ii->second) << ") return " << getQualifiedName(ii->first) << ";\n"; OS << " return 0;\n"; @@ -879,7 +950,32 @@ OS << " };\n"; OS << " return 0;\n"; OS << "}\n\n"; - + + // Emit composeSubRegIndices + RegMaps.computeComposites(); + OS << "unsigned " << ClassName + << "::composeSubRegIndices(unsigned IdxA, unsigned IdxB) const {\n" + << " switch (IdxA) {\n" + << " default:\n return IdxB;\n"; + for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) { + bool Open = false; + for (unsigned j = 0; j != e; ++j) { + if (Record *Comp = RegMaps.Composite.lookup( + std::make_pair(SubRegIndices[i], SubRegIndices[j]))) { + if (!Open) { + OS << " case " << getQualifiedName(SubRegIndices[i]) + << ": switch(IdxB) {\n default: return IdxB;\n"; + Open = true; + } + OS << " case " << getQualifiedName(SubRegIndices[j]) + << ": return " << getQualifiedName(Comp) << ";\n"; + } + } + if (Open) + OS << " }\n"; + } + OS << " }\n}\n\n"; + // Emit the constructor of the class... OS << ClassName << "::" << ClassName << "(int CallFrameSetupOpcode, int CallFrameDestroyOpcode)\n" From gohman at apple.com Fri May 28 18:50:08 2010 From: gohman at apple.com (Dan Gohman) Date: Fri, 28 May 2010 16:50:08 -0700 Subject: [llvm-commits] [test-suite] r105015 - /test-suite/trunk/MultiSource/Applications/aha/aha.c In-Reply-To: References: <20100528230020.782373128018@llvm.org> Message-ID: On May 28, 2010, at 4:14 PM, Dale Johannesen wrote: > > On May 28, 2010, at 4:00 PMPDT, Dan Gohman wrote: > >> Author: djg >> Date: Fri May 28 18:00:20 2010 >> New Revision: 105015 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=105015&view=rev >> Log: >> Use static inline instead of inline, to avoid depending on language mode >> and inline level. > > Why do we want to do this? It should work either way, and if performance comparisons look funny because something is inlined differently, that seems like useful information indicating we should look at the inlining heuristics. In C99 mode, the compiler isn't required to emit definitions for such inline functions, so at -O0 this program didn't link. With static, this program will compile as intended regardless of the language mode. Dan From evan.cheng at apple.com Fri May 28 19:06:36 2010 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 29 May 2010 00:06:36 -0000 Subject: [llvm-commits] [llvm] r105065 - /llvm/trunk/lib/CodeGen/MachineLICM.cpp Message-ID: <20100529000637.0660E312800A@llvm.org> Author: evancheng Date: Fri May 28 19:06:36 2010 New Revision: 105065 URL: http://llvm.org/viewvc/llvm-project?rev=105065&view=rev Log: Doh. Machine LICM is re-initializing the CSE map over and over. Patch by Anna Zaks. rdar://8037934. Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineLICM.cpp?rev=105065&r1=105064&r2=105065&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineLICM.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineLICM.cpp Fri May 28 19:06:36 2010 @@ -62,6 +62,7 @@ // State that is updated as we process loops bool Changed; // True if a loop is changed. + bool FirstInLoop; // True if it's the first LICM in the loop. MachineLoop *CurLoop; // The current loop we are working on. MachineBasicBlock *CurPreheader; // The preheader for CurLoop. @@ -207,7 +208,7 @@ else DEBUG(dbgs() << "******** Post-regalloc Machine LICM ********\n"); - Changed = false; + Changed = FirstInLoop = false; TM = &MF.getTarget(); TII = TM->getInstrInfo(); TRI = TM->getRegisterInfo(); @@ -244,6 +245,7 @@ // CSEMap is initialized for loop header when the first instruction is // being hoisted. MachineDomTreeNode *N = DT->getNode(CurLoop->getHeader()); + FirstInLoop = true; HoistRegion(N); CSEMap.clear(); } @@ -776,7 +778,10 @@ // If this is the first instruction being hoisted to the preheader, // initialize the CSE map with potential common expressions. - InitCSEMap(CurPreheader); + if (FirstInLoop) { + InitCSEMap(CurPreheader); + FirstInLoop = false; + } // Look for opportunity to CSE the hoisted instruction. unsigned Opcode = MI->getOpcode(); From stoklund at 2pi.dk Fri May 28 19:14:14 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Sat, 29 May 2010 00:14:14 -0000 Subject: [llvm-commits] [llvm] r105066 - /llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp Message-ID: <20100529001414.893D2312800A@llvm.org> Author: stoklund Date: Fri May 28 19:14:14 2010 New Revision: 105066 URL: http://llvm.org/viewvc/llvm-project?rev=105066&view=rev Log: Handle composed subreg indices when processing REQ_SEQUENCE instructions. Modified: llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp Modified: llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp?rev=105066&r1=105065&r2=105066&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp (original) +++ llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp Fri May 28 19:14:14 2010 @@ -1136,14 +1136,13 @@ static void UpdateRegSequenceSrcs(unsigned SrcReg, unsigned DstReg, unsigned SubIdx, - MachineRegisterInfo *MRI) { + MachineRegisterInfo *MRI, + const TargetRegisterInfo &TRI) { for (MachineRegisterInfo::reg_iterator RI = MRI->reg_begin(SrcReg), RE = MRI->reg_end(); RI != RE; ) { MachineOperand &MO = RI.getOperand(); ++RI; - MO.setReg(DstReg); - assert(MO.getSubReg() == 0); - MO.setSubReg(SubIdx); + MO.substVirtReg(DstReg, SubIdx, TRI); } } @@ -1315,7 +1314,7 @@ for (unsigned i = 1, e = MI->getNumOperands(); i < e; i += 2) { unsigned SrcReg = MI->getOperand(i).getReg(); unsigned SubIdx = MI->getOperand(i+1).getImm(); - UpdateRegSequenceSrcs(SrcReg, DstReg, SubIdx, MRI); + UpdateRegSequenceSrcs(SrcReg, DstReg, SubIdx, MRI, *TRI); } if (IsImpDef) { From evan.cheng at apple.com Fri May 28 20:35:22 2010 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 29 May 2010 01:35:22 -0000 Subject: [llvm-commits] [llvm] r105092 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/sibcall-3.ll Message-ID: <20100529013522.7CD08312800A@llvm.org> Author: evancheng Date: Fri May 28 20:35:22 2010 New Revision: 105092 URL: http://llvm.org/viewvc/llvm-project?rev=105092&view=rev Log: Fix PR7193: if sibling call address can take a register, make sure there are enough registers available by counting inreg arguments. Added: llvm/trunk/test/CodeGen/X86/sibcall-3.ll Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=105092&r1=105091&r2=105092&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri May 28 20:35:22 2010 @@ -2427,6 +2427,24 @@ } } } + + // If the tailcall address may be in a register, then make sure it's + // possible to register allocate for it. In 32-bit, the call address can + // only target EAX, EDX, or ECX since the tail call must be scheduled after + // callee-saved registers are restored. In 64-bit, it's RAX, RCX, RDX, RSI, + // RDI, R8, R9, R11. + if (!isa(Callee) && + !isa(Callee)) { + unsigned Limit = Subtarget->is64Bit() ? 8 : 3; + unsigned NumInRegs = 0; + for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { + CCValAssign &VA = ArgLocs[i]; + if (VA.isRegLoc()) { + if (++NumInRegs == Limit) + return false; + } + } + } } return true; Added: llvm/trunk/test/CodeGen/X86/sibcall-3.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/sibcall-3.ll?rev=105092&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/sibcall-3.ll (added) +++ llvm/trunk/test/CodeGen/X86/sibcall-3.ll Fri May 28 20:35:22 2010 @@ -0,0 +1,16 @@ +; RUN: llc < %s -mtriple=i386-unknown-unknown | FileCheck %s +; PR7193 + +define void @t1(i8* inreg %dst, i8* inreg %src, i8* inreg %len) nounwind { +; CHECK: t1: +; CHECK: call 0 + tail call void null(i8* inreg %dst, i8* inreg %src, i8* inreg %len) nounwind + ret void +} + +define void @t2(i8* inreg %dst, i8* inreg %src, i8* inreg %len) nounwind { +; CHECK: t2: +; CHECK: jmpl + tail call void null(i8* inreg %dst, i8* inreg %src) nounwind + ret void +} From evan.cheng at apple.com Fri May 28 21:23:39 2010 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 29 May 2010 02:23:39 -0000 Subject: [llvm-commits] [llvm] r105095 - in /llvm/trunk: lib/CodeGen/MachineRegisterInfo.cpp test/CodeGen/X86/2008-03-10-RegAllocInfLoop.ll Message-ID: <20100529022339.42896312800A@llvm.org> Author: evancheng Date: Fri May 28 21:23:39 2010 New Revision: 105095 URL: http://llvm.org/viewvc/llvm-project?rev=105095&view=rev Log: Remove schedule-livein-copies. It's not being used. Modified: llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp llvm/trunk/test/CodeGen/X86/2008-03-10-RegAllocInfLoop.ll Modified: llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp?rev=105095&r1=105094&r2=105095&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp Fri May 28 21:23:39 2010 @@ -174,11 +174,6 @@ return 0; } -static cl::opt -SchedLiveInCopies("schedule-livein-copies", cl::Hidden, - cl::desc("Schedule copies of livein registers"), - cl::init(false)); - /// EmitLiveInCopy - Emit a copy for a live in physical register. If the /// physical register has only a single copy use, then coalesced the copy /// if possible. @@ -254,34 +249,21 @@ MachineRegisterInfo::EmitLiveInCopies(MachineBasicBlock *EntryMBB, const TargetRegisterInfo &TRI, const TargetInstrInfo &TII) { - if (SchedLiveInCopies) { - // Emit the copies at a heuristically-determined location in the block. - DenseMap CopyRegMap; - MachineBasicBlock::iterator InsertPos = EntryMBB->begin(); - for (MachineRegisterInfo::livein_iterator LI = livein_begin(), - E = livein_end(); LI != E; ++LI) - if (LI->second) { - const TargetRegisterClass *RC = getRegClass(LI->second); - EmitLiveInCopy(EntryMBB, InsertPos, LI->second, LI->first, - RC, CopyRegMap, *this, TRI, TII); - } - } else { - // Emit the copies into the top of the block. - for (MachineRegisterInfo::livein_iterator LI = livein_begin(), - E = livein_end(); LI != E; ++LI) - if (LI->second) { - const TargetRegisterClass *RC = getRegClass(LI->second); - bool Emitted = TII.copyRegToReg(*EntryMBB, EntryMBB->begin(), - LI->second, LI->first, RC, RC, - DebugLoc()); - assert(Emitted && "Unable to issue a live-in copy instruction!\n"); - (void) Emitted; - } - } + // Emit the copies into the top of the block. + for (MachineRegisterInfo::livein_iterator LI = livein_begin(), + E = livein_end(); LI != E; ++LI) + if (LI->second) { + const TargetRegisterClass *RC = getRegClass(LI->second); + bool Emitted = TII.copyRegToReg(*EntryMBB, EntryMBB->begin(), + LI->second, LI->first, RC, RC, + DebugLoc()); + assert(Emitted && "Unable to issue a live-in copy instruction!\n"); + (void) Emitted; + } // Add function live-ins to entry block live-in set. for (MachineRegisterInfo::livein_iterator I = livein_begin(), - E = livein_end(); I != E; ++I) + E = livein_end(); I != E; ++I) EntryMBB->addLiveIn(I->first); } Modified: llvm/trunk/test/CodeGen/X86/2008-03-10-RegAllocInfLoop.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2008-03-10-RegAllocInfLoop.ll?rev=105095&r1=105094&r2=105095&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2008-03-10-RegAllocInfLoop.ll (original) +++ llvm/trunk/test/CodeGen/X86/2008-03-10-RegAllocInfLoop.ll Fri May 28 21:23:39 2010 @@ -1,5 +1,4 @@ ; RUN: llc < %s -mtriple=i386-pc-linux-gnu -relocation-model=pic -disable-fp-elim -; RUN: llc < %s -mtriple=i386-pc-linux-gnu -relocation-model=pic -disable-fp-elim -schedule-livein-copies | not grep {Number of register spills} ; PR2134 declare fastcc i8* @w_addchar(i8*, i32*, i32*, i8 signext ) nounwind From nicholas at mxc.ca Sat May 29 01:11:16 2010 From: nicholas at mxc.ca (Nick Lewycky) Date: Sat, 29 May 2010 06:11:16 -0000 Subject: [llvm-commits] [llvm] r105096 - /llvm/trunk/include/llvm/Value.h Message-ID: <20100529061116.C0489312800A@llvm.org> Author: nicholas Date: Sat May 29 01:11:16 2010 New Revision: 105096 URL: http://llvm.org/viewvc/llvm-project?rev=105096&view=rev Log: Fix typo. Modified: llvm/trunk/include/llvm/Value.h Modified: llvm/trunk/include/llvm/Value.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Value.h?rev=105096&r1=105095&r2=105096&view=diff ============================================================================== --- llvm/trunk/include/llvm/Value.h (original) +++ llvm/trunk/include/llvm/Value.h Sat May 29 01:11:16 2010 @@ -210,7 +210,7 @@ UndefValueVal, // This is an instance of UndefValue BlockAddressVal, // This is an instance of BlockAddress ConstantExprVal, // This is an instance of ConstantExpr - ConstantAggregateZeroVal, // This is an instance of ConstantAggregateNull + ConstantAggregateZeroVal, // This is an instance of ConstantAggregateZero ConstantIntVal, // This is an instance of ConstantInt ConstantFPVal, // This is an instance of ConstantFP ConstantArrayVal, // This is an instance of ConstantArray From nicholas at mxc.ca Sat May 29 01:44:15 2010 From: nicholas at mxc.ca (Nick Lewycky) Date: Sat, 29 May 2010 06:44:15 -0000 Subject: [llvm-commits] [llvm] r105098 - /llvm/trunk/docs/LangRef.html Message-ID: <20100529064415.D9A4B312800A@llvm.org> Author: nicholas Date: Sat May 29 01:44:15 2010 New Revision: 105098 URL: http://llvm.org/viewvc/llvm-project?rev=105098&view=rev Log: Document aggregate operation constant expressions. Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=105098&r1=105097&r2=105098&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Sat May 29 01:44:15 2010 @@ -2574,6 +2574,18 @@
    Perform the shufflevector operation on constants.
    +
    extractvalue (VAL, IDX0, IDX1, ...)
    +
    Perform the extractvalue operation on + constants. The index list is interpreted in a similar manner as indices in + a 'getelementptr' operation. At least one + index value must be specified.
    + +
    insertvalue (VAL, ELT, IDX0, IDX1, ...)
    +
    Perform the insertvalue operation on + constants. The index list is interpreted in a similar manner as indices in + a 'getelementptr' operation. At least one + index value must be specified.
    +
    OPCODE (LHS, RHS)
    Perform the specified operation of the LHS and RHS constants. OPCODE may be any of the binary From anton at korobeynikov.info Sat May 29 08:40:51 2010 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Sat, 29 May 2010 17:40:51 +0400 Subject: [llvm-commits] Global Merge Pass for ARM In-Reply-To: References: <1274006983.22060.61.camel@aslstation> <85FA0CB8-76CF-42A8-AD4F-C17F08902366@apple.com> Message-ID: <1275140451.22060.104.camel@aslstation> Hi, Evan > Yes, adding a target hook for this seems like the right thing. > Why do you need two though? Is getMinGlobalOffset necessary? I'm thinking about the next series of iterations for this pass. The idea is quite simple: many load/store instructions have signed offset fields (e.g. on arm +-4095) and currently we don't exploit the negative offsets at all. If we use as a global base the middle of the global, then we can address with the same base as twice as we have right now. The updated patch is attached (still inside Target/ARM, but can be moved out) > 1. Use SmallVector instead of std::vector? Fixed > 3. MaxOffset should not be initialized when the pass is created. What > if we want to support switching between ARM / Thumb mode on a function > to function basis? Can it use TargetLowering::isLegalAddressingMode() > or something similar instead? New hook to TLI was added, however for now we are using the result in a same way as before. When we'll have separate handling for the functions in ARM/Thumb mode, then we'll need to look into the users and infer the maximum possible offset for each global depending on this. I've put a fixme there. > -- With best regards, Anton Korobeynikov. Faculty of Mathematics & Mechanics, Saint Petersburg State University. -------------- next part -------------- A non-text attachment was scrubbed... Name: globalmerge.patch Type: text/x-patch Size: 9711 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20100529/3d96636c/attachment.bin From benny.kra at googlemail.com Sat May 29 09:03:51 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Sat, 29 May 2010 14:03:51 -0000 Subject: [llvm-commits] [llvm] r105100 - /llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp Message-ID: <20100529140351.A481F312800A@llvm.org> Author: d0k Date: Sat May 29 09:03:51 2010 New Revision: 105100 URL: http://llvm.org/viewvc/llvm-project?rev=105100&view=rev Log: Remove unused function. Modified: llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp Modified: llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp?rev=105100&r1=105099&r2=105100&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp Sat May 29 09:03:51 2010 @@ -174,75 +174,6 @@ return 0; } -/// EmitLiveInCopy - Emit a copy for a live in physical register. If the -/// physical register has only a single copy use, then coalesced the copy -/// if possible. -static void EmitLiveInCopy(MachineBasicBlock *MBB, - MachineBasicBlock::iterator &InsertPos, - unsigned VirtReg, unsigned PhysReg, - const TargetRegisterClass *RC, - DenseMap &CopyRegMap, - const MachineRegisterInfo &MRI, - const TargetRegisterInfo &TRI, - const TargetInstrInfo &TII) { - unsigned NumUses = 0; - MachineInstr *UseMI = NULL; - for (MachineRegisterInfo::use_iterator UI = MRI.use_begin(VirtReg), - UE = MRI.use_end(); UI != UE; ++UI) { - UseMI = &*UI; - if (++NumUses > 1) - break; - } - - // If the number of uses is not one, or the use is not a move instruction, - // don't coalesce. Also, only coalesce away a virtual register to virtual - // register copy. - bool Coalesced = false; - unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; - if (NumUses == 1 && - TII.isMoveInstr(*UseMI, SrcReg, DstReg, SrcSubReg, DstSubReg) && - TargetRegisterInfo::isVirtualRegister(DstReg)) { - VirtReg = DstReg; - Coalesced = true; - } - - // Now find an ideal location to insert the copy. - MachineBasicBlock::iterator Pos = InsertPos; - while (Pos != MBB->begin()) { - MachineInstr *PrevMI = prior(Pos); - DenseMap::iterator RI = CopyRegMap.find(PrevMI); - // copyRegToReg might emit multiple instructions to do a copy. - unsigned CopyDstReg = (RI == CopyRegMap.end()) ? 0 : RI->second; - if (CopyDstReg && !TRI.regsOverlap(CopyDstReg, PhysReg)) - // This is what the BB looks like right now: - // r1024 = mov r0 - // ... - // r1 = mov r1024 - // - // We want to insert "r1025 = mov r1". Inserting this copy below the - // move to r1024 makes it impossible for that move to be coalesced. - // - // r1025 = mov r1 - // r1024 = mov r0 - // ... - // r1 = mov 1024 - // r2 = mov 1025 - break; // Woot! Found a good location. - --Pos; - } - - bool Emitted = TII.copyRegToReg(*MBB, Pos, VirtReg, PhysReg, RC, RC, - DebugLoc()); - assert(Emitted && "Unable to issue a live-in copy instruction!\n"); - (void) Emitted; - - CopyRegMap.insert(std::make_pair(prior(Pos), VirtReg)); - if (Coalesced) { - if (&*InsertPos == UseMI) ++InsertPos; - MBB->erase(UseMI); - } -} - /// EmitLiveInCopies - Emit copies to initialize livein virtual registers /// into the given entry block. void From gohman at apple.com Sat May 29 12:03:37 2010 From: gohman at apple.com (Dan Gohman) Date: Sat, 29 May 2010 17:03:37 -0000 Subject: [llvm-commits] [llvm] r105101 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAG.h lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp lib/CodeGen/SelectionDAG/FunctionLoweringInfo.h lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <20100529170337.365E0312800A@llvm.org> Author: djg Date: Sat May 29 12:03:36 2010 New Revision: 105101 URL: http://llvm.org/viewvc/llvm-project?rev=105101&view=rev Log: SelectionDAG shouldn't have a FunctionLoweringInfo member. RegsForValue shouldn't have a TargetLoweringInfo member. And FunctionLoweringInfo::set doesn't needs its EnableFastISel argument. Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAG.h?rev=105101&r1=105100&r2=105101&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Sat May 29 12:03:36 2010 @@ -29,7 +29,6 @@ namespace llvm { class AliasAnalysis; -class FunctionLoweringInfo; class MachineConstantPoolValue; class MachineFunction; class MDNode; @@ -134,7 +133,6 @@ const TargetLowering &TLI; const TargetSelectionDAGInfo &TSI; MachineFunction *MF; - FunctionLoweringInfo &FLI; LLVMContext *Context; /// EntryNode - The starting token. @@ -187,7 +185,7 @@ SelectionDAG(const SelectionDAG&); // Do not implement. public: - SelectionDAG(const TargetMachine &TM, FunctionLoweringInfo &fli); + explicit SelectionDAG(const TargetMachine &TM); ~SelectionDAG(); /// init - Prepare this SelectionDAG to process code in the given @@ -204,7 +202,6 @@ const TargetMachine &getTarget() const { return TM; } const TargetLowering &getTargetLoweringInfo() const { return TLI; } const TargetSelectionDAGInfo &getSelectionDAGInfo() const { return TSI; } - FunctionLoweringInfo &getFunctionLoweringInfo() const { return FLI; } LLVMContext *getContext() const {return Context; } /// viewGraph - Pop up a GraphViz/gv window with the DAG rendered using 'dot'. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp?rev=105101&r1=105100&r2=105101&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp Sat May 29 12:03:36 2010 @@ -74,8 +74,7 @@ : TLI(tli) { } -void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, - bool EnableFastISel) { +void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf) { Fn = &fn; MF = &mf; RegInfo = &MF->getRegInfo(); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.h?rev=105101&r1=105100&r2=105101&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.h Sat May 29 12:03:36 2010 @@ -106,7 +106,7 @@ /// set - Initialize this FunctionLoweringInfo with the given Function /// and its associated MachineFunction. /// - void set(const Function &Fn, MachineFunction &MF, bool EnableFastISel); + void set(const Function &Fn, MachineFunction &MF); /// clear - Clear out all the function-specific state. This returns this /// FunctionLoweringInfo to an empty state, ready to be used for a Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=105101&r1=105100&r2=105101&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sat May 29 12:03:36 2010 @@ -790,9 +790,8 @@ } // EntryNode could meaningfully have debug info if we can find it... -SelectionDAG::SelectionDAG(const TargetMachine &tm, FunctionLoweringInfo &fli) +SelectionDAG::SelectionDAG(const TargetMachine &tm) : TM(tm), TLI(*tm.getTargetLowering()), TSI(*tm.getSelectionDAGInfo()), - FLI(fli), EntryNode(ISD::EntryToken, DebugLoc(), getVTList(MVT::Other)), Root(getEntryNode()), Ordering(0) { AllNodes.push_back(&EntryNode); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=105101&r1=105100&r2=105101&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Sat May 29 12:03:36 2010 @@ -81,10 +81,6 @@ /// registers of some legal type. /// struct RegsForValue { - /// TLI - The TargetLowering object. - /// - const TargetLowering *TLI; - /// ValueVTs - The value types of the values, which may not be legal, and /// may need be promoted or synthesized from one or more registers. /// @@ -107,25 +103,25 @@ /// SmallVector Regs; - RegsForValue() : TLI(0) {} + RegsForValue() {} - RegsForValue(const TargetLowering &tli, - const SmallVector ®s, + RegsForValue(const SmallVector ®s, EVT regvt, EVT valuevt) - : TLI(&tli), ValueVTs(1, valuevt), RegVTs(1, regvt), Regs(regs) {} - RegsForValue(const TargetLowering &tli, - const SmallVector ®s, + : ValueVTs(1, valuevt), RegVTs(1, regvt), Regs(regs) {} + + RegsForValue(const SmallVector ®s, const SmallVector ®vts, const SmallVector &valuevts) - : TLI(&tli), ValueVTs(valuevts), RegVTs(regvts), Regs(regs) {} + : ValueVTs(valuevts), RegVTs(regvts), Regs(regs) {} + RegsForValue(LLVMContext &Context, const TargetLowering &tli, - unsigned Reg, const Type *Ty) : TLI(&tli) { + unsigned Reg, const Type *Ty) { ComputeValueVTs(tli, Ty, ValueVTs); for (unsigned Value = 0, e = ValueVTs.size(); Value != e; ++Value) { EVT ValueVT = ValueVTs[Value]; - unsigned NumRegs = TLI->getNumRegisters(Context, ValueVT); - EVT RegisterVT = TLI->getRegisterType(Context, ValueVT); + unsigned NumRegs = tli.getNumRegisters(Context, ValueVT); + EVT RegisterVT = tli.getRegisterType(Context, ValueVT); for (unsigned i = 0; i != NumRegs; ++i) Regs.push_back(Reg + i); RegVTs.push_back(RegisterVT); @@ -134,19 +130,17 @@ } /// areValueTypesLegal - Return true if types of all the values are legal. - bool areValueTypesLegal() { + bool areValueTypesLegal(const TargetLowering &TLI) { for (unsigned Value = 0, e = ValueVTs.size(); Value != e; ++Value) { EVT RegisterVT = RegVTs[Value]; - if (!TLI->isTypeLegal(RegisterVT)) + if (!TLI.isTypeLegal(RegisterVT)) return false; } return true; } - /// append - Add the specified values to this one. void append(const RegsForValue &RHS) { - TLI = RHS.TLI; ValueVTs.append(RHS.ValueVTs.begin(), RHS.ValueVTs.end()); RegVTs.append(RHS.RegVTs.begin(), RHS.RegVTs.end()); Regs.append(RHS.Regs.begin(), RHS.Regs.end()); @@ -157,7 +151,8 @@ /// this value and returns the result as a ValueVTs value. This uses /// Chain/Flag as the input and updates them for the output Chain/Flag. /// If the Flag pointer is NULL, no flag is used. - SDValue getCopyFromRegs(SelectionDAG &DAG, DebugLoc dl, + SDValue getCopyFromRegs(SelectionDAG &DAG, FunctionLoweringInfo &FuncInfo, + DebugLoc dl, SDValue &Chain, SDValue *Flag) const; /// getCopyToRegs - Emit a series of CopyToReg nodes that copies the @@ -762,7 +757,7 @@ RegsForValue RFV(*DAG.getContext(), TLI, InReg, V->getType()); SDValue Chain = DAG.getEntryNode(); - return RFV.getCopyFromRegs(DAG, getCurDebugLoc(), Chain, NULL); + return RFV.getCopyFromRegs(DAG, FuncInfo, getCurDebugLoc(), Chain, NULL); } /// Get the EVTs and ArgFlags collections that represent the legalized return @@ -829,10 +824,9 @@ void SelectionDAGBuilder::visitRet(const ReturnInst &I) { SDValue Chain = getControlRoot(); SmallVector Outs; - FunctionLoweringInfo &FLI = DAG.getFunctionLoweringInfo(); - if (!FLI.CanLowerReturn) { - unsigned DemoteReg = FLI.DemoteRegister; + if (!FuncInfo.CanLowerReturn) { + unsigned DemoteReg = FuncInfo.DemoteRegister; const Function *F = I.getParent()->getParent(); // Emit a store of the return value through the virtual register. @@ -4754,15 +4748,19 @@ /// this value and returns the result as a ValueVT value. This uses /// Chain/Flag as the input and updates them for the output Chain/Flag. /// If the Flag pointer is NULL, no flag is used. -SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG, DebugLoc dl, +SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG, + FunctionLoweringInfo &FuncInfo, + DebugLoc dl, SDValue &Chain, SDValue *Flag) const { + const TargetLowering &TLI = DAG.getTargetLoweringInfo(); + // Assemble the legal parts into the final values. SmallVector Values(ValueVTs.size()); SmallVector Parts; for (unsigned Value = 0, Part = 0, e = ValueVTs.size(); Value != e; ++Value) { // Copy the legal parts from the registers. EVT ValueVT = ValueVTs[Value]; - unsigned NumRegs = TLI->getNumRegisters(*DAG.getContext(), ValueVT); + unsigned NumRegs = TLI.getNumRegisters(*DAG.getContext(), ValueVT); EVT RegisterVT = RegVTs[Value]; Parts.resize(NumRegs); @@ -4782,9 +4780,9 @@ if (TargetRegisterInfo::isVirtualRegister(Regs[Part+i]) && RegisterVT.isInteger() && !RegisterVT.isVector()) { unsigned SlotNo = Regs[Part+i]-TargetRegisterInfo::FirstVirtualRegister; - FunctionLoweringInfo &FLI = DAG.getFunctionLoweringInfo(); - if (FLI.LiveOutRegInfo.size() > SlotNo) { - FunctionLoweringInfo::LiveOutInfo &LOI = FLI.LiveOutRegInfo[SlotNo]; + if (FuncInfo.LiveOutRegInfo.size() > SlotNo) { + const FunctionLoweringInfo::LiveOutInfo &LOI = + FuncInfo.LiveOutRegInfo[SlotNo]; unsigned RegSize = RegisterVT.getSizeInBits(); unsigned NumSignBits = LOI.NumSignBits; @@ -4837,12 +4835,14 @@ /// If the Flag pointer is NULL, no flag is used. void RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG, DebugLoc dl, SDValue &Chain, SDValue *Flag) const { + const TargetLowering &TLI = DAG.getTargetLoweringInfo(); + // Get the list of the values's legal parts. unsigned NumRegs = Regs.size(); SmallVector Parts(NumRegs); for (unsigned Value = 0, Part = 0, e = ValueVTs.size(); Value != e; ++Value) { EVT ValueVT = ValueVTs[Value]; - unsigned NumParts = TLI->getNumRegisters(*DAG.getContext(), ValueVT); + unsigned NumParts = TLI.getNumRegisters(*DAG.getContext(), ValueVT); EVT RegisterVT = RegVTs[Value]; getCopyToParts(DAG, dl, @@ -4888,6 +4888,8 @@ unsigned MatchingIdx, SelectionDAG &DAG, std::vector &Ops) const { + const TargetLowering &TLI = DAG.getTargetLoweringInfo(); + unsigned Flag = InlineAsm::getFlagWord(Code, Regs.size()); if (HasMatching) Flag = InlineAsm::getFlagWordForMatchingOp(Flag, MatchingIdx); @@ -4895,7 +4897,7 @@ Ops.push_back(Res); for (unsigned Value = 0, Reg = 0, e = ValueVTs.size(); Value != e; ++Value) { - unsigned NumRegs = TLI->getNumRegisters(*DAG.getContext(), ValueVTs[Value]); + unsigned NumRegs = TLI.getNumRegisters(*DAG.getContext(), ValueVTs[Value]); EVT RegisterVT = RegVTs[Value]; for (unsigned i = 0; i != NumRegs; ++i) { assert(Reg < Regs.size() && "Mismatch in # registers expected"); @@ -5155,7 +5157,7 @@ } } - OpInfo.AssignedRegs = RegsForValue(TLI, Regs, RegVT, ValueVT); + OpInfo.AssignedRegs = RegsForValue(Regs, RegVT, ValueVT); const TargetRegisterInfo *TRI = DAG.getTarget().getRegisterInfo(); OpInfo.MarkAllocatedRegs(isOutReg, isInReg, OutputRegs, InputRegs, *TRI); return; @@ -5173,7 +5175,7 @@ for (; NumRegs; --NumRegs) Regs.push_back(RegInfo.createVirtualRegister(RC)); - OpInfo.AssignedRegs = RegsForValue(TLI, Regs, RegVT, ValueVT); + OpInfo.AssignedRegs = RegsForValue(Regs, RegVT, ValueVT); return; } @@ -5216,7 +5218,7 @@ for (unsigned i = RegStart; i != RegEnd; ++i) Regs.push_back(RegClassRegs[i]); - OpInfo.AssignedRegs = RegsForValue(TLI, Regs, *RC->vt_begin(), + OpInfo.AssignedRegs = RegsForValue(Regs, *RC->vt_begin(), OpInfo.ConstraintVT); OpInfo.MarkAllocatedRegs(isOutReg, isInReg, OutputRegs, InputRegs, *TRI); return; @@ -5498,7 +5500,6 @@ } RegsForValue MatchedRegs; - MatchedRegs.TLI = &TLI; MatchedRegs.ValueVTs.push_back(InOperandVal.getValueType()); EVT RegVT = AsmNodeOperands[CurOp+1].getValueType(); MatchedRegs.RegVTs.push_back(RegVT); @@ -5571,7 +5572,7 @@ // Copy the input into the appropriate registers. if (OpInfo.AssignedRegs.Regs.empty() || - !OpInfo.AssignedRegs.areValueTypesLegal()) + !OpInfo.AssignedRegs.areValueTypesLegal(TLI)) report_fatal_error("Couldn't allocate input reg for constraint '" + Twine(OpInfo.ConstraintCode) + "'!"); @@ -5607,7 +5608,7 @@ // If this asm returns a register value, copy the result from that register // and set it as the value of the call. if (!RetValRegs.Regs.empty()) { - SDValue Val = RetValRegs.getCopyFromRegs(DAG, getCurDebugLoc(), + SDValue Val = RetValRegs.getCopyFromRegs(DAG, FuncInfo, getCurDebugLoc(), Chain, &Flag); // FIXME: Why don't we do this for inline asms with MRVs? @@ -5647,7 +5648,7 @@ for (unsigned i = 0, e = IndirectStoresToEmit.size(); i != e; ++i) { RegsForValue &OutRegs = IndirectStoresToEmit[i].first; const Value *Ptr = IndirectStoresToEmit[i].second; - SDValue OutVal = OutRegs.getCopyFromRegs(DAG, getCurDebugLoc(), + SDValue OutVal = OutRegs.getCopyFromRegs(DAG, FuncInfo, getCurDebugLoc(), Chain, &Flag); StoresToEmit.push_back(std::make_pair(OutVal, Ptr)); } @@ -5905,11 +5906,11 @@ SmallVector OutsFlags; getReturnInfo(F.getReturnType(), F.getAttributes().getRetAttributes(), OutVTs, OutsFlags, TLI); - FunctionLoweringInfo &FLI = DAG.getFunctionLoweringInfo(); - FLI.CanLowerReturn = TLI.CanLowerReturn(F.getCallingConv(), F.isVarArg(), - OutVTs, OutsFlags, DAG); - if (!FLI.CanLowerReturn) { + FuncInfo->CanLowerReturn = TLI.CanLowerReturn(F.getCallingConv(), + F.isVarArg(), + OutVTs, OutsFlags, DAG); + if (!FuncInfo->CanLowerReturn) { // Put in an sret pointer parameter before all the other parameters. SmallVector ValueVTs; ComputeValueVTs(TLI, PointerType::getUnqual(F.getReturnType()), ValueVTs); @@ -6003,7 +6004,7 @@ // Set up the argument values. unsigned i = 0; Idx = 1; - if (!FLI.CanLowerReturn) { + if (!FuncInfo->CanLowerReturn) { // Create a virtual register for the sret pointer, and put in a copy // from the sret argument into it. SmallVector ValueVTs; @@ -6017,7 +6018,7 @@ MachineFunction& MF = SDB->DAG.getMachineFunction(); MachineRegisterInfo& RegInfo = MF.getRegInfo(); unsigned SRetReg = RegInfo.createVirtualRegister(TLI.getRegClassFor(RegVT)); - FLI.DemoteRegister = SRetReg; + FuncInfo->DemoteRegister = SRetReg; NewRoot = SDB->DAG.getCopyToReg(NewRoot, SDB->getCurDebugLoc(), SRetReg, ArgValue); DAG.setRoot(NewRoot); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=105101&r1=105100&r2=105101&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Sat May 29 12:03:36 2010 @@ -171,7 +171,7 @@ SelectionDAGISel::SelectionDAGISel(const TargetMachine &tm, CodeGenOpt::Level OL) : MachineFunctionPass(&ID), TM(tm), TLI(*tm.getTargetLowering()), FuncInfo(new FunctionLoweringInfo(TLI)), - CurDAG(new SelectionDAG(tm, *FuncInfo)), + CurDAG(new SelectionDAG(tm)), SDB(new SelectionDAGBuilder(*CurDAG, *FuncInfo, OL)), GFI(), OptLevel(OL), @@ -244,7 +244,7 @@ DEBUG(dbgs() << "\n\n\n=== " << Fn.getName() << "\n"); CurDAG->init(*MF); - FuncInfo->set(Fn, *MF, EnableFastISel); + FuncInfo->set(Fn, *MF); SDB->init(GFI, *AA); SelectAllBasicBlocks(Fn); From gohman at apple.com Sat May 29 12:53:24 2010 From: gohman at apple.com (Dan Gohman) Date: Sat, 29 May 2010 17:53:24 -0000 Subject: [llvm-commits] [llvm] r105105 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Message-ID: <20100529175324.9D8B4312800A@llvm.org> Author: djg Date: Sat May 29 12:53:24 2010 New Revision: 105105 URL: http://llvm.org/viewvc/llvm-project?rev=105105&view=rev Log: Reorder some code in SelectionDAGBuilder. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=105105&r1=105104&r2=105105&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Sat May 29 12:53:24 2010 @@ -70,108 +70,6 @@ cl::location(LimitFloatPrecision), cl::init(0)); -namespace { - /// RegsForValue - This struct represents the registers (physical or virtual) - /// that a particular set of values is assigned, and the type information - /// about the value. The most common situation is to represent one value at a - /// time, but struct or array values are handled element-wise as multiple - /// values. The splitting of aggregates is performed recursively, so that we - /// never have aggregate-typed registers. The values at this point do not - /// necessarily have legal types, so each value may require one or more - /// registers of some legal type. - /// - struct RegsForValue { - /// ValueVTs - The value types of the values, which may not be legal, and - /// may need be promoted or synthesized from one or more registers. - /// - SmallVector ValueVTs; - - /// RegVTs - The value types of the registers. This is the same size as - /// ValueVTs and it records, for each value, what the type of the assigned - /// register or registers are. (Individual values are never synthesized - /// from more than one type of register.) - /// - /// With virtual registers, the contents of RegVTs is redundant with TLI's - /// getRegisterType member function, however when with physical registers - /// it is necessary to have a separate record of the types. - /// - SmallVector RegVTs; - - /// Regs - This list holds the registers assigned to the values. - /// Each legal or promoted value requires one register, and each - /// expanded value requires multiple registers. - /// - SmallVector Regs; - - RegsForValue() {} - - RegsForValue(const SmallVector ®s, - EVT regvt, EVT valuevt) - : ValueVTs(1, valuevt), RegVTs(1, regvt), Regs(regs) {} - - RegsForValue(const SmallVector ®s, - const SmallVector ®vts, - const SmallVector &valuevts) - : ValueVTs(valuevts), RegVTs(regvts), Regs(regs) {} - - RegsForValue(LLVMContext &Context, const TargetLowering &tli, - unsigned Reg, const Type *Ty) { - ComputeValueVTs(tli, Ty, ValueVTs); - - for (unsigned Value = 0, e = ValueVTs.size(); Value != e; ++Value) { - EVT ValueVT = ValueVTs[Value]; - unsigned NumRegs = tli.getNumRegisters(Context, ValueVT); - EVT RegisterVT = tli.getRegisterType(Context, ValueVT); - for (unsigned i = 0; i != NumRegs; ++i) - Regs.push_back(Reg + i); - RegVTs.push_back(RegisterVT); - Reg += NumRegs; - } - } - - /// areValueTypesLegal - Return true if types of all the values are legal. - bool areValueTypesLegal(const TargetLowering &TLI) { - for (unsigned Value = 0, e = ValueVTs.size(); Value != e; ++Value) { - EVT RegisterVT = RegVTs[Value]; - if (!TLI.isTypeLegal(RegisterVT)) - return false; - } - return true; - } - - /// append - Add the specified values to this one. - void append(const RegsForValue &RHS) { - ValueVTs.append(RHS.ValueVTs.begin(), RHS.ValueVTs.end()); - RegVTs.append(RHS.RegVTs.begin(), RHS.RegVTs.end()); - Regs.append(RHS.Regs.begin(), RHS.Regs.end()); - } - - - /// getCopyFromRegs - Emit a series of CopyFromReg nodes that copies from - /// this value and returns the result as a ValueVTs value. This uses - /// Chain/Flag as the input and updates them for the output Chain/Flag. - /// If the Flag pointer is NULL, no flag is used. - SDValue getCopyFromRegs(SelectionDAG &DAG, FunctionLoweringInfo &FuncInfo, - DebugLoc dl, - SDValue &Chain, SDValue *Flag) const; - - /// getCopyToRegs - Emit a series of CopyToReg nodes that copies the - /// specified value into the registers specified by this object. This uses - /// Chain/Flag as the input and updates them for the output Chain/Flag. - /// If the Flag pointer is NULL, no flag is used. - void getCopyToRegs(SDValue Val, SelectionDAG &DAG, DebugLoc dl, - SDValue &Chain, SDValue *Flag) const; - - /// AddInlineAsmOperands - Add this value to the specified inlineasm node - /// operand list. This adds the code marker, matching input operand index - /// (if applicable), and includes the number of values added into it. - void AddInlineAsmOperands(unsigned Kind, - bool HasMatching, unsigned MatchingIdx, - SelectionDAG &DAG, - std::vector &Ops) const; - }; -} - /// getCopyFromParts - Create a value that contains the specified legal parts /// combined into the value they represent. If the parts combine to a type /// larger then ValueVT then AssertOp can be used to specify whether the extra @@ -523,2418 +421,2680 @@ } } +namespace { + /// RegsForValue - This struct represents the registers (physical or virtual) + /// that a particular set of values is assigned, and the type information + /// about the value. The most common situation is to represent one value at a + /// time, but struct or array values are handled element-wise as multiple + /// values. The splitting of aggregates is performed recursively, so that we + /// never have aggregate-typed registers. The values at this point do not + /// necessarily have legal types, so each value may require one or more + /// registers of some legal type. + /// + struct RegsForValue { + /// ValueVTs - The value types of the values, which may not be legal, and + /// may need be promoted or synthesized from one or more registers. + /// + SmallVector ValueVTs; -void SelectionDAGBuilder::init(GCFunctionInfo *gfi, AliasAnalysis &aa) { - AA = &aa; - GFI = gfi; - TD = DAG.getTarget().getTargetData(); -} - -/// clear - Clear out the current SelectionDAG and the associated -/// state and prepare this SelectionDAGBuilder object to be used -/// for a new block. This doesn't clear out information about -/// additional blocks that are needed to complete switch lowering -/// or PHI node updating; that information is cleared out as it is -/// consumed. -void SelectionDAGBuilder::clear() { - NodeMap.clear(); - PendingLoads.clear(); - PendingExports.clear(); - CurDebugLoc = DebugLoc(); - HasTailCall = false; -} + /// RegVTs - The value types of the registers. This is the same size as + /// ValueVTs and it records, for each value, what the type of the assigned + /// register or registers are. (Individual values are never synthesized + /// from more than one type of register.) + /// + /// With virtual registers, the contents of RegVTs is redundant with TLI's + /// getRegisterType member function, however when with physical registers + /// it is necessary to have a separate record of the types. + /// + SmallVector RegVTs; -/// getRoot - Return the current virtual root of the Selection DAG, -/// flushing any PendingLoad items. This must be done before emitting -/// a store or any other node that may need to be ordered after any -/// prior load instructions. -/// -SDValue SelectionDAGBuilder::getRoot() { - if (PendingLoads.empty()) - return DAG.getRoot(); + /// Regs - This list holds the registers assigned to the values. + /// Each legal or promoted value requires one register, and each + /// expanded value requires multiple registers. + /// + SmallVector Regs; - if (PendingLoads.size() == 1) { - SDValue Root = PendingLoads[0]; - DAG.setRoot(Root); - PendingLoads.clear(); - return Root; - } + RegsForValue() {} - // Otherwise, we have to make a token factor node. - SDValue Root = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(), MVT::Other, - &PendingLoads[0], PendingLoads.size()); - PendingLoads.clear(); - DAG.setRoot(Root); - return Root; -} + RegsForValue(const SmallVector ®s, + EVT regvt, EVT valuevt) + : ValueVTs(1, valuevt), RegVTs(1, regvt), Regs(regs) {} -/// getControlRoot - Similar to getRoot, but instead of flushing all the -/// PendingLoad items, flush all the PendingExports items. It is necessary -/// to do this before emitting a terminator instruction. -/// -SDValue SelectionDAGBuilder::getControlRoot() { - SDValue Root = DAG.getRoot(); + RegsForValue(const SmallVector ®s, + const SmallVector ®vts, + const SmallVector &valuevts) + : ValueVTs(valuevts), RegVTs(regvts), Regs(regs) {} - if (PendingExports.empty()) - return Root; + RegsForValue(LLVMContext &Context, const TargetLowering &tli, + unsigned Reg, const Type *Ty) { + ComputeValueVTs(tli, Ty, ValueVTs); - // Turn all of the CopyToReg chains into one factored node. - if (Root.getOpcode() != ISD::EntryToken) { - unsigned i = 0, e = PendingExports.size(); - for (; i != e; ++i) { - assert(PendingExports[i].getNode()->getNumOperands() > 1); - if (PendingExports[i].getNode()->getOperand(0) == Root) - break; // Don't add the root if we already indirectly depend on it. + for (unsigned Value = 0, e = ValueVTs.size(); Value != e; ++Value) { + EVT ValueVT = ValueVTs[Value]; + unsigned NumRegs = tli.getNumRegisters(Context, ValueVT); + EVT RegisterVT = tli.getRegisterType(Context, ValueVT); + for (unsigned i = 0; i != NumRegs; ++i) + Regs.push_back(Reg + i); + RegVTs.push_back(RegisterVT); + Reg += NumRegs; + } } - if (i == e) - PendingExports.push_back(Root); - } - - Root = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(), MVT::Other, - &PendingExports[0], - PendingExports.size()); - PendingExports.clear(); - DAG.setRoot(Root); - return Root; -} + /// areValueTypesLegal - Return true if types of all the values are legal. + bool areValueTypesLegal(const TargetLowering &TLI) { + for (unsigned Value = 0, e = ValueVTs.size(); Value != e; ++Value) { + EVT RegisterVT = RegVTs[Value]; + if (!TLI.isTypeLegal(RegisterVT)) + return false; + } + return true; + } -void SelectionDAGBuilder::AssignOrderingToNode(const SDNode *Node) { - if (DAG.GetOrdering(Node) != 0) return; // Already has ordering. - DAG.AssignOrdering(Node, SDNodeOrder); + /// append - Add the specified values to this one. + void append(const RegsForValue &RHS) { + ValueVTs.append(RHS.ValueVTs.begin(), RHS.ValueVTs.end()); + RegVTs.append(RHS.RegVTs.begin(), RHS.RegVTs.end()); + Regs.append(RHS.Regs.begin(), RHS.Regs.end()); + } - for (unsigned I = 0, E = Node->getNumOperands(); I != E; ++I) - AssignOrderingToNode(Node->getOperand(I).getNode()); -} + /// getCopyFromRegs - Emit a series of CopyFromReg nodes that copies from + /// this value and returns the result as a ValueVTs value. This uses + /// Chain/Flag as the input and updates them for the output Chain/Flag. + /// If the Flag pointer is NULL, no flag is used. + SDValue getCopyFromRegs(SelectionDAG &DAG, FunctionLoweringInfo &FuncInfo, + DebugLoc dl, + SDValue &Chain, SDValue *Flag) const; -void SelectionDAGBuilder::visit(const Instruction &I) { - // Set up outgoing PHI node register values before emitting the terminator. - if (isa(&I)) - HandlePHINodesInSuccessorBlocks(I.getParent()); + /// getCopyToRegs - Emit a series of CopyToReg nodes that copies the + /// specified value into the registers specified by this object. This uses + /// Chain/Flag as the input and updates them for the output Chain/Flag. + /// If the Flag pointer is NULL, no flag is used. + void getCopyToRegs(SDValue Val, SelectionDAG &DAG, DebugLoc dl, + SDValue &Chain, SDValue *Flag) const; - CurDebugLoc = I.getDebugLoc(); - - visit(I.getOpcode(), I); - - if (!isa(&I) && !HasTailCall) - CopyToExportRegsIfNeeded(&I); - - CurDebugLoc = DebugLoc(); -} - -void SelectionDAGBuilder::visitPHI(const PHINode &) { - llvm_unreachable("SelectionDAGBuilder shouldn't visit PHI nodes!"); -} - -void SelectionDAGBuilder::visit(unsigned Opcode, const User &I) { - // Note: this doesn't use InstVisitor, because it has to work with - // ConstantExpr's in addition to instructions. - switch (Opcode) { - default: llvm_unreachable("Unknown instruction type encountered!"); - // Build the switch statement using the Instruction.def file. -#define HANDLE_INST(NUM, OPCODE, CLASS) \ - case Instruction::OPCODE: visit##OPCODE((CLASS&)I); break; -#include "llvm/Instruction.def" - } - - // Assign the ordering to the freshly created DAG nodes. - if (NodeMap.count(&I)) { - ++SDNodeOrder; - AssignOrderingToNode(getValue(&I).getNode()); - } + /// AddInlineAsmOperands - Add this value to the specified inlineasm node + /// operand list. This adds the code marker, matching input operand index + /// (if applicable), and includes the number of values added into it. + void AddInlineAsmOperands(unsigned Kind, + bool HasMatching, unsigned MatchingIdx, + SelectionDAG &DAG, + std::vector &Ops) const; + }; } -SDValue SelectionDAGBuilder::getValue(const Value *V) { - SDValue &N = NodeMap[V]; - if (N.getNode()) return N; - - if (const Constant *C = dyn_cast(V)) { - EVT VT = TLI.getValueType(V->getType(), true); +/// getCopyFromRegs - Emit a series of CopyFromReg nodes that copies from +/// this value and returns the result as a ValueVT value. This uses +/// Chain/Flag as the input and updates them for the output Chain/Flag. +/// If the Flag pointer is NULL, no flag is used. +SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG, + FunctionLoweringInfo &FuncInfo, + DebugLoc dl, + SDValue &Chain, SDValue *Flag) const { + const TargetLowering &TLI = DAG.getTargetLoweringInfo(); - if (const ConstantInt *CI = dyn_cast(C)) - return N = DAG.getConstant(*CI, VT); + // Assemble the legal parts into the final values. + SmallVector Values(ValueVTs.size()); + SmallVector Parts; + for (unsigned Value = 0, Part = 0, e = ValueVTs.size(); Value != e; ++Value) { + // Copy the legal parts from the registers. + EVT ValueVT = ValueVTs[Value]; + unsigned NumRegs = TLI.getNumRegisters(*DAG.getContext(), ValueVT); + EVT RegisterVT = RegVTs[Value]; - if (const GlobalValue *GV = dyn_cast(C)) - return N = DAG.getGlobalAddress(GV, VT); + Parts.resize(NumRegs); + for (unsigned i = 0; i != NumRegs; ++i) { + SDValue P; + if (Flag == 0) { + P = DAG.getCopyFromReg(Chain, dl, Regs[Part+i], RegisterVT); + } else { + P = DAG.getCopyFromReg(Chain, dl, Regs[Part+i], RegisterVT, *Flag); + *Flag = P.getValue(2); + } - if (isa(C)) - return N = DAG.getConstant(0, TLI.getPointerTy()); + Chain = P.getValue(1); - if (const ConstantFP *CFP = dyn_cast(C)) - return N = DAG.getConstantFP(*CFP, VT); + // If the source register was virtual and if we know something about it, + // add an assert node. + if (TargetRegisterInfo::isVirtualRegister(Regs[Part+i]) && + RegisterVT.isInteger() && !RegisterVT.isVector()) { + unsigned SlotNo = Regs[Part+i]-TargetRegisterInfo::FirstVirtualRegister; + if (FuncInfo.LiveOutRegInfo.size() > SlotNo) { + const FunctionLoweringInfo::LiveOutInfo &LOI = + FuncInfo.LiveOutRegInfo[SlotNo]; - if (isa(C) && !V->getType()->isAggregateType()) - return N = DAG.getUNDEF(VT); + unsigned RegSize = RegisterVT.getSizeInBits(); + unsigned NumSignBits = LOI.NumSignBits; + unsigned NumZeroBits = LOI.KnownZero.countLeadingOnes(); - if (const ConstantExpr *CE = dyn_cast(C)) { - visit(CE->getOpcode(), *CE); - SDValue N1 = NodeMap[V]; - assert(N1.getNode() && "visit didn't populate the NodeMap!"); - return N1; - } + // FIXME: We capture more information than the dag can represent. For + // now, just use the tightest assertzext/assertsext possible. + bool isSExt = true; + EVT FromVT(MVT::Other); + if (NumSignBits == RegSize) + isSExt = true, FromVT = MVT::i1; // ASSERT SEXT 1 + else if (NumZeroBits >= RegSize-1) + isSExt = false, FromVT = MVT::i1; // ASSERT ZEXT 1 + else if (NumSignBits > RegSize-8) + isSExt = true, FromVT = MVT::i8; // ASSERT SEXT 8 + else if (NumZeroBits >= RegSize-8) + isSExt = false, FromVT = MVT::i8; // ASSERT ZEXT 8 + else if (NumSignBits > RegSize-16) + isSExt = true, FromVT = MVT::i16; // ASSERT SEXT 16 + else if (NumZeroBits >= RegSize-16) + isSExt = false, FromVT = MVT::i16; // ASSERT ZEXT 16 + else if (NumSignBits > RegSize-32) + isSExt = true, FromVT = MVT::i32; // ASSERT SEXT 32 + else if (NumZeroBits >= RegSize-32) + isSExt = false, FromVT = MVT::i32; // ASSERT ZEXT 32 - if (isa(C) || isa(C)) { - SmallVector Constants; - for (User::const_op_iterator OI = C->op_begin(), OE = C->op_end(); - OI != OE; ++OI) { - SDNode *Val = getValue(*OI).getNode(); - // If the operand is an empty aggregate, there are no values. - if (!Val) continue; - // Add each leaf value from the operand to the Constants list - // to form a flattened list of all the values. - for (unsigned i = 0, e = Val->getNumValues(); i != e; ++i) - Constants.push_back(SDValue(Val, i)); + if (FromVT != MVT::Other) + P = DAG.getNode(isSExt ? ISD::AssertSext : ISD::AssertZext, dl, + RegisterVT, P, DAG.getValueType(FromVT)); + } } - return DAG.getMergeValues(&Constants[0], Constants.size(), - getCurDebugLoc()); + Parts[i] = P; } - if (C->getType()->isStructTy() || C->getType()->isArrayTy()) { - assert((isa(C) || isa(C)) && - "Unknown struct or array constant!"); + Values[Value] = getCopyFromParts(DAG, dl, Parts.begin(), + NumRegs, RegisterVT, ValueVT); + Part += NumRegs; + Parts.clear(); + } - SmallVector ValueVTs; - ComputeValueVTs(TLI, C->getType(), ValueVTs); - unsigned NumElts = ValueVTs.size(); - if (NumElts == 0) - return SDValue(); // empty struct - SmallVector Constants(NumElts); - for (unsigned i = 0; i != NumElts; ++i) { - EVT EltVT = ValueVTs[i]; - if (isa(C)) - Constants[i] = DAG.getUNDEF(EltVT); - else if (EltVT.isFloatingPoint()) - Constants[i] = DAG.getConstantFP(0, EltVT); - else - Constants[i] = DAG.getConstant(0, EltVT); - } + return DAG.getNode(ISD::MERGE_VALUES, dl, + DAG.getVTList(&ValueVTs[0], ValueVTs.size()), + &Values[0], ValueVTs.size()); +} - return DAG.getMergeValues(&Constants[0], NumElts, - getCurDebugLoc()); - } +/// getCopyToRegs - Emit a series of CopyToReg nodes that copies the +/// specified value into the registers specified by this object. This uses +/// Chain/Flag as the input and updates them for the output Chain/Flag. +/// If the Flag pointer is NULL, no flag is used. +void RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG, DebugLoc dl, + SDValue &Chain, SDValue *Flag) const { + const TargetLowering &TLI = DAG.getTargetLoweringInfo(); - if (const BlockAddress *BA = dyn_cast(C)) - return DAG.getBlockAddress(BA, VT); + // Get the list of the values's legal parts. + unsigned NumRegs = Regs.size(); + SmallVector Parts(NumRegs); + for (unsigned Value = 0, Part = 0, e = ValueVTs.size(); Value != e; ++Value) { + EVT ValueVT = ValueVTs[Value]; + unsigned NumParts = TLI.getNumRegisters(*DAG.getContext(), ValueVT); + EVT RegisterVT = RegVTs[Value]; - const VectorType *VecTy = cast(V->getType()); - unsigned NumElements = VecTy->getNumElements(); + getCopyToParts(DAG, dl, + Val.getValue(Val.getResNo() + Value), + &Parts[Part], NumParts, RegisterVT); + Part += NumParts; + } - // Now that we know the number and type of the elements, get that number of - // elements into the Ops array based on what kind of constant it is. - SmallVector Ops; - if (const ConstantVector *CP = dyn_cast(C)) { - for (unsigned i = 0; i != NumElements; ++i) - Ops.push_back(getValue(CP->getOperand(i))); + // Copy the parts into the registers. + SmallVector Chains(NumRegs); + for (unsigned i = 0; i != NumRegs; ++i) { + SDValue Part; + if (Flag == 0) { + Part = DAG.getCopyToReg(Chain, dl, Regs[i], Parts[i]); } else { - assert(isa(C) && "Unknown vector constant!"); - EVT EltVT = TLI.getValueType(VecTy->getElementType()); - - SDValue Op; - if (EltVT.isFloatingPoint()) - Op = DAG.getConstantFP(0, EltVT); - else - Op = DAG.getConstant(0, EltVT); - Ops.assign(NumElements, Op); + Part = DAG.getCopyToReg(Chain, dl, Regs[i], Parts[i], *Flag); + *Flag = Part.getValue(1); } - // Create a BUILD_VECTOR node. - return NodeMap[V] = DAG.getNode(ISD::BUILD_VECTOR, getCurDebugLoc(), - VT, &Ops[0], Ops.size()); - } - - // If this is a static alloca, generate it as the frameindex instead of - // computation. - if (const AllocaInst *AI = dyn_cast(V)) { - DenseMap::iterator SI = - FuncInfo.StaticAllocaMap.find(AI); - if (SI != FuncInfo.StaticAllocaMap.end()) - return DAG.getFrameIndex(SI->second, TLI.getPointerTy()); + Chains[i] = Part.getValue(0); } - unsigned InReg = FuncInfo.ValueMap[V]; - assert(InReg && "Value not in map!"); - - RegsForValue RFV(*DAG.getContext(), TLI, InReg, V->getType()); - SDValue Chain = DAG.getEntryNode(); - return RFV.getCopyFromRegs(DAG, FuncInfo, getCurDebugLoc(), Chain, NULL); + if (NumRegs == 1 || Flag) + // If NumRegs > 1 && Flag is used then the use of the last CopyToReg is + // flagged to it. That is the CopyToReg nodes and the user are considered + // a single scheduling unit. If we create a TokenFactor and return it as + // chain, then the TokenFactor is both a predecessor (operand) of the + // user as well as a successor (the TF operands are flagged to the user). + // c1, f1 = CopyToReg + // c2, f2 = CopyToReg + // c3 = TokenFactor c1, c2 + // ... + // = op c3, ..., f2 + Chain = Chains[NumRegs-1]; + else + Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Chains[0], NumRegs); } -/// Get the EVTs and ArgFlags collections that represent the legalized return -/// type of the given function. This does not require a DAG or a return value, -/// and is suitable for use before any DAGs for the function are constructed. -static void getReturnInfo(const Type* ReturnType, - Attributes attr, SmallVectorImpl &OutVTs, - SmallVectorImpl &OutFlags, - const TargetLowering &TLI, - SmallVectorImpl *Offsets = 0) { - SmallVector ValueVTs; - ComputeValueVTs(TLI, ReturnType, ValueVTs); - unsigned NumValues = ValueVTs.size(); - if (NumValues == 0) return; - unsigned Offset = 0; - - for (unsigned j = 0, f = NumValues; j != f; ++j) { - EVT VT = ValueVTs[j]; - ISD::NodeType ExtendKind = ISD::ANY_EXTEND; +/// AddInlineAsmOperands - Add this value to the specified inlineasm node +/// operand list. This adds the code marker and includes the number of +/// values added into it. +void RegsForValue::AddInlineAsmOperands(unsigned Code, bool HasMatching, + unsigned MatchingIdx, + SelectionDAG &DAG, + std::vector &Ops) const { + const TargetLowering &TLI = DAG.getTargetLoweringInfo(); - if (attr & Attribute::SExt) - ExtendKind = ISD::SIGN_EXTEND; - else if (attr & Attribute::ZExt) - ExtendKind = ISD::ZERO_EXTEND; + unsigned Flag = InlineAsm::getFlagWord(Code, Regs.size()); + if (HasMatching) + Flag = InlineAsm::getFlagWordForMatchingOp(Flag, MatchingIdx); + SDValue Res = DAG.getTargetConstant(Flag, MVT::i32); + Ops.push_back(Res); - // FIXME: C calling convention requires the return type to be promoted to - // at least 32-bit. But this is not necessary for non-C calling - // conventions. The frontend should mark functions whose return values - // require promoting with signext or zeroext attributes. - if (ExtendKind != ISD::ANY_EXTEND && VT.isInteger()) { - EVT MinVT = TLI.getRegisterType(ReturnType->getContext(), MVT::i32); - if (VT.bitsLT(MinVT)) - VT = MinVT; + for (unsigned Value = 0, Reg = 0, e = ValueVTs.size(); Value != e; ++Value) { + unsigned NumRegs = TLI.getNumRegisters(*DAG.getContext(), ValueVTs[Value]); + EVT RegisterVT = RegVTs[Value]; + for (unsigned i = 0; i != NumRegs; ++i) { + assert(Reg < Regs.size() && "Mismatch in # registers expected"); + Ops.push_back(DAG.getRegister(Regs[Reg++], RegisterVT)); } + } +} - unsigned NumParts = TLI.getNumRegisters(ReturnType->getContext(), VT); - EVT PartVT = TLI.getRegisterType(ReturnType->getContext(), VT); - unsigned PartSize = TLI.getTargetData()->getTypeAllocSize( - PartVT.getTypeForEVT(ReturnType->getContext())); - - // 'inreg' on function refers to return value - ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy(); - if (attr & Attribute::InReg) - Flags.setInReg(); - - // Propagate extension type if any - if (attr & Attribute::SExt) - Flags.setSExt(); - else if (attr & Attribute::ZExt) - Flags.setZExt(); +void SelectionDAGBuilder::init(GCFunctionInfo *gfi, AliasAnalysis &aa) { + AA = &aa; + GFI = gfi; + TD = DAG.getTarget().getTargetData(); +} - for (unsigned i = 0; i < NumParts; ++i) { - OutVTs.push_back(PartVT); - OutFlags.push_back(Flags); - if (Offsets) - { - Offsets->push_back(Offset); - Offset += PartSize; - } - } - } +/// clear - Clear out the current SelectionDAG and the associated +/// state and prepare this SelectionDAGBuilder object to be used +/// for a new block. This doesn't clear out information about +/// additional blocks that are needed to complete switch lowering +/// or PHI node updating; that information is cleared out as it is +/// consumed. +void SelectionDAGBuilder::clear() { + NodeMap.clear(); + PendingLoads.clear(); + PendingExports.clear(); + CurDebugLoc = DebugLoc(); + HasTailCall = false; } -void SelectionDAGBuilder::visitRet(const ReturnInst &I) { - SDValue Chain = getControlRoot(); - SmallVector Outs; +/// getRoot - Return the current virtual root of the Selection DAG, +/// flushing any PendingLoad items. This must be done before emitting +/// a store or any other node that may need to be ordered after any +/// prior load instructions. +/// +SDValue SelectionDAGBuilder::getRoot() { + if (PendingLoads.empty()) + return DAG.getRoot(); - if (!FuncInfo.CanLowerReturn) { - unsigned DemoteReg = FuncInfo.DemoteRegister; - const Function *F = I.getParent()->getParent(); + if (PendingLoads.size() == 1) { + SDValue Root = PendingLoads[0]; + DAG.setRoot(Root); + PendingLoads.clear(); + return Root; + } - // Emit a store of the return value through the virtual register. - // Leave Outs empty so that LowerReturn won't try to load return - // registers the usual way. - SmallVector PtrValueVTs; - ComputeValueVTs(TLI, PointerType::getUnqual(F->getReturnType()), - PtrValueVTs); + // Otherwise, we have to make a token factor node. + SDValue Root = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(), MVT::Other, + &PendingLoads[0], PendingLoads.size()); + PendingLoads.clear(); + DAG.setRoot(Root); + return Root; +} - SDValue RetPtr = DAG.getRegister(DemoteReg, PtrValueVTs[0]); - SDValue RetOp = getValue(I.getOperand(0)); +/// getControlRoot - Similar to getRoot, but instead of flushing all the +/// PendingLoad items, flush all the PendingExports items. It is necessary +/// to do this before emitting a terminator instruction. +/// +SDValue SelectionDAGBuilder::getControlRoot() { + SDValue Root = DAG.getRoot(); - SmallVector ValueVTs; - SmallVector Offsets; - ComputeValueVTs(TLI, I.getOperand(0)->getType(), ValueVTs, &Offsets); - unsigned NumValues = ValueVTs.size(); + if (PendingExports.empty()) + return Root; - SmallVector Chains(NumValues); - EVT PtrVT = PtrValueVTs[0]; - for (unsigned i = 0; i != NumValues; ++i) { - SDValue Add = DAG.getNode(ISD::ADD, getCurDebugLoc(), PtrVT, RetPtr, - DAG.getConstant(Offsets[i], PtrVT)); - Chains[i] = - DAG.getStore(Chain, getCurDebugLoc(), - SDValue(RetOp.getNode(), RetOp.getResNo() + i), - Add, NULL, Offsets[i], false, false, 0); + // Turn all of the CopyToReg chains into one factored node. + if (Root.getOpcode() != ISD::EntryToken) { + unsigned i = 0, e = PendingExports.size(); + for (; i != e; ++i) { + assert(PendingExports[i].getNode()->getNumOperands() > 1); + if (PendingExports[i].getNode()->getOperand(0) == Root) + break; // Don't add the root if we already indirectly depend on it. } - Chain = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(), - MVT::Other, &Chains[0], NumValues); - } else if (I.getNumOperands() != 0) { - SmallVector ValueVTs; - ComputeValueVTs(TLI, I.getOperand(0)->getType(), ValueVTs); - unsigned NumValues = ValueVTs.size(); - if (NumValues) { - SDValue RetOp = getValue(I.getOperand(0)); - for (unsigned j = 0, f = NumValues; j != f; ++j) { - EVT VT = ValueVTs[j]; - - ISD::NodeType ExtendKind = ISD::ANY_EXTEND; + if (i == e) + PendingExports.push_back(Root); + } - const Function *F = I.getParent()->getParent(); - if (F->paramHasAttr(0, Attribute::SExt)) - ExtendKind = ISD::SIGN_EXTEND; - else if (F->paramHasAttr(0, Attribute::ZExt)) - ExtendKind = ISD::ZERO_EXTEND; + Root = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(), MVT::Other, + &PendingExports[0], + PendingExports.size()); + PendingExports.clear(); + DAG.setRoot(Root); + return Root; +} - // FIXME: C calling convention requires the return type to be promoted - // to at least 32-bit. But this is not necessary for non-C calling - // conventions. The frontend should mark functions whose return values - // require promoting with signext or zeroext attributes. - if (ExtendKind != ISD::ANY_EXTEND && VT.isInteger()) { - EVT MinVT = TLI.getRegisterType(*DAG.getContext(), MVT::i32); - if (VT.bitsLT(MinVT)) - VT = MinVT; - } +void SelectionDAGBuilder::AssignOrderingToNode(const SDNode *Node) { + if (DAG.GetOrdering(Node) != 0) return; // Already has ordering. + DAG.AssignOrdering(Node, SDNodeOrder); - unsigned NumParts = TLI.getNumRegisters(*DAG.getContext(), VT); - EVT PartVT = TLI.getRegisterType(*DAG.getContext(), VT); - SmallVector Parts(NumParts); - getCopyToParts(DAG, getCurDebugLoc(), - SDValue(RetOp.getNode(), RetOp.getResNo() + j), - &Parts[0], NumParts, PartVT, ExtendKind); + for (unsigned I = 0, E = Node->getNumOperands(); I != E; ++I) + AssignOrderingToNode(Node->getOperand(I).getNode()); +} - // 'inreg' on function refers to return value - ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy(); - if (F->paramHasAttr(0, Attribute::InReg)) - Flags.setInReg(); +void SelectionDAGBuilder::visit(const Instruction &I) { + // Set up outgoing PHI node register values before emitting the terminator. + if (isa(&I)) + HandlePHINodesInSuccessorBlocks(I.getParent()); - // Propagate extension type if any - if (F->paramHasAttr(0, Attribute::SExt)) - Flags.setSExt(); - else if (F->paramHasAttr(0, Attribute::ZExt)) - Flags.setZExt(); + CurDebugLoc = I.getDebugLoc(); - for (unsigned i = 0; i < NumParts; ++i) - Outs.push_back(ISD::OutputArg(Flags, Parts[i], /*isfixed=*/true)); - } - } - } + visit(I.getOpcode(), I); - bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg(); - CallingConv::ID CallConv = - DAG.getMachineFunction().getFunction()->getCallingConv(); - Chain = TLI.LowerReturn(Chain, CallConv, isVarArg, - Outs, getCurDebugLoc(), DAG); + if (!isa(&I) && !HasTailCall) + CopyToExportRegsIfNeeded(&I); - // Verify that the target's LowerReturn behaved as expected. - assert(Chain.getNode() && Chain.getValueType() == MVT::Other && - "LowerReturn didn't return a valid chain!"); + CurDebugLoc = DebugLoc(); +} - // Update the DAG with the new chain value resulting from return lowering. - DAG.setRoot(Chain); +void SelectionDAGBuilder::visitPHI(const PHINode &) { + llvm_unreachable("SelectionDAGBuilder shouldn't visit PHI nodes!"); } -/// CopyToExportRegsIfNeeded - If the given value has virtual registers -/// created for it, emit nodes to copy the value into the virtual -/// registers. -void SelectionDAGBuilder::CopyToExportRegsIfNeeded(const Value *V) { - DenseMap::iterator VMI = FuncInfo.ValueMap.find(V); - if (VMI != FuncInfo.ValueMap.end()) { - assert(!V->use_empty() && "Unused value assigned virtual registers!"); - CopyValueToVirtualRegister(V, VMI->second); +void SelectionDAGBuilder::visit(unsigned Opcode, const User &I) { + // Note: this doesn't use InstVisitor, because it has to work with + // ConstantExpr's in addition to instructions. + switch (Opcode) { + default: llvm_unreachable("Unknown instruction type encountered!"); + // Build the switch statement using the Instruction.def file. +#define HANDLE_INST(NUM, OPCODE, CLASS) \ + case Instruction::OPCODE: visit##OPCODE((CLASS&)I); break; +#include "llvm/Instruction.def" + } + + // Assign the ordering to the freshly created DAG nodes. + if (NodeMap.count(&I)) { + ++SDNodeOrder; + AssignOrderingToNode(getValue(&I).getNode()); } } -/// ExportFromCurrentBlock - If this condition isn't known to be exported from -/// the current basic block, add it to ValueMap now so that we'll get a -/// CopyTo/FromReg. -void SelectionDAGBuilder::ExportFromCurrentBlock(const Value *V) { - // No need to export constants. - if (!isa(V) && !isa(V)) return; - - // Already exported? - if (FuncInfo.isExportedInst(V)) return; - - unsigned Reg = FuncInfo.InitializeRegForValue(V); - CopyValueToVirtualRegister(V, Reg); -} +SDValue SelectionDAGBuilder::getValue(const Value *V) { + SDValue &N = NodeMap[V]; + if (N.getNode()) return N; -bool SelectionDAGBuilder::isExportableFromCurrentBlock(const Value *V, - const BasicBlock *FromBB) { - // The operands of the setcc have to be in this block. We don't know - // how to export them from some other block. - if (const Instruction *VI = dyn_cast(V)) { - // Can export from current BB. - if (VI->getParent() == FromBB) - return true; + if (const Constant *C = dyn_cast(V)) { + EVT VT = TLI.getValueType(V->getType(), true); - // Is already exported, noop. - return FuncInfo.isExportedInst(V); - } + if (const ConstantInt *CI = dyn_cast(C)) + return N = DAG.getConstant(*CI, VT); - // If this is an argument, we can export it if the BB is the entry block or - // if it is already exported. - if (isa(V)) { - if (FromBB == &FromBB->getParent()->getEntryBlock()) - return true; + if (const GlobalValue *GV = dyn_cast(C)) + return N = DAG.getGlobalAddress(GV, VT); - // Otherwise, can only export this if it is already exported. - return FuncInfo.isExportedInst(V); - } + if (isa(C)) + return N = DAG.getConstant(0, TLI.getPointerTy()); - // Otherwise, constants can always be exported. - return true; -} + if (const ConstantFP *CFP = dyn_cast(C)) + return N = DAG.getConstantFP(*CFP, VT); -static bool InBlock(const Value *V, const BasicBlock *BB) { - if (const Instruction *I = dyn_cast(V)) - return I->getParent() == BB; - return true; -} + if (isa(C) && !V->getType()->isAggregateType()) + return N = DAG.getUNDEF(VT); -/// EmitBranchForMergedCondition - Helper method for FindMergedConditions. -/// This function emits a branch and is used at the leaves of an OR or an -/// AND operator tree. -/// -void -SelectionDAGBuilder::EmitBranchForMergedCondition(const Value *Cond, - MachineBasicBlock *TBB, - MachineBasicBlock *FBB, - MachineBasicBlock *CurBB, - MachineBasicBlock *SwitchBB) { - const BasicBlock *BB = CurBB->getBasicBlock(); + if (const ConstantExpr *CE = dyn_cast(C)) { + visit(CE->getOpcode(), *CE); + SDValue N1 = NodeMap[V]; + assert(N1.getNode() && "visit didn't populate the NodeMap!"); + return N1; + } - // If the leaf of the tree is a comparison, merge the condition into - // the caseblock. - if (const CmpInst *BOp = dyn_cast(Cond)) { - // The operands of the cmp have to be in this block. We don't know - // how to export them from some other block. If this is the first block - // of the sequence, no exporting is needed. - if (CurBB == SwitchBB || - (isExportableFromCurrentBlock(BOp->getOperand(0), BB) && - isExportableFromCurrentBlock(BOp->getOperand(1), BB))) { - ISD::CondCode Condition; - if (const ICmpInst *IC = dyn_cast(Cond)) { - Condition = getICmpCondCode(IC->getPredicate()); - } else if (const FCmpInst *FC = dyn_cast(Cond)) { - Condition = getFCmpCondCode(FC->getPredicate()); - } else { - Condition = ISD::SETEQ; // silence warning. - llvm_unreachable("Unknown compare instruction"); + if (isa(C) || isa(C)) { + SmallVector Constants; + for (User::const_op_iterator OI = C->op_begin(), OE = C->op_end(); + OI != OE; ++OI) { + SDNode *Val = getValue(*OI).getNode(); + // If the operand is an empty aggregate, there are no values. + if (!Val) continue; + // Add each leaf value from the operand to the Constants list + // to form a flattened list of all the values. + for (unsigned i = 0, e = Val->getNumValues(); i != e; ++i) + Constants.push_back(SDValue(Val, i)); } - CaseBlock CB(Condition, BOp->getOperand(0), - BOp->getOperand(1), NULL, TBB, FBB, CurBB); - SwitchCases.push_back(CB); - return; + return DAG.getMergeValues(&Constants[0], Constants.size(), + getCurDebugLoc()); } - } - // Create a CaseBlock record representing this branch. - CaseBlock CB(ISD::SETEQ, Cond, ConstantInt::getTrue(*DAG.getContext()), - NULL, TBB, FBB, CurBB); - SwitchCases.push_back(CB); -} + if (C->getType()->isStructTy() || C->getType()->isArrayTy()) { + assert((isa(C) || isa(C)) && + "Unknown struct or array constant!"); -/// FindMergedConditions - If Cond is an expression like -void SelectionDAGBuilder::FindMergedConditions(const Value *Cond, - MachineBasicBlock *TBB, - MachineBasicBlock *FBB, - MachineBasicBlock *CurBB, - MachineBasicBlock *SwitchBB, - unsigned Opc) { - // If this node is not part of the or/and tree, emit it as a branch. - const Instruction *BOp = dyn_cast(Cond); - if (!BOp || !(isa(BOp) || isa(BOp)) || - (unsigned)BOp->getOpcode() != Opc || !BOp->hasOneUse() || - BOp->getParent() != CurBB->getBasicBlock() || - !InBlock(BOp->getOperand(0), CurBB->getBasicBlock()) || - !InBlock(BOp->getOperand(1), CurBB->getBasicBlock())) { - EmitBranchForMergedCondition(Cond, TBB, FBB, CurBB, SwitchBB); - return; - } + SmallVector ValueVTs; + ComputeValueVTs(TLI, C->getType(), ValueVTs); + unsigned NumElts = ValueVTs.size(); + if (NumElts == 0) + return SDValue(); // empty struct + SmallVector Constants(NumElts); + for (unsigned i = 0; i != NumElts; ++i) { + EVT EltVT = ValueVTs[i]; + if (isa(C)) + Constants[i] = DAG.getUNDEF(EltVT); + else if (EltVT.isFloatingPoint()) + Constants[i] = DAG.getConstantFP(0, EltVT); + else + Constants[i] = DAG.getConstant(0, EltVT); + } - // Create TmpBB after CurBB. - MachineFunction::iterator BBI = CurBB; - MachineFunction &MF = DAG.getMachineFunction(); - MachineBasicBlock *TmpBB = MF.CreateMachineBasicBlock(CurBB->getBasicBlock()); - CurBB->getParent()->insert(++BBI, TmpBB); + return DAG.getMergeValues(&Constants[0], NumElts, + getCurDebugLoc()); + } - if (Opc == Instruction::Or) { - // Codegen X | Y as: - // jmp_if_X TBB - // jmp TmpBB - // TmpBB: - // jmp_if_Y TBB - // jmp FBB - // + if (const BlockAddress *BA = dyn_cast(C)) + return DAG.getBlockAddress(BA, VT); - // Emit the LHS condition. - FindMergedConditions(BOp->getOperand(0), TBB, TmpBB, CurBB, SwitchBB, Opc); + const VectorType *VecTy = cast(V->getType()); + unsigned NumElements = VecTy->getNumElements(); - // Emit the RHS condition into TmpBB. - FindMergedConditions(BOp->getOperand(1), TBB, FBB, TmpBB, SwitchBB, Opc); - } else { - assert(Opc == Instruction::And && "Unknown merge op!"); - // Codegen X & Y as: - // jmp_if_X TmpBB - // jmp FBB - // TmpBB: - // jmp_if_Y TBB - // jmp FBB - // - // This requires creation of TmpBB after CurBB. + // Now that we know the number and type of the elements, get that number of + // elements into the Ops array based on what kind of constant it is. + SmallVector Ops; + if (const ConstantVector *CP = dyn_cast(C)) { + for (unsigned i = 0; i != NumElements; ++i) + Ops.push_back(getValue(CP->getOperand(i))); + } else { + assert(isa(C) && "Unknown vector constant!"); + EVT EltVT = TLI.getValueType(VecTy->getElementType()); - // Emit the LHS condition. - FindMergedConditions(BOp->getOperand(0), TmpBB, FBB, CurBB, SwitchBB, Opc); + SDValue Op; + if (EltVT.isFloatingPoint()) + Op = DAG.getConstantFP(0, EltVT); + else + Op = DAG.getConstant(0, EltVT); + Ops.assign(NumElements, Op); + } - // Emit the RHS condition into TmpBB. - FindMergedConditions(BOp->getOperand(1), TBB, FBB, TmpBB, SwitchBB, Opc); + // Create a BUILD_VECTOR node. + return NodeMap[V] = DAG.getNode(ISD::BUILD_VECTOR, getCurDebugLoc(), + VT, &Ops[0], Ops.size()); } -} -/// If the set of cases should be emitted as a series of branches, return true. -/// If we should emit this as a bunch of and/or'd together conditions, return -/// false. -bool -SelectionDAGBuilder::ShouldEmitAsBranches(const std::vector &Cases){ - if (Cases.size() != 2) return true; - - // If this is two comparisons of the same values or'd or and'd together, they - // will get folded into a single comparison, so don't emit two blocks. - if ((Cases[0].CmpLHS == Cases[1].CmpLHS && - Cases[0].CmpRHS == Cases[1].CmpRHS) || - (Cases[0].CmpRHS == Cases[1].CmpLHS && - Cases[0].CmpLHS == Cases[1].CmpRHS)) { - return false; + // If this is a static alloca, generate it as the frameindex instead of + // computation. + if (const AllocaInst *AI = dyn_cast(V)) { + DenseMap::iterator SI = + FuncInfo.StaticAllocaMap.find(AI); + if (SI != FuncInfo.StaticAllocaMap.end()) + return DAG.getFrameIndex(SI->second, TLI.getPointerTy()); } - // Handle: (X != null) | (Y != null) --> (X|Y) != 0 - // Handle: (X == null) & (Y == null) --> (X|Y) == 0 - if (Cases[0].CmpRHS == Cases[1].CmpRHS && - Cases[0].CC == Cases[1].CC && - isa(Cases[0].CmpRHS) && - cast(Cases[0].CmpRHS)->isNullValue()) { - if (Cases[0].CC == ISD::SETEQ && Cases[0].TrueBB == Cases[1].ThisBB) - return false; - if (Cases[0].CC == ISD::SETNE && Cases[0].FalseBB == Cases[1].ThisBB) - return false; - } - - return true; + unsigned InReg = FuncInfo.ValueMap[V]; + assert(InReg && "Value not in map!"); + + RegsForValue RFV(*DAG.getContext(), TLI, InReg, V->getType()); + SDValue Chain = DAG.getEntryNode(); + return RFV.getCopyFromRegs(DAG, FuncInfo, getCurDebugLoc(), Chain, NULL); } -void SelectionDAGBuilder::visitBr(const BranchInst &I) { - MachineBasicBlock *BrMBB = FuncInfo.MBBMap[I.getParent()]; +/// Get the EVTs and ArgFlags collections that represent the legalized return +/// type of the given function. This does not require a DAG or a return value, +/// and is suitable for use before any DAGs for the function are constructed. +static void getReturnInfo(const Type* ReturnType, + Attributes attr, SmallVectorImpl &OutVTs, + SmallVectorImpl &OutFlags, + const TargetLowering &TLI, + SmallVectorImpl *Offsets = 0) { + SmallVector ValueVTs; + ComputeValueVTs(TLI, ReturnType, ValueVTs); + unsigned NumValues = ValueVTs.size(); + if (NumValues == 0) return; + unsigned Offset = 0; - // Update machine-CFG edges. - MachineBasicBlock *Succ0MBB = FuncInfo.MBBMap[I.getSuccessor(0)]; + for (unsigned j = 0, f = NumValues; j != f; ++j) { + EVT VT = ValueVTs[j]; + ISD::NodeType ExtendKind = ISD::ANY_EXTEND; - // Figure out which block is immediately after the current one. - MachineBasicBlock *NextBlock = 0; - MachineFunction::iterator BBI = BrMBB; - if (++BBI != FuncInfo.MF->end()) - NextBlock = BBI; + if (attr & Attribute::SExt) + ExtendKind = ISD::SIGN_EXTEND; + else if (attr & Attribute::ZExt) + ExtendKind = ISD::ZERO_EXTEND; - if (I.isUnconditional()) { - // Update machine-CFG edges. - BrMBB->addSuccessor(Succ0MBB); + // FIXME: C calling convention requires the return type to be promoted to + // at least 32-bit. But this is not necessary for non-C calling + // conventions. The frontend should mark functions whose return values + // require promoting with signext or zeroext attributes. + if (ExtendKind != ISD::ANY_EXTEND && VT.isInteger()) { + EVT MinVT = TLI.getRegisterType(ReturnType->getContext(), MVT::i32); + if (VT.bitsLT(MinVT)) + VT = MinVT; + } - // If this is not a fall-through branch, emit the branch. - if (Succ0MBB != NextBlock) - DAG.setRoot(DAG.getNode(ISD::BR, getCurDebugLoc(), - MVT::Other, getControlRoot(), - DAG.getBasicBlock(Succ0MBB))); + unsigned NumParts = TLI.getNumRegisters(ReturnType->getContext(), VT); + EVT PartVT = TLI.getRegisterType(ReturnType->getContext(), VT); + unsigned PartSize = TLI.getTargetData()->getTypeAllocSize( + PartVT.getTypeForEVT(ReturnType->getContext())); - return; + // 'inreg' on function refers to return value + ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy(); + if (attr & Attribute::InReg) + Flags.setInReg(); + + // Propagate extension type if any + if (attr & Attribute::SExt) + Flags.setSExt(); + else if (attr & Attribute::ZExt) + Flags.setZExt(); + + for (unsigned i = 0; i < NumParts; ++i) { + OutVTs.push_back(PartVT); + OutFlags.push_back(Flags); + if (Offsets) + { + Offsets->push_back(Offset); + Offset += PartSize; + } + } } +} - // If this condition is one of the special cases we handle, do special stuff - // now. - const Value *CondVal = I.getCondition(); - MachineBasicBlock *Succ1MBB = FuncInfo.MBBMap[I.getSuccessor(1)]; +void SelectionDAGBuilder::visitRet(const ReturnInst &I) { + SDValue Chain = getControlRoot(); + SmallVector Outs; - // If this is a series of conditions that are or'd or and'd together, emit - // this as a sequence of branches instead of setcc's with and/or operations. - // For example, instead of something like: - // cmp A, B - // C = seteq - // cmp D, E - // F = setle - // or C, F - // jnz foo - // Emit: - // cmp A, B - // je foo - // cmp D, E - // jle foo - // - if (const BinaryOperator *BOp = dyn_cast(CondVal)) { - if (BOp->hasOneUse() && - (BOp->getOpcode() == Instruction::And || - BOp->getOpcode() == Instruction::Or)) { - FindMergedConditions(BOp, Succ0MBB, Succ1MBB, BrMBB, BrMBB, - BOp->getOpcode()); - // If the compares in later blocks need to use values not currently - // exported from this block, export them now. This block should always - // be the first entry. - assert(SwitchCases[0].ThisBB == BrMBB && "Unexpected lowering!"); + if (!FuncInfo.CanLowerReturn) { + unsigned DemoteReg = FuncInfo.DemoteRegister; + const Function *F = I.getParent()->getParent(); - // Allow some cases to be rejected. - if (ShouldEmitAsBranches(SwitchCases)) { - for (unsigned i = 1, e = SwitchCases.size(); i != e; ++i) { - ExportFromCurrentBlock(SwitchCases[i].CmpLHS); - ExportFromCurrentBlock(SwitchCases[i].CmpRHS); - } + // Emit a store of the return value through the virtual register. + // Leave Outs empty so that LowerReturn won't try to load return + // registers the usual way. + SmallVector PtrValueVTs; + ComputeValueVTs(TLI, PointerType::getUnqual(F->getReturnType()), + PtrValueVTs); - // Emit the branch for this block. - visitSwitchCase(SwitchCases[0], BrMBB); - SwitchCases.erase(SwitchCases.begin()); - return; - } + SDValue RetPtr = DAG.getRegister(DemoteReg, PtrValueVTs[0]); + SDValue RetOp = getValue(I.getOperand(0)); - // Okay, we decided not to do this, remove any inserted MBB's and clear - // SwitchCases. - for (unsigned i = 1, e = SwitchCases.size(); i != e; ++i) - FuncInfo.MF->erase(SwitchCases[i].ThisBB); + SmallVector ValueVTs; + SmallVector Offsets; + ComputeValueVTs(TLI, I.getOperand(0)->getType(), ValueVTs, &Offsets); + unsigned NumValues = ValueVTs.size(); - SwitchCases.clear(); + SmallVector Chains(NumValues); + EVT PtrVT = PtrValueVTs[0]; + for (unsigned i = 0; i != NumValues; ++i) { + SDValue Add = DAG.getNode(ISD::ADD, getCurDebugLoc(), PtrVT, RetPtr, + DAG.getConstant(Offsets[i], PtrVT)); + Chains[i] = + DAG.getStore(Chain, getCurDebugLoc(), + SDValue(RetOp.getNode(), RetOp.getResNo() + i), + Add, NULL, Offsets[i], false, false, 0); } - } - // Create a CaseBlock record representing this branch. - CaseBlock CB(ISD::SETEQ, CondVal, ConstantInt::getTrue(*DAG.getContext()), - NULL, Succ0MBB, Succ1MBB, BrMBB); + Chain = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(), + MVT::Other, &Chains[0], NumValues); + } else if (I.getNumOperands() != 0) { + SmallVector ValueVTs; + ComputeValueVTs(TLI, I.getOperand(0)->getType(), ValueVTs); + unsigned NumValues = ValueVTs.size(); + if (NumValues) { + SDValue RetOp = getValue(I.getOperand(0)); + for (unsigned j = 0, f = NumValues; j != f; ++j) { + EVT VT = ValueVTs[j]; - // Use visitSwitchCase to actually insert the fast branch sequence for this - // cond branch. - visitSwitchCase(CB, BrMBB); -} + ISD::NodeType ExtendKind = ISD::ANY_EXTEND; -/// visitSwitchCase - Emits the necessary code to represent a single node in -/// the binary search tree resulting from lowering a switch instruction. -void SelectionDAGBuilder::visitSwitchCase(CaseBlock &CB, - MachineBasicBlock *SwitchBB) { - SDValue Cond; - SDValue CondLHS = getValue(CB.CmpLHS); - DebugLoc dl = getCurDebugLoc(); + const Function *F = I.getParent()->getParent(); + if (F->paramHasAttr(0, Attribute::SExt)) + ExtendKind = ISD::SIGN_EXTEND; + else if (F->paramHasAttr(0, Attribute::ZExt)) + ExtendKind = ISD::ZERO_EXTEND; - // Build the setcc now. - if (CB.CmpMHS == NULL) { - // Fold "(X == true)" to X and "(X == false)" to !X to - // handle common cases produced by branch lowering. - if (CB.CmpRHS == ConstantInt::getTrue(*DAG.getContext()) && - CB.CC == ISD::SETEQ) - Cond = CondLHS; - else if (CB.CmpRHS == ConstantInt::getFalse(*DAG.getContext()) && - CB.CC == ISD::SETEQ) { - SDValue True = DAG.getConstant(1, CondLHS.getValueType()); - Cond = DAG.getNode(ISD::XOR, dl, CondLHS.getValueType(), CondLHS, True); - } else - Cond = DAG.getSetCC(dl, MVT::i1, CondLHS, getValue(CB.CmpRHS), CB.CC); - } else { - assert(CB.CC == ISD::SETLE && "Can handle only LE ranges now"); + // FIXME: C calling convention requires the return type to be promoted + // to at least 32-bit. But this is not necessary for non-C calling + // conventions. The frontend should mark functions whose return values + // require promoting with signext or zeroext attributes. + if (ExtendKind != ISD::ANY_EXTEND && VT.isInteger()) { + EVT MinVT = TLI.getRegisterType(*DAG.getContext(), MVT::i32); + if (VT.bitsLT(MinVT)) + VT = MinVT; + } - const APInt& Low = cast(CB.CmpLHS)->getValue(); - const APInt& High = cast(CB.CmpRHS)->getValue(); + unsigned NumParts = TLI.getNumRegisters(*DAG.getContext(), VT); + EVT PartVT = TLI.getRegisterType(*DAG.getContext(), VT); + SmallVector Parts(NumParts); + getCopyToParts(DAG, getCurDebugLoc(), + SDValue(RetOp.getNode(), RetOp.getResNo() + j), + &Parts[0], NumParts, PartVT, ExtendKind); - SDValue CmpOp = getValue(CB.CmpMHS); - EVT VT = CmpOp.getValueType(); + // 'inreg' on function refers to return value + ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy(); + if (F->paramHasAttr(0, Attribute::InReg)) + Flags.setInReg(); - if (cast(CB.CmpLHS)->isMinValue(true)) { - Cond = DAG.getSetCC(dl, MVT::i1, CmpOp, DAG.getConstant(High, VT), - ISD::SETLE); - } else { - SDValue SUB = DAG.getNode(ISD::SUB, dl, - VT, CmpOp, DAG.getConstant(Low, VT)); - Cond = DAG.getSetCC(dl, MVT::i1, SUB, - DAG.getConstant(High-Low, VT), ISD::SETULE); + // Propagate extension type if any + if (F->paramHasAttr(0, Attribute::SExt)) + Flags.setSExt(); + else if (F->paramHasAttr(0, Attribute::ZExt)) + Flags.setZExt(); + + for (unsigned i = 0; i < NumParts; ++i) + Outs.push_back(ISD::OutputArg(Flags, Parts[i], /*isfixed=*/true)); + } } } - // Update successor info - SwitchBB->addSuccessor(CB.TrueBB); - SwitchBB->addSuccessor(CB.FalseBB); + bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg(); + CallingConv::ID CallConv = + DAG.getMachineFunction().getFunction()->getCallingConv(); + Chain = TLI.LowerReturn(Chain, CallConv, isVarArg, + Outs, getCurDebugLoc(), DAG); - // Set NextBlock to be the MBB immediately after the current one, if any. - // This is used to avoid emitting unnecessary branches to the next block. - MachineBasicBlock *NextBlock = 0; - MachineFunction::iterator BBI = SwitchBB; - if (++BBI != FuncInfo.MF->end()) - NextBlock = BBI; + // Verify that the target's LowerReturn behaved as expected. + assert(Chain.getNode() && Chain.getValueType() == MVT::Other && + "LowerReturn didn't return a valid chain!"); - // If the lhs block is the next block, invert the condition so that we can - // fall through to the lhs instead of the rhs block. - if (CB.TrueBB == NextBlock) { - std::swap(CB.TrueBB, CB.FalseBB); - SDValue True = DAG.getConstant(1, Cond.getValueType()); - Cond = DAG.getNode(ISD::XOR, dl, Cond.getValueType(), Cond, True); - } + // Update the DAG with the new chain value resulting from return lowering. + DAG.setRoot(Chain); +} - SDValue BrCond = DAG.getNode(ISD::BRCOND, dl, - MVT::Other, getControlRoot(), Cond, - DAG.getBasicBlock(CB.TrueBB)); +/// CopyToExportRegsIfNeeded - If the given value has virtual registers +/// created for it, emit nodes to copy the value into the virtual +/// registers. +void SelectionDAGBuilder::CopyToExportRegsIfNeeded(const Value *V) { + DenseMap::iterator VMI = FuncInfo.ValueMap.find(V); + if (VMI != FuncInfo.ValueMap.end()) { + assert(!V->use_empty() && "Unused value assigned virtual registers!"); + CopyValueToVirtualRegister(V, VMI->second); + } +} - // If the branch was constant folded, fix up the CFG. - if (BrCond.getOpcode() == ISD::BR) { - SwitchBB->removeSuccessor(CB.FalseBB); - } else { - // Otherwise, go ahead and insert the false branch. - if (BrCond == getControlRoot()) - SwitchBB->removeSuccessor(CB.TrueBB); +/// ExportFromCurrentBlock - If this condition isn't known to be exported from +/// the current basic block, add it to ValueMap now so that we'll get a +/// CopyTo/FromReg. +void SelectionDAGBuilder::ExportFromCurrentBlock(const Value *V) { + // No need to export constants. + if (!isa(V) && !isa(V)) return; - if (CB.FalseBB != NextBlock) - BrCond = DAG.getNode(ISD::BR, dl, MVT::Other, BrCond, - DAG.getBasicBlock(CB.FalseBB)); - } + // Already exported? + if (FuncInfo.isExportedInst(V)) return; - DAG.setRoot(BrCond); + unsigned Reg = FuncInfo.InitializeRegForValue(V); + CopyValueToVirtualRegister(V, Reg); } -/// visitJumpTable - Emit JumpTable node in the current MBB -void SelectionDAGBuilder::visitJumpTable(JumpTable &JT) { - // Emit the code for the jump table - assert(JT.Reg != -1U && "Should lower JT Header first!"); - EVT PTy = TLI.getPointerTy(); - SDValue Index = DAG.getCopyFromReg(getControlRoot(), getCurDebugLoc(), - JT.Reg, PTy); - SDValue Table = DAG.getJumpTable(JT.JTI, PTy); - SDValue BrJumpTable = DAG.getNode(ISD::BR_JT, getCurDebugLoc(), - MVT::Other, Index.getValue(1), - Table, Index); - DAG.setRoot(BrJumpTable); -} +bool SelectionDAGBuilder::isExportableFromCurrentBlock(const Value *V, + const BasicBlock *FromBB) { + // The operands of the setcc have to be in this block. We don't know + // how to export them from some other block. + if (const Instruction *VI = dyn_cast(V)) { + // Can export from current BB. + if (VI->getParent() == FromBB) + return true; -/// visitJumpTableHeader - This function emits necessary code to produce index -/// in the JumpTable from switch case. -void SelectionDAGBuilder::visitJumpTableHeader(JumpTable &JT, - JumpTableHeader &JTH, - MachineBasicBlock *SwitchBB) { - // Subtract the lowest switch case value from the value being switched on and - // conditional branch to default mbb if the result is greater than the - // difference between smallest and largest cases. - SDValue SwitchOp = getValue(JTH.SValue); - EVT VT = SwitchOp.getValueType(); - SDValue Sub = DAG.getNode(ISD::SUB, getCurDebugLoc(), VT, SwitchOp, - DAG.getConstant(JTH.First, VT)); + // Is already exported, noop. + return FuncInfo.isExportedInst(V); + } - // The SDNode we just created, which holds the value being switched on minus - // the smallest case value, needs to be copied to a virtual register so it - // can be used as an index into the jump table in a subsequent basic block. - // This value may be smaller or larger than the target's pointer type, and - // therefore require extension or truncating. - SwitchOp = DAG.getZExtOrTrunc(Sub, getCurDebugLoc(), TLI.getPointerTy()); + // If this is an argument, we can export it if the BB is the entry block or + // if it is already exported. + if (isa(V)) { + if (FromBB == &FromBB->getParent()->getEntryBlock()) + return true; - unsigned JumpTableReg = FuncInfo.MakeReg(TLI.getPointerTy()); - SDValue CopyTo = DAG.getCopyToReg(getControlRoot(), getCurDebugLoc(), - JumpTableReg, SwitchOp); - JT.Reg = JumpTableReg; + // Otherwise, can only export this if it is already exported. + return FuncInfo.isExportedInst(V); + } - // Emit the range check for the jump table, and branch to the default block - // for the switch statement if the value being switched on exceeds the largest - // case in the switch. - SDValue CMP = DAG.getSetCC(getCurDebugLoc(), - TLI.getSetCCResultType(Sub.getValueType()), Sub, - DAG.getConstant(JTH.Last-JTH.First,VT), - ISD::SETUGT); + // Otherwise, constants can always be exported. + return true; +} - // Set NextBlock to be the MBB immediately after the current one, if any. - // This is used to avoid emitting unnecessary branches to the next block. - MachineBasicBlock *NextBlock = 0; - MachineFunction::iterator BBI = SwitchBB; +static bool InBlock(const Value *V, const BasicBlock *BB) { + if (const Instruction *I = dyn_cast(V)) + return I->getParent() == BB; + return true; +} - if (++BBI != FuncInfo.MF->end()) - NextBlock = BBI; +/// EmitBranchForMergedCondition - Helper method for FindMergedConditions. +/// This function emits a branch and is used at the leaves of an OR or an +/// AND operator tree. +/// +void +SelectionDAGBuilder::EmitBranchForMergedCondition(const Value *Cond, + MachineBasicBlock *TBB, + MachineBasicBlock *FBB, + MachineBasicBlock *CurBB, + MachineBasicBlock *SwitchBB) { + const BasicBlock *BB = CurBB->getBasicBlock(); - SDValue BrCond = DAG.getNode(ISD::BRCOND, getCurDebugLoc(), - MVT::Other, CopyTo, CMP, - DAG.getBasicBlock(JT.Default)); + // If the leaf of the tree is a comparison, merge the condition into + // the caseblock. + if (const CmpInst *BOp = dyn_cast(Cond)) { + // The operands of the cmp have to be in this block. We don't know + // how to export them from some other block. If this is the first block + // of the sequence, no exporting is needed. + if (CurBB == SwitchBB || + (isExportableFromCurrentBlock(BOp->getOperand(0), BB) && + isExportableFromCurrentBlock(BOp->getOperand(1), BB))) { + ISD::CondCode Condition; + if (const ICmpInst *IC = dyn_cast(Cond)) { + Condition = getICmpCondCode(IC->getPredicate()); + } else if (const FCmpInst *FC = dyn_cast(Cond)) { + Condition = getFCmpCondCode(FC->getPredicate()); + } else { + Condition = ISD::SETEQ; // silence warning. + llvm_unreachable("Unknown compare instruction"); + } - if (JT.MBB != NextBlock) - BrCond = DAG.getNode(ISD::BR, getCurDebugLoc(), MVT::Other, BrCond, - DAG.getBasicBlock(JT.MBB)); + CaseBlock CB(Condition, BOp->getOperand(0), + BOp->getOperand(1), NULL, TBB, FBB, CurBB); + SwitchCases.push_back(CB); + return; + } + } - DAG.setRoot(BrCond); + // Create a CaseBlock record representing this branch. + CaseBlock CB(ISD::SETEQ, Cond, ConstantInt::getTrue(*DAG.getContext()), + NULL, TBB, FBB, CurBB); + SwitchCases.push_back(CB); } -/// visitBitTestHeader - This function emits necessary code to produce value -/// suitable for "bit tests" -void SelectionDAGBuilder::visitBitTestHeader(BitTestBlock &B, - MachineBasicBlock *SwitchBB) { - // Subtract the minimum value - SDValue SwitchOp = getValue(B.SValue); - EVT VT = SwitchOp.getValueType(); - SDValue Sub = DAG.getNode(ISD::SUB, getCurDebugLoc(), VT, SwitchOp, - DAG.getConstant(B.First, VT)); +/// FindMergedConditions - If Cond is an expression like +void SelectionDAGBuilder::FindMergedConditions(const Value *Cond, + MachineBasicBlock *TBB, + MachineBasicBlock *FBB, + MachineBasicBlock *CurBB, + MachineBasicBlock *SwitchBB, + unsigned Opc) { + // If this node is not part of the or/and tree, emit it as a branch. + const Instruction *BOp = dyn_cast(Cond); + if (!BOp || !(isa(BOp) || isa(BOp)) || + (unsigned)BOp->getOpcode() != Opc || !BOp->hasOneUse() || + BOp->getParent() != CurBB->getBasicBlock() || + !InBlock(BOp->getOperand(0), CurBB->getBasicBlock()) || + !InBlock(BOp->getOperand(1), CurBB->getBasicBlock())) { + EmitBranchForMergedCondition(Cond, TBB, FBB, CurBB, SwitchBB); + return; + } - // Check range - SDValue RangeCmp = DAG.getSetCC(getCurDebugLoc(), - TLI.getSetCCResultType(Sub.getValueType()), - Sub, DAG.getConstant(B.Range, VT), - ISD::SETUGT); + // Create TmpBB after CurBB. + MachineFunction::iterator BBI = CurBB; + MachineFunction &MF = DAG.getMachineFunction(); + MachineBasicBlock *TmpBB = MF.CreateMachineBasicBlock(CurBB->getBasicBlock()); + CurBB->getParent()->insert(++BBI, TmpBB); - SDValue ShiftOp = DAG.getZExtOrTrunc(Sub, getCurDebugLoc(), - TLI.getPointerTy()); + if (Opc == Instruction::Or) { + // Codegen X | Y as: + // jmp_if_X TBB + // jmp TmpBB + // TmpBB: + // jmp_if_Y TBB + // jmp FBB + // - B.Reg = FuncInfo.MakeReg(TLI.getPointerTy()); - SDValue CopyTo = DAG.getCopyToReg(getControlRoot(), getCurDebugLoc(), - B.Reg, ShiftOp); + // Emit the LHS condition. + FindMergedConditions(BOp->getOperand(0), TBB, TmpBB, CurBB, SwitchBB, Opc); - // Set NextBlock to be the MBB immediately after the current one, if any. - // This is used to avoid emitting unnecessary branches to the next block. - MachineBasicBlock *NextBlock = 0; - MachineFunction::iterator BBI = SwitchBB; - if (++BBI != FuncInfo.MF->end()) - NextBlock = BBI; + // Emit the RHS condition into TmpBB. + FindMergedConditions(BOp->getOperand(1), TBB, FBB, TmpBB, SwitchBB, Opc); + } else { + assert(Opc == Instruction::And && "Unknown merge op!"); + // Codegen X & Y as: + // jmp_if_X TmpBB + // jmp FBB + // TmpBB: + // jmp_if_Y TBB + // jmp FBB + // + // This requires creation of TmpBB after CurBB. - MachineBasicBlock* MBB = B.Cases[0].ThisBB; + // Emit the LHS condition. + FindMergedConditions(BOp->getOperand(0), TmpBB, FBB, CurBB, SwitchBB, Opc); - SwitchBB->addSuccessor(B.Default); - SwitchBB->addSuccessor(MBB); + // Emit the RHS condition into TmpBB. + FindMergedConditions(BOp->getOperand(1), TBB, FBB, TmpBB, SwitchBB, Opc); + } +} - SDValue BrRange = DAG.getNode(ISD::BRCOND, getCurDebugLoc(), - MVT::Other, CopyTo, RangeCmp, - DAG.getBasicBlock(B.Default)); +/// If the set of cases should be emitted as a series of branches, return true. +/// If we should emit this as a bunch of and/or'd together conditions, return +/// false. +bool +SelectionDAGBuilder::ShouldEmitAsBranches(const std::vector &Cases){ + if (Cases.size() != 2) return true; - if (MBB != NextBlock) - BrRange = DAG.getNode(ISD::BR, getCurDebugLoc(), MVT::Other, CopyTo, - DAG.getBasicBlock(MBB)); + // If this is two comparisons of the same values or'd or and'd together, they + // will get folded into a single comparison, so don't emit two blocks. + if ((Cases[0].CmpLHS == Cases[1].CmpLHS && + Cases[0].CmpRHS == Cases[1].CmpRHS) || + (Cases[0].CmpRHS == Cases[1].CmpLHS && + Cases[0].CmpLHS == Cases[1].CmpRHS)) { + return false; + } - DAG.setRoot(BrRange); + // Handle: (X != null) | (Y != null) --> (X|Y) != 0 + // Handle: (X == null) & (Y == null) --> (X|Y) == 0 + if (Cases[0].CmpRHS == Cases[1].CmpRHS && + Cases[0].CC == Cases[1].CC && + isa(Cases[0].CmpRHS) && + cast(Cases[0].CmpRHS)->isNullValue()) { + if (Cases[0].CC == ISD::SETEQ && Cases[0].TrueBB == Cases[1].ThisBB) + return false; + if (Cases[0].CC == ISD::SETNE && Cases[0].FalseBB == Cases[1].ThisBB) + return false; + } + + return true; } -/// visitBitTestCase - this function produces one "bit test" -void SelectionDAGBuilder::visitBitTestCase(MachineBasicBlock* NextMBB, - unsigned Reg, - BitTestCase &B, - MachineBasicBlock *SwitchBB) { - // Make desired shift - SDValue ShiftOp = DAG.getCopyFromReg(getControlRoot(), getCurDebugLoc(), Reg, - TLI.getPointerTy()); - SDValue SwitchVal = DAG.getNode(ISD::SHL, getCurDebugLoc(), - TLI.getPointerTy(), - DAG.getConstant(1, TLI.getPointerTy()), - ShiftOp); - - // Emit bit tests and jumps - SDValue AndOp = DAG.getNode(ISD::AND, getCurDebugLoc(), - TLI.getPointerTy(), SwitchVal, - DAG.getConstant(B.Mask, TLI.getPointerTy())); - SDValue AndCmp = DAG.getSetCC(getCurDebugLoc(), - TLI.getSetCCResultType(AndOp.getValueType()), - AndOp, DAG.getConstant(0, TLI.getPointerTy()), - ISD::SETNE); - - SwitchBB->addSuccessor(B.TargetBB); - SwitchBB->addSuccessor(NextMBB); +void SelectionDAGBuilder::visitBr(const BranchInst &I) { + MachineBasicBlock *BrMBB = FuncInfo.MBBMap[I.getParent()]; - SDValue BrAnd = DAG.getNode(ISD::BRCOND, getCurDebugLoc(), - MVT::Other, getControlRoot(), - AndCmp, DAG.getBasicBlock(B.TargetBB)); + // Update machine-CFG edges. + MachineBasicBlock *Succ0MBB = FuncInfo.MBBMap[I.getSuccessor(0)]; - // Set NextBlock to be the MBB immediately after the current one, if any. - // This is used to avoid emitting unnecessary branches to the next block. + // Figure out which block is immediately after the current one. MachineBasicBlock *NextBlock = 0; - MachineFunction::iterator BBI = SwitchBB; + MachineFunction::iterator BBI = BrMBB; if (++BBI != FuncInfo.MF->end()) NextBlock = BBI; - if (NextMBB != NextBlock) - BrAnd = DAG.getNode(ISD::BR, getCurDebugLoc(), MVT::Other, BrAnd, - DAG.getBasicBlock(NextMBB)); - - DAG.setRoot(BrAnd); -} - -void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) { - MachineBasicBlock *InvokeMBB = FuncInfo.MBBMap[I.getParent()]; + if (I.isUnconditional()) { + // Update machine-CFG edges. + BrMBB->addSuccessor(Succ0MBB); - // Retrieve successors. - MachineBasicBlock *Return = FuncInfo.MBBMap[I.getSuccessor(0)]; - MachineBasicBlock *LandingPad = FuncInfo.MBBMap[I.getSuccessor(1)]; + // If this is not a fall-through branch, emit the branch. + if (Succ0MBB != NextBlock) + DAG.setRoot(DAG.getNode(ISD::BR, getCurDebugLoc(), + MVT::Other, getControlRoot(), + DAG.getBasicBlock(Succ0MBB))); - const Value *Callee(I.getCalledValue()); - if (isa(Callee)) - visitInlineAsm(&I); - else - LowerCallTo(&I, getValue(Callee), false, LandingPad); + return; + } - // If the value of the invoke is used outside of its defining block, make it - // available as a virtual register. - CopyToExportRegsIfNeeded(&I); + // If this condition is one of the special cases we handle, do special stuff + // now. + const Value *CondVal = I.getCondition(); + MachineBasicBlock *Succ1MBB = FuncInfo.MBBMap[I.getSuccessor(1)]; - // Update successor info - InvokeMBB->addSuccessor(Return); - InvokeMBB->addSuccessor(LandingPad); + // If this is a series of conditions that are or'd or and'd together, emit + // this as a sequence of branches instead of setcc's with and/or operations. + // For example, instead of something like: + // cmp A, B + // C = seteq + // cmp D, E + // F = setle + // or C, F + // jnz foo + // Emit: + // cmp A, B + // je foo + // cmp D, E + // jle foo + // + if (const BinaryOperator *BOp = dyn_cast(CondVal)) { + if (BOp->hasOneUse() && + (BOp->getOpcode() == Instruction::And || + BOp->getOpcode() == Instruction::Or)) { + FindMergedConditions(BOp, Succ0MBB, Succ1MBB, BrMBB, BrMBB, + BOp->getOpcode()); + // If the compares in later blocks need to use values not currently + // exported from this block, export them now. This block should always + // be the first entry. + assert(SwitchCases[0].ThisBB == BrMBB && "Unexpected lowering!"); - // Drop into normal successor. - DAG.setRoot(DAG.getNode(ISD::BR, getCurDebugLoc(), - MVT::Other, getControlRoot(), - DAG.getBasicBlock(Return))); -} + // Allow some cases to be rejected. + if (ShouldEmitAsBranches(SwitchCases)) { + for (unsigned i = 1, e = SwitchCases.size(); i != e; ++i) { + ExportFromCurrentBlock(SwitchCases[i].CmpLHS); + ExportFromCurrentBlock(SwitchCases[i].CmpRHS); + } -void SelectionDAGBuilder::visitUnwind(const UnwindInst &I) { -} + // Emit the branch for this block. + visitSwitchCase(SwitchCases[0], BrMBB); + SwitchCases.erase(SwitchCases.begin()); + return; + } -/// handleSmallSwitchCaseRange - Emit a series of specific tests (suitable for -/// small case ranges). -bool SelectionDAGBuilder::handleSmallSwitchRange(CaseRec& CR, - CaseRecVector& WorkList, - const Value* SV, - MachineBasicBlock *Default, - MachineBasicBlock *SwitchBB) { - Case& BackCase = *(CR.Range.second-1); + // Okay, we decided not to do this, remove any inserted MBB's and clear + // SwitchCases. + for (unsigned i = 1, e = SwitchCases.size(); i != e; ++i) + FuncInfo.MF->erase(SwitchCases[i].ThisBB); - // Size is the number of Cases represented by this range. - size_t Size = CR.Range.second - CR.Range.first; - if (Size > 3) - return false; + SwitchCases.clear(); + } + } - // Get the MachineFunction which holds the current MBB. This is used when - // inserting any additional MBBs necessary to represent the switch. - MachineFunction *CurMF = FuncInfo.MF; + // Create a CaseBlock record representing this branch. + CaseBlock CB(ISD::SETEQ, CondVal, ConstantInt::getTrue(*DAG.getContext()), + NULL, Succ0MBB, Succ1MBB, BrMBB); - // Figure out which block is immediately after the current one. - MachineBasicBlock *NextBlock = 0; - MachineFunction::iterator BBI = CR.CaseBB; + // Use visitSwitchCase to actually insert the fast branch sequence for this + // cond branch. + visitSwitchCase(CB, BrMBB); +} - if (++BBI != FuncInfo.MF->end()) - NextBlock = BBI; +/// visitSwitchCase - Emits the necessary code to represent a single node in +/// the binary search tree resulting from lowering a switch instruction. +void SelectionDAGBuilder::visitSwitchCase(CaseBlock &CB, + MachineBasicBlock *SwitchBB) { + SDValue Cond; + SDValue CondLHS = getValue(CB.CmpLHS); + DebugLoc dl = getCurDebugLoc(); - // TODO: If any two of the cases has the same destination, and if one value - // is the same as the other, but has one bit unset that the other has set, - // use bit manipulation to do two compares at once. For example: - // "if (X == 6 || X == 4)" -> "if ((X|2) == 6)" + // Build the setcc now. + if (CB.CmpMHS == NULL) { + // Fold "(X == true)" to X and "(X == false)" to !X to + // handle common cases produced by branch lowering. + if (CB.CmpRHS == ConstantInt::getTrue(*DAG.getContext()) && + CB.CC == ISD::SETEQ) + Cond = CondLHS; + else if (CB.CmpRHS == ConstantInt::getFalse(*DAG.getContext()) && + CB.CC == ISD::SETEQ) { + SDValue True = DAG.getConstant(1, CondLHS.getValueType()); + Cond = DAG.getNode(ISD::XOR, dl, CondLHS.getValueType(), CondLHS, True); + } else + Cond = DAG.getSetCC(dl, MVT::i1, CondLHS, getValue(CB.CmpRHS), CB.CC); + } else { + assert(CB.CC == ISD::SETLE && "Can handle only LE ranges now"); - // Rearrange the case blocks so that the last one falls through if possible. - if (NextBlock && Default != NextBlock && BackCase.BB != NextBlock) { - // The last case block won't fall through into 'NextBlock' if we emit the - // branches in this order. See if rearranging a case value would help. - for (CaseItr I = CR.Range.first, E = CR.Range.second-1; I != E; ++I) { - if (I->BB == NextBlock) { - std::swap(*I, BackCase); - break; - } - } - } + const APInt& Low = cast(CB.CmpLHS)->getValue(); + const APInt& High = cast(CB.CmpRHS)->getValue(); - // Create a CaseBlock record representing a conditional branch to - // the Case's target mbb if the value being switched on SV is equal - // to C. - MachineBasicBlock *CurBlock = CR.CaseBB; - for (CaseItr I = CR.Range.first, E = CR.Range.second; I != E; ++I) { - MachineBasicBlock *FallThrough; - if (I != E-1) { - FallThrough = CurMF->CreateMachineBasicBlock(CurBlock->getBasicBlock()); - CurMF->insert(BBI, FallThrough); + SDValue CmpOp = getValue(CB.CmpMHS); + EVT VT = CmpOp.getValueType(); - // Put SV in a virtual register to make it available from the new blocks. - ExportFromCurrentBlock(SV); + if (cast(CB.CmpLHS)->isMinValue(true)) { + Cond = DAG.getSetCC(dl, MVT::i1, CmpOp, DAG.getConstant(High, VT), + ISD::SETLE); } else { - // If the last case doesn't match, go to the default block. - FallThrough = Default; + SDValue SUB = DAG.getNode(ISD::SUB, dl, + VT, CmpOp, DAG.getConstant(Low, VT)); + Cond = DAG.getSetCC(dl, MVT::i1, SUB, + DAG.getConstant(High-Low, VT), ISD::SETULE); } + } - const Value *RHS, *LHS, *MHS; - ISD::CondCode CC; - if (I->High == I->Low) { - // This is just small small case range :) containing exactly 1 case - CC = ISD::SETEQ; - LHS = SV; RHS = I->High; MHS = NULL; - } else { - CC = ISD::SETLE; - LHS = I->Low; MHS = SV; RHS = I->High; - } - CaseBlock CB(CC, LHS, RHS, MHS, I->BB, FallThrough, CurBlock); + // Update successor info + SwitchBB->addSuccessor(CB.TrueBB); + SwitchBB->addSuccessor(CB.FalseBB); - // If emitting the first comparison, just call visitSwitchCase to emit the - // code into the current block. Otherwise, push the CaseBlock onto the - // vector to be later processed by SDISel, and insert the node's MBB - // before the next MBB. - if (CurBlock == SwitchBB) - visitSwitchCase(CB, SwitchBB); - else - SwitchCases.push_back(CB); + // Set NextBlock to be the MBB immediately after the current one, if any. + // This is used to avoid emitting unnecessary branches to the next block. + MachineBasicBlock *NextBlock = 0; + MachineFunction::iterator BBI = SwitchBB; + if (++BBI != FuncInfo.MF->end()) + NextBlock = BBI; - CurBlock = FallThrough; + // If the lhs block is the next block, invert the condition so that we can + // fall through to the lhs instead of the rhs block. + if (CB.TrueBB == NextBlock) { + std::swap(CB.TrueBB, CB.FalseBB); + SDValue True = DAG.getConstant(1, Cond.getValueType()); + Cond = DAG.getNode(ISD::XOR, dl, Cond.getValueType(), Cond, True); } - return true; -} - -static inline bool areJTsAllowed(const TargetLowering &TLI) { - return !DisableJumpTables && - (TLI.isOperationLegalOrCustom(ISD::BR_JT, MVT::Other) || - TLI.isOperationLegalOrCustom(ISD::BRIND, MVT::Other)); -} + SDValue BrCond = DAG.getNode(ISD::BRCOND, dl, + MVT::Other, getControlRoot(), Cond, + DAG.getBasicBlock(CB.TrueBB)); -static APInt ComputeRange(const APInt &First, const APInt &Last) { - APInt LastExt(Last), FirstExt(First); - uint32_t BitWidth = std::max(Last.getBitWidth(), First.getBitWidth()) + 1; - LastExt.sext(BitWidth); FirstExt.sext(BitWidth); - return (LastExt - FirstExt + 1ULL); + // If the branch was constant folded, fix up the CFG. + if (BrCond.getOpcode() == ISD::BR) { + SwitchBB->removeSuccessor(CB.FalseBB); + } else { + // Otherwise, go ahead and insert the false branch. + if (BrCond == getControlRoot()) + SwitchBB->removeSuccessor(CB.TrueBB); + + if (CB.FalseBB != NextBlock) + BrCond = DAG.getNode(ISD::BR, dl, MVT::Other, BrCond, + DAG.getBasicBlock(CB.FalseBB)); + } + + DAG.setRoot(BrCond); } -/// handleJTSwitchCase - Emit jumptable for current switch case range -bool SelectionDAGBuilder::handleJTSwitchCase(CaseRec& CR, - CaseRecVector& WorkList, - const Value* SV, - MachineBasicBlock* Default, - MachineBasicBlock *SwitchBB) { - Case& FrontCase = *CR.Range.first; - Case& BackCase = *(CR.Range.second-1); +/// visitJumpTable - Emit JumpTable node in the current MBB +void SelectionDAGBuilder::visitJumpTable(JumpTable &JT) { + // Emit the code for the jump table + assert(JT.Reg != -1U && "Should lower JT Header first!"); + EVT PTy = TLI.getPointerTy(); + SDValue Index = DAG.getCopyFromReg(getControlRoot(), getCurDebugLoc(), + JT.Reg, PTy); + SDValue Table = DAG.getJumpTable(JT.JTI, PTy); + SDValue BrJumpTable = DAG.getNode(ISD::BR_JT, getCurDebugLoc(), + MVT::Other, Index.getValue(1), + Table, Index); + DAG.setRoot(BrJumpTable); +} - const APInt &First = cast(FrontCase.Low)->getValue(); - const APInt &Last = cast(BackCase.High)->getValue(); +/// visitJumpTableHeader - This function emits necessary code to produce index +/// in the JumpTable from switch case. +void SelectionDAGBuilder::visitJumpTableHeader(JumpTable &JT, + JumpTableHeader &JTH, + MachineBasicBlock *SwitchBB) { + // Subtract the lowest switch case value from the value being switched on and + // conditional branch to default mbb if the result is greater than the + // difference between smallest and largest cases. + SDValue SwitchOp = getValue(JTH.SValue); + EVT VT = SwitchOp.getValueType(); + SDValue Sub = DAG.getNode(ISD::SUB, getCurDebugLoc(), VT, SwitchOp, + DAG.getConstant(JTH.First, VT)); - APInt TSize(First.getBitWidth(), 0); - for (CaseItr I = CR.Range.first, E = CR.Range.second; - I!=E; ++I) - TSize += I->size(); + // The SDNode we just created, which holds the value being switched on minus + // the smallest case value, needs to be copied to a virtual register so it + // can be used as an index into the jump table in a subsequent basic block. + // This value may be smaller or larger than the target's pointer type, and + // therefore require extension or truncating. + SwitchOp = DAG.getZExtOrTrunc(Sub, getCurDebugLoc(), TLI.getPointerTy()); - if (!areJTsAllowed(TLI) || TSize.ult(4)) - return false; + unsigned JumpTableReg = FuncInfo.MakeReg(TLI.getPointerTy()); + SDValue CopyTo = DAG.getCopyToReg(getControlRoot(), getCurDebugLoc(), + JumpTableReg, SwitchOp); + JT.Reg = JumpTableReg; - APInt Range = ComputeRange(First, Last); - double Density = TSize.roundToDouble() / Range.roundToDouble(); - if (Density < 0.4) - return false; + // Emit the range check for the jump table, and branch to the default block + // for the switch statement if the value being switched on exceeds the largest + // case in the switch. + SDValue CMP = DAG.getSetCC(getCurDebugLoc(), + TLI.getSetCCResultType(Sub.getValueType()), Sub, + DAG.getConstant(JTH.Last-JTH.First,VT), + ISD::SETUGT); - DEBUG(dbgs() << "Lowering jump table\n" - << "First entry: " << First << ". Last entry: " << Last << '\n' - << "Range: " << Range - << "Size: " << TSize << ". Density: " << Density << "\n\n"); + // Set NextBlock to be the MBB immediately after the current one, if any. + // This is used to avoid emitting unnecessary branches to the next block. + MachineBasicBlock *NextBlock = 0; + MachineFunction::iterator BBI = SwitchBB; - // Get the MachineFunction which holds the current MBB. This is used when - // inserting any additional MBBs necessary to represent the switch. - MachineFunction *CurMF = FuncInfo.MF; + if (++BBI != FuncInfo.MF->end()) + NextBlock = BBI; - // Figure out which block is immediately after the current one. - MachineFunction::iterator BBI = CR.CaseBB; - ++BBI; + SDValue BrCond = DAG.getNode(ISD::BRCOND, getCurDebugLoc(), + MVT::Other, CopyTo, CMP, + DAG.getBasicBlock(JT.Default)); - const BasicBlock *LLVMBB = CR.CaseBB->getBasicBlock(); + if (JT.MBB != NextBlock) + BrCond = DAG.getNode(ISD::BR, getCurDebugLoc(), MVT::Other, BrCond, + DAG.getBasicBlock(JT.MBB)); - // Create a new basic block to hold the code for loading the address - // of the jump table, and jumping to it. Update successor information; - // we will either branch to the default case for the switch, or the jump - // table. - MachineBasicBlock *JumpTableBB = CurMF->CreateMachineBasicBlock(LLVMBB); - CurMF->insert(BBI, JumpTableBB); - CR.CaseBB->addSuccessor(Default); - CR.CaseBB->addSuccessor(JumpTableBB); + DAG.setRoot(BrCond); +} - // Build a vector of destination BBs, corresponding to each target - // of the jump table. If the value of the jump table slot corresponds to - // a case statement, push the case's BB onto the vector, otherwise, push - // the default BB. - std::vector DestBBs; - APInt TEI = First; - for (CaseItr I = CR.Range.first, E = CR.Range.second; I != E; ++TEI) { - const APInt &Low = cast(I->Low)->getValue(); - const APInt &High = cast(I->High)->getValue(); +/// visitBitTestHeader - This function emits necessary code to produce value +/// suitable for "bit tests" +void SelectionDAGBuilder::visitBitTestHeader(BitTestBlock &B, + MachineBasicBlock *SwitchBB) { + // Subtract the minimum value + SDValue SwitchOp = getValue(B.SValue); + EVT VT = SwitchOp.getValueType(); + SDValue Sub = DAG.getNode(ISD::SUB, getCurDebugLoc(), VT, SwitchOp, + DAG.getConstant(B.First, VT)); - if (Low.sle(TEI) && TEI.sle(High)) { - DestBBs.push_back(I->BB); - if (TEI==High) - ++I; - } else { - DestBBs.push_back(Default); - } - } + // Check range + SDValue RangeCmp = DAG.getSetCC(getCurDebugLoc(), + TLI.getSetCCResultType(Sub.getValueType()), + Sub, DAG.getConstant(B.Range, VT), + ISD::SETUGT); - // Update successor info. Add one edge to each unique successor. - BitVector SuccsHandled(CR.CaseBB->getParent()->getNumBlockIDs()); - for (std::vector::iterator I = DestBBs.begin(), - E = DestBBs.end(); I != E; ++I) { - if (!SuccsHandled[(*I)->getNumber()]) { - SuccsHandled[(*I)->getNumber()] = true; - JumpTableBB->addSuccessor(*I); - } - } + SDValue ShiftOp = DAG.getZExtOrTrunc(Sub, getCurDebugLoc(), + TLI.getPointerTy()); - // Create a jump table index for this jump table. - unsigned JTEncoding = TLI.getJumpTableEncoding(); - unsigned JTI = CurMF->getOrCreateJumpTableInfo(JTEncoding) - ->createJumpTableIndex(DestBBs); + B.Reg = FuncInfo.MakeReg(TLI.getPointerTy()); + SDValue CopyTo = DAG.getCopyToReg(getControlRoot(), getCurDebugLoc(), + B.Reg, ShiftOp); - // Set the jump table information so that we can codegen it as a second - // MachineBasicBlock - JumpTable JT(-1U, JTI, JumpTableBB, Default); - JumpTableHeader JTH(First, Last, SV, CR.CaseBB, (CR.CaseBB == SwitchBB)); - if (CR.CaseBB == SwitchBB) - visitJumpTableHeader(JT, JTH, SwitchBB); + // Set NextBlock to be the MBB immediately after the current one, if any. + // This is used to avoid emitting unnecessary branches to the next block. + MachineBasicBlock *NextBlock = 0; + MachineFunction::iterator BBI = SwitchBB; + if (++BBI != FuncInfo.MF->end()) + NextBlock = BBI; - JTCases.push_back(JumpTableBlock(JTH, JT)); + MachineBasicBlock* MBB = B.Cases[0].ThisBB; - return true; + SwitchBB->addSuccessor(B.Default); + SwitchBB->addSuccessor(MBB); + + SDValue BrRange = DAG.getNode(ISD::BRCOND, getCurDebugLoc(), + MVT::Other, CopyTo, RangeCmp, + DAG.getBasicBlock(B.Default)); + + if (MBB != NextBlock) + BrRange = DAG.getNode(ISD::BR, getCurDebugLoc(), MVT::Other, CopyTo, + DAG.getBasicBlock(MBB)); + + DAG.setRoot(BrRange); } -/// handleBTSplitSwitchCase - emit comparison and split binary search tree into -/// 2 subtrees. -bool SelectionDAGBuilder::handleBTSplitSwitchCase(CaseRec& CR, - CaseRecVector& WorkList, - const Value* SV, - MachineBasicBlock *Default, - MachineBasicBlock *SwitchBB) { - // Get the MachineFunction which holds the current MBB. This is used when - // inserting any additional MBBs necessary to represent the switch. - MachineFunction *CurMF = FuncInfo.MF; +/// visitBitTestCase - this function produces one "bit test" +void SelectionDAGBuilder::visitBitTestCase(MachineBasicBlock* NextMBB, + unsigned Reg, + BitTestCase &B, + MachineBasicBlock *SwitchBB) { + // Make desired shift + SDValue ShiftOp = DAG.getCopyFromReg(getControlRoot(), getCurDebugLoc(), Reg, + TLI.getPointerTy()); + SDValue SwitchVal = DAG.getNode(ISD::SHL, getCurDebugLoc(), + TLI.getPointerTy(), + DAG.getConstant(1, TLI.getPointerTy()), + ShiftOp); - // Figure out which block is immediately after the current one. - MachineFunction::iterator BBI = CR.CaseBB; - ++BBI; + // Emit bit tests and jumps + SDValue AndOp = DAG.getNode(ISD::AND, getCurDebugLoc(), + TLI.getPointerTy(), SwitchVal, + DAG.getConstant(B.Mask, TLI.getPointerTy())); + SDValue AndCmp = DAG.getSetCC(getCurDebugLoc(), + TLI.getSetCCResultType(AndOp.getValueType()), + AndOp, DAG.getConstant(0, TLI.getPointerTy()), + ISD::SETNE); - Case& FrontCase = *CR.Range.first; - Case& BackCase = *(CR.Range.second-1); - const BasicBlock *LLVMBB = CR.CaseBB->getBasicBlock(); + SwitchBB->addSuccessor(B.TargetBB); + SwitchBB->addSuccessor(NextMBB); - // Size is the number of Cases represented by this range. - unsigned Size = CR.Range.second - CR.Range.first; + SDValue BrAnd = DAG.getNode(ISD::BRCOND, getCurDebugLoc(), + MVT::Other, getControlRoot(), + AndCmp, DAG.getBasicBlock(B.TargetBB)); - const APInt &First = cast(FrontCase.Low)->getValue(); - const APInt &Last = cast(BackCase.High)->getValue(); - double FMetric = 0; - CaseItr Pivot = CR.Range.first + Size/2; + // Set NextBlock to be the MBB immediately after the current one, if any. + // This is used to avoid emitting unnecessary branches to the next block. + MachineBasicBlock *NextBlock = 0; + MachineFunction::iterator BBI = SwitchBB; + if (++BBI != FuncInfo.MF->end()) + NextBlock = BBI; - // Select optimal pivot, maximizing sum density of LHS and RHS. This will - // (heuristically) allow us to emit JumpTable's later. - APInt TSize(First.getBitWidth(), 0); - for (CaseItr I = CR.Range.first, E = CR.Range.second; - I!=E; ++I) - TSize += I->size(); + if (NextMBB != NextBlock) + BrAnd = DAG.getNode(ISD::BR, getCurDebugLoc(), MVT::Other, BrAnd, + DAG.getBasicBlock(NextMBB)); - APInt LSize = FrontCase.size(); - APInt RSize = TSize-LSize; - DEBUG(dbgs() << "Selecting best pivot: \n" - << "First: " << First << ", Last: " << Last <<'\n' - << "LSize: " << LSize << ", RSize: " << RSize << '\n'); - for (CaseItr I = CR.Range.first, J=I+1, E = CR.Range.second; - J!=E; ++I, ++J) { - const APInt &LEnd = cast(I->High)->getValue(); - const APInt &RBegin = cast(J->Low)->getValue(); - APInt Range = ComputeRange(LEnd, RBegin); - assert((Range - 2ULL).isNonNegative() && - "Invalid case distance"); - double LDensity = (double)LSize.roundToDouble() / - (LEnd - First + 1ULL).roundToDouble(); - double RDensity = (double)RSize.roundToDouble() / - (Last - RBegin + 1ULL).roundToDouble(); - double Metric = Range.logBase2()*(LDensity+RDensity); - // Should always split in some non-trivial place - DEBUG(dbgs() <<"=>Step\n" - << "LEnd: " << LEnd << ", RBegin: " << RBegin << '\n' - << "LDensity: " << LDensity - << ", RDensity: " << RDensity << '\n' - << "Metric: " << Metric << '\n'); - if (FMetric < Metric) { - Pivot = J; - FMetric = Metric; - DEBUG(dbgs() << "Current metric set to: " << FMetric << '\n'); - } - - LSize += J->size(); - RSize -= J->size(); - } - if (areJTsAllowed(TLI)) { - // If our case is dense we *really* should handle it earlier! - assert((FMetric > 0) && "Should handle dense range earlier!"); - } else { - Pivot = CR.Range.first + Size/2; - } - - CaseRange LHSR(CR.Range.first, Pivot); - CaseRange RHSR(Pivot, CR.Range.second); - Constant *C = Pivot->Low; - MachineBasicBlock *FalseBB = 0, *TrueBB = 0; - - // We know that we branch to the LHS if the Value being switched on is - // less than the Pivot value, C. We use this to optimize our binary - // tree a bit, by recognizing that if SV is greater than or equal to the - // LHS's Case Value, and that Case Value is exactly one less than the - // Pivot's Value, then we can branch directly to the LHS's Target, - // rather than creating a leaf node for it. - if ((LHSR.second - LHSR.first) == 1 && - LHSR.first->High == CR.GE && - cast(C)->getValue() == - (cast(CR.GE)->getValue() + 1LL)) { - TrueBB = LHSR.first->BB; - } else { - TrueBB = CurMF->CreateMachineBasicBlock(LLVMBB); - CurMF->insert(BBI, TrueBB); - WorkList.push_back(CaseRec(TrueBB, C, CR.GE, LHSR)); + DAG.setRoot(BrAnd); +} - // Put SV in a virtual register to make it available from the new blocks. - ExportFromCurrentBlock(SV); - } +void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) { + MachineBasicBlock *InvokeMBB = FuncInfo.MBBMap[I.getParent()]; - // Similar to the optimization above, if the Value being switched on is - // known to be less than the Constant CR.LT, and the current Case Value - // is CR.LT - 1, then we can branch directly to the target block for - // the current Case Value, rather than emitting a RHS leaf node for it. - if ((RHSR.second - RHSR.first) == 1 && CR.LT && - cast(RHSR.first->Low)->getValue() == - (cast(CR.LT)->getValue() - 1LL)) { - FalseBB = RHSR.first->BB; - } else { - FalseBB = CurMF->CreateMachineBasicBlock(LLVMBB); - CurMF->insert(BBI, FalseBB); - WorkList.push_back(CaseRec(FalseBB,CR.LT,C,RHSR)); + // Retrieve successors. + MachineBasicBlock *Return = FuncInfo.MBBMap[I.getSuccessor(0)]; + MachineBasicBlock *LandingPad = FuncInfo.MBBMap[I.getSuccessor(1)]; - // Put SV in a virtual register to make it available from the new blocks. - ExportFromCurrentBlock(SV); - } + const Value *Callee(I.getCalledValue()); + if (isa(Callee)) + visitInlineAsm(&I); + else + LowerCallTo(&I, getValue(Callee), false, LandingPad); - // Create a CaseBlock record representing a conditional branch to - // the LHS node if the value being switched on SV is less than C. - // Otherwise, branch to LHS. - CaseBlock CB(ISD::SETLT, SV, C, NULL, TrueBB, FalseBB, CR.CaseBB); + // If the value of the invoke is used outside of its defining block, make it + // available as a virtual register. + CopyToExportRegsIfNeeded(&I); - if (CR.CaseBB == SwitchBB) - visitSwitchCase(CB, SwitchBB); - else - SwitchCases.push_back(CB); + // Update successor info + InvokeMBB->addSuccessor(Return); + InvokeMBB->addSuccessor(LandingPad); - return true; + // Drop into normal successor. + DAG.setRoot(DAG.getNode(ISD::BR, getCurDebugLoc(), + MVT::Other, getControlRoot(), + DAG.getBasicBlock(Return))); } -/// handleBitTestsSwitchCase - if current case range has few destination and -/// range span less, than machine word bitwidth, encode case range into series -/// of masks and emit bit tests with these masks. -bool SelectionDAGBuilder::handleBitTestsSwitchCase(CaseRec& CR, - CaseRecVector& WorkList, - const Value* SV, - MachineBasicBlock* Default, - MachineBasicBlock *SwitchBB){ - EVT PTy = TLI.getPointerTy(); - unsigned IntPtrBits = PTy.getSizeInBits(); +void SelectionDAGBuilder::visitUnwind(const UnwindInst &I) { +} - Case& FrontCase = *CR.Range.first; +/// handleSmallSwitchCaseRange - Emit a series of specific tests (suitable for +/// small case ranges). +bool SelectionDAGBuilder::handleSmallSwitchRange(CaseRec& CR, + CaseRecVector& WorkList, + const Value* SV, + MachineBasicBlock *Default, + MachineBasicBlock *SwitchBB) { Case& BackCase = *(CR.Range.second-1); + // Size is the number of Cases represented by this range. + size_t Size = CR.Range.second - CR.Range.first; + if (Size > 3) + return false; + // Get the MachineFunction which holds the current MBB. This is used when // inserting any additional MBBs necessary to represent the switch. MachineFunction *CurMF = FuncInfo.MF; - // If target does not have legal shift left, do not emit bit tests at all. - if (!TLI.isOperationLegal(ISD::SHL, TLI.getPointerTy())) - return false; - - size_t numCmps = 0; - for (CaseItr I = CR.Range.first, E = CR.Range.second; - I!=E; ++I) { - // Single case counts one, case range - two. - numCmps += (I->Low == I->High ? 1 : 2); - } - - // Count unique destinations - SmallSet Dests; - for (CaseItr I = CR.Range.first, E = CR.Range.second; I!=E; ++I) { - Dests.insert(I->BB); - if (Dests.size() > 3) - // Don't bother the code below, if there are too much unique destinations - return false; - } - DEBUG(dbgs() << "Total number of unique destinations: " - << Dests.size() << '\n' - << "Total number of comparisons: " << numCmps << '\n'); - - // Compute span of values. - const APInt& minValue = cast(FrontCase.Low)->getValue(); - const APInt& maxValue = cast(BackCase.High)->getValue(); - APInt cmpRange = maxValue - minValue; - - DEBUG(dbgs() << "Compare range: " << cmpRange << '\n' - << "Low bound: " << minValue << '\n' - << "High bound: " << maxValue << '\n'); - - if (cmpRange.uge(IntPtrBits) || - (!(Dests.size() == 1 && numCmps >= 3) && - !(Dests.size() == 2 && numCmps >= 5) && - !(Dests.size() >= 3 && numCmps >= 6))) - return false; - - DEBUG(dbgs() << "Emitting bit tests\n"); - APInt lowBound = APInt::getNullValue(cmpRange.getBitWidth()); + // Figure out which block is immediately after the current one. + MachineBasicBlock *NextBlock = 0; + MachineFunction::iterator BBI = CR.CaseBB; - // Optimize the case where all the case values fit in a - // word without having to subtract minValue. In this case, - // we can optimize away the subtraction. - if (minValue.isNonNegative() && maxValue.slt(IntPtrBits)) { - cmpRange = maxValue; - } else { - lowBound = minValue; - } + if (++BBI != FuncInfo.MF->end()) + NextBlock = BBI; - CaseBitsVector CasesBits; - unsigned i, count = 0; + // TODO: If any two of the cases has the same destination, and if one value + // is the same as the other, but has one bit unset that the other has set, + // use bit manipulation to do two compares at once. For example: + // "if (X == 6 || X == 4)" -> "if ((X|2) == 6)" - for (CaseItr I = CR.Range.first, E = CR.Range.second; I!=E; ++I) { - MachineBasicBlock* Dest = I->BB; - for (i = 0; i < count; ++i) - if (Dest == CasesBits[i].BB) + // Rearrange the case blocks so that the last one falls through if possible. + if (NextBlock && Default != NextBlock && BackCase.BB != NextBlock) { + // The last case block won't fall through into 'NextBlock' if we emit the + // branches in this order. See if rearranging a case value would help. + for (CaseItr I = CR.Range.first, E = CR.Range.second-1; I != E; ++I) { + if (I->BB == NextBlock) { + std::swap(*I, BackCase); break; - - if (i == count) { - assert((count < 3) && "Too much destinations to test!"); - CasesBits.push_back(CaseBits(0, Dest, 0)); - count++; + } } + } - const APInt& lowValue = cast(I->Low)->getValue(); - const APInt& highValue = cast(I->High)->getValue(); + // Create a CaseBlock record representing a conditional branch to + // the Case's target mbb if the value being switched on SV is equal + // to C. + MachineBasicBlock *CurBlock = CR.CaseBB; + for (CaseItr I = CR.Range.first, E = CR.Range.second; I != E; ++I) { + MachineBasicBlock *FallThrough; + if (I != E-1) { + FallThrough = CurMF->CreateMachineBasicBlock(CurBlock->getBasicBlock()); + CurMF->insert(BBI, FallThrough); - uint64_t lo = (lowValue - lowBound).getZExtValue(); - uint64_t hi = (highValue - lowBound).getZExtValue(); + // Put SV in a virtual register to make it available from the new blocks. + ExportFromCurrentBlock(SV); + } else { + // If the last case doesn't match, go to the default block. + FallThrough = Default; + } - for (uint64_t j = lo; j <= hi; j++) { - CasesBits[i].Mask |= 1ULL << j; - CasesBits[i].Bits++; + const Value *RHS, *LHS, *MHS; + ISD::CondCode CC; + if (I->High == I->Low) { + // This is just small small case range :) containing exactly 1 case + CC = ISD::SETEQ; + LHS = SV; RHS = I->High; MHS = NULL; + } else { + CC = ISD::SETLE; + LHS = I->Low; MHS = SV; RHS = I->High; } + CaseBlock CB(CC, LHS, RHS, MHS, I->BB, FallThrough, CurBlock); - } - std::sort(CasesBits.begin(), CasesBits.end(), CaseBitsCmp()); + // If emitting the first comparison, just call visitSwitchCase to emit the + // code into the current block. Otherwise, push the CaseBlock onto the + // vector to be later processed by SDISel, and insert the node's MBB + // before the next MBB. + if (CurBlock == SwitchBB) + visitSwitchCase(CB, SwitchBB); + else + SwitchCases.push_back(CB); - BitTestInfo BTC; + CurBlock = FallThrough; + } - // Figure out which block is immediately after the current one. - MachineFunction::iterator BBI = CR.CaseBB; - ++BBI; + return true; +} - const BasicBlock *LLVMBB = CR.CaseBB->getBasicBlock(); - - DEBUG(dbgs() << "Cases:\n"); - for (unsigned i = 0, e = CasesBits.size(); i!=e; ++i) { - DEBUG(dbgs() << "Mask: " << CasesBits[i].Mask - << ", Bits: " << CasesBits[i].Bits - << ", BB: " << CasesBits[i].BB << '\n'); - - MachineBasicBlock *CaseBB = CurMF->CreateMachineBasicBlock(LLVMBB); - CurMF->insert(BBI, CaseBB); - BTC.push_back(BitTestCase(CasesBits[i].Mask, - CaseBB, - CasesBits[i].BB)); - - // Put SV in a virtual register to make it available from the new blocks. - ExportFromCurrentBlock(SV); - } - - BitTestBlock BTB(lowBound, cmpRange, SV, - -1U, (CR.CaseBB == SwitchBB), - CR.CaseBB, Default, BTC); - - if (CR.CaseBB == SwitchBB) - visitBitTestHeader(BTB, SwitchBB); - - BitTestCases.push_back(BTB); +static inline bool areJTsAllowed(const TargetLowering &TLI) { + return !DisableJumpTables && + (TLI.isOperationLegalOrCustom(ISD::BR_JT, MVT::Other) || + TLI.isOperationLegalOrCustom(ISD::BRIND, MVT::Other)); +} - return true; +static APInt ComputeRange(const APInt &First, const APInt &Last) { + APInt LastExt(Last), FirstExt(First); + uint32_t BitWidth = std::max(Last.getBitWidth(), First.getBitWidth()) + 1; + LastExt.sext(BitWidth); FirstExt.sext(BitWidth); + return (LastExt - FirstExt + 1ULL); } -/// Clusterify - Transform simple list of Cases into list of CaseRange's -size_t SelectionDAGBuilder::Clusterify(CaseVector& Cases, - const SwitchInst& SI) { - size_t numCmps = 0; +/// handleJTSwitchCase - Emit jumptable for current switch case range +bool SelectionDAGBuilder::handleJTSwitchCase(CaseRec& CR, + CaseRecVector& WorkList, + const Value* SV, + MachineBasicBlock* Default, + MachineBasicBlock *SwitchBB) { + Case& FrontCase = *CR.Range.first; + Case& BackCase = *(CR.Range.second-1); - // Start with "simple" cases - for (size_t i = 1; i < SI.getNumSuccessors(); ++i) { - MachineBasicBlock *SMBB = FuncInfo.MBBMap[SI.getSuccessor(i)]; - Cases.push_back(Case(SI.getSuccessorValue(i), - SI.getSuccessorValue(i), - SMBB)); - } - std::sort(Cases.begin(), Cases.end(), CaseCmp()); + const APInt &First = cast(FrontCase.Low)->getValue(); + const APInt &Last = cast(BackCase.High)->getValue(); - // Merge case into clusters - if (Cases.size() >= 2) - // Must recompute end() each iteration because it may be - // invalidated by erase if we hold on to it - for (CaseItr I = Cases.begin(), J = ++(Cases.begin()); J != Cases.end(); ) { - const APInt& nextValue = cast(J->Low)->getValue(); - const APInt& currentValue = cast(I->High)->getValue(); - MachineBasicBlock* nextBB = J->BB; - MachineBasicBlock* currentBB = I->BB; + APInt TSize(First.getBitWidth(), 0); + for (CaseItr I = CR.Range.first, E = CR.Range.second; + I!=E; ++I) + TSize += I->size(); - // If the two neighboring cases go to the same destination, merge them - // into a single case. - if ((nextValue - currentValue == 1) && (currentBB == nextBB)) { - I->High = J->High; - J = Cases.erase(J); - } else { - I = J++; - } - } + if (!areJTsAllowed(TLI) || TSize.ult(4)) + return false; - for (CaseItr I=Cases.begin(), E=Cases.end(); I!=E; ++I, ++numCmps) { - if (I->Low != I->High) - // A range counts double, since it requires two compares. - ++numCmps; - } + APInt Range = ComputeRange(First, Last); + double Density = TSize.roundToDouble() / Range.roundToDouble(); + if (Density < 0.4) + return false; - return numCmps; -} + DEBUG(dbgs() << "Lowering jump table\n" + << "First entry: " << First << ". Last entry: " << Last << '\n' + << "Range: " << Range + << "Size: " << TSize << ". Density: " << Density << "\n\n"); -void SelectionDAGBuilder::visitSwitch(const SwitchInst &SI) { - MachineBasicBlock *SwitchMBB = FuncInfo.MBBMap[SI.getParent()]; + // Get the MachineFunction which holds the current MBB. This is used when + // inserting any additional MBBs necessary to represent the switch. + MachineFunction *CurMF = FuncInfo.MF; // Figure out which block is immediately after the current one. - MachineBasicBlock *NextBlock = 0; - MachineBasicBlock *Default = FuncInfo.MBBMap[SI.getDefaultDest()]; + MachineFunction::iterator BBI = CR.CaseBB; + ++BBI; - // If there is only the default destination, branch to it if it is not the - // next basic block. Otherwise, just fall through. - if (SI.getNumOperands() == 2) { - // Update machine-CFG edges. + const BasicBlock *LLVMBB = CR.CaseBB->getBasicBlock(); - // If this is not a fall-through branch, emit the branch. - SwitchMBB->addSuccessor(Default); - if (Default != NextBlock) - DAG.setRoot(DAG.getNode(ISD::BR, getCurDebugLoc(), - MVT::Other, getControlRoot(), - DAG.getBasicBlock(Default))); + // Create a new basic block to hold the code for loading the address + // of the jump table, and jumping to it. Update successor information; + // we will either branch to the default case for the switch, or the jump + // table. + MachineBasicBlock *JumpTableBB = CurMF->CreateMachineBasicBlock(LLVMBB); + CurMF->insert(BBI, JumpTableBB); + CR.CaseBB->addSuccessor(Default); + CR.CaseBB->addSuccessor(JumpTableBB); - return; + // Build a vector of destination BBs, corresponding to each target + // of the jump table. If the value of the jump table slot corresponds to + // a case statement, push the case's BB onto the vector, otherwise, push + // the default BB. + std::vector DestBBs; + APInt TEI = First; + for (CaseItr I = CR.Range.first, E = CR.Range.second; I != E; ++TEI) { + const APInt &Low = cast(I->Low)->getValue(); + const APInt &High = cast(I->High)->getValue(); + + if (Low.sle(TEI) && TEI.sle(High)) { + DestBBs.push_back(I->BB); + if (TEI==High) + ++I; + } else { + DestBBs.push_back(Default); + } } - // If there are any non-default case statements, create a vector of Cases - // representing each one, and sort the vector so that we can efficiently - // create a binary search tree from them. - CaseVector Cases; - size_t numCmps = Clusterify(Cases, SI); - DEBUG(dbgs() << "Clusterify finished. Total clusters: " << Cases.size() - << ". Total compares: " << numCmps << '\n'); - numCmps = 0; + // Update successor info. Add one edge to each unique successor. + BitVector SuccsHandled(CR.CaseBB->getParent()->getNumBlockIDs()); + for (std::vector::iterator I = DestBBs.begin(), + E = DestBBs.end(); I != E; ++I) { + if (!SuccsHandled[(*I)->getNumber()]) { + SuccsHandled[(*I)->getNumber()] = true; + JumpTableBB->addSuccessor(*I); + } + } - // Get the Value to be switched on and default basic blocks, which will be - // inserted into CaseBlock records, representing basic blocks in the binary - // search tree. - const Value *SV = SI.getOperand(0); + // Create a jump table index for this jump table. + unsigned JTEncoding = TLI.getJumpTableEncoding(); + unsigned JTI = CurMF->getOrCreateJumpTableInfo(JTEncoding) + ->createJumpTableIndex(DestBBs); - // Push the initial CaseRec onto the worklist - CaseRecVector WorkList; - WorkList.push_back(CaseRec(SwitchMBB,0,0, - CaseRange(Cases.begin(),Cases.end()))); + // Set the jump table information so that we can codegen it as a second + // MachineBasicBlock + JumpTable JT(-1U, JTI, JumpTableBB, Default); + JumpTableHeader JTH(First, Last, SV, CR.CaseBB, (CR.CaseBB == SwitchBB)); + if (CR.CaseBB == SwitchBB) + visitJumpTableHeader(JT, JTH, SwitchBB); - while (!WorkList.empty()) { - // Grab a record representing a case range to process off the worklist - CaseRec CR = WorkList.back(); - WorkList.pop_back(); + JTCases.push_back(JumpTableBlock(JTH, JT)); - if (handleBitTestsSwitchCase(CR, WorkList, SV, Default, SwitchMBB)) - continue; + return true; +} - // If the range has few cases (two or less) emit a series of specific - // tests. - if (handleSmallSwitchRange(CR, WorkList, SV, Default, SwitchMBB)) - continue; +/// handleBTSplitSwitchCase - emit comparison and split binary search tree into +/// 2 subtrees. +bool SelectionDAGBuilder::handleBTSplitSwitchCase(CaseRec& CR, + CaseRecVector& WorkList, + const Value* SV, + MachineBasicBlock *Default, + MachineBasicBlock *SwitchBB) { + // Get the MachineFunction which holds the current MBB. This is used when + // inserting any additional MBBs necessary to represent the switch. + MachineFunction *CurMF = FuncInfo.MF; - // If the switch has more than 5 blocks, and at least 40% dense, and the - // target supports indirect branches, then emit a jump table rather than - // lowering the switch to a binary tree of conditional branches. - if (handleJTSwitchCase(CR, WorkList, SV, Default, SwitchMBB)) - continue; + // Figure out which block is immediately after the current one. + MachineFunction::iterator BBI = CR.CaseBB; + ++BBI; - // Emit binary tree. We need to pick a pivot, and push left and right ranges - // onto the worklist. Leafs are handled via handleSmallSwitchRange() call. - handleBTSplitSwitchCase(CR, WorkList, SV, Default, SwitchMBB); - } -} + Case& FrontCase = *CR.Range.first; + Case& BackCase = *(CR.Range.second-1); + const BasicBlock *LLVMBB = CR.CaseBB->getBasicBlock(); -void SelectionDAGBuilder::visitIndirectBr(const IndirectBrInst &I) { - MachineBasicBlock *IndirectBrMBB = FuncInfo.MBBMap[I.getParent()]; + // Size is the number of Cases represented by this range. + unsigned Size = CR.Range.second - CR.Range.first; - // Update machine-CFG edges with unique successors. - SmallVector succs; - succs.reserve(I.getNumSuccessors()); - for (unsigned i = 0, e = I.getNumSuccessors(); i != e; ++i) - succs.push_back(I.getSuccessor(i)); - array_pod_sort(succs.begin(), succs.end()); - succs.erase(std::unique(succs.begin(), succs.end()), succs.end()); - for (unsigned i = 0, e = succs.size(); i != e; ++i) - IndirectBrMBB->addSuccessor(FuncInfo.MBBMap[succs[i]]); + const APInt &First = cast(FrontCase.Low)->getValue(); + const APInt &Last = cast(BackCase.High)->getValue(); + double FMetric = 0; + CaseItr Pivot = CR.Range.first + Size/2; - DAG.setRoot(DAG.getNode(ISD::BRIND, getCurDebugLoc(), - MVT::Other, getControlRoot(), - getValue(I.getAddress()))); -} + // Select optimal pivot, maximizing sum density of LHS and RHS. This will + // (heuristically) allow us to emit JumpTable's later. + APInt TSize(First.getBitWidth(), 0); + for (CaseItr I = CR.Range.first, E = CR.Range.second; + I!=E; ++I) + TSize += I->size(); -void SelectionDAGBuilder::visitFSub(const User &I) { - // -0.0 - X --> fneg - const Type *Ty = I.getType(); - if (Ty->isVectorTy()) { - if (ConstantVector *CV = dyn_cast(I.getOperand(0))) { - const VectorType *DestTy = cast(I.getType()); - const Type *ElTy = DestTy->getElementType(); - unsigned VL = DestTy->getNumElements(); - std::vector NZ(VL, ConstantFP::getNegativeZero(ElTy)); - Constant *CNZ = ConstantVector::get(&NZ[0], NZ.size()); - if (CV == CNZ) { - SDValue Op2 = getValue(I.getOperand(1)); - setValue(&I, DAG.getNode(ISD::FNEG, getCurDebugLoc(), - Op2.getValueType(), Op2)); - return; - } + APInt LSize = FrontCase.size(); + APInt RSize = TSize-LSize; + DEBUG(dbgs() << "Selecting best pivot: \n" + << "First: " << First << ", Last: " << Last <<'\n' + << "LSize: " << LSize << ", RSize: " << RSize << '\n'); + for (CaseItr I = CR.Range.first, J=I+1, E = CR.Range.second; + J!=E; ++I, ++J) { + const APInt &LEnd = cast(I->High)->getValue(); + const APInt &RBegin = cast(J->Low)->getValue(); + APInt Range = ComputeRange(LEnd, RBegin); + assert((Range - 2ULL).isNonNegative() && + "Invalid case distance"); + double LDensity = (double)LSize.roundToDouble() / + (LEnd - First + 1ULL).roundToDouble(); + double RDensity = (double)RSize.roundToDouble() / + (Last - RBegin + 1ULL).roundToDouble(); + double Metric = Range.logBase2()*(LDensity+RDensity); + // Should always split in some non-trivial place + DEBUG(dbgs() <<"=>Step\n" + << "LEnd: " << LEnd << ", RBegin: " << RBegin << '\n' + << "LDensity: " << LDensity + << ", RDensity: " << RDensity << '\n' + << "Metric: " << Metric << '\n'); + if (FMetric < Metric) { + Pivot = J; + FMetric = Metric; + DEBUG(dbgs() << "Current metric set to: " << FMetric << '\n'); } + + LSize += J->size(); + RSize -= J->size(); + } + if (areJTsAllowed(TLI)) { + // If our case is dense we *really* should handle it earlier! + assert((FMetric > 0) && "Should handle dense range earlier!"); + } else { + Pivot = CR.Range.first + Size/2; } - if (ConstantFP *CFP = dyn_cast(I.getOperand(0))) - if (CFP->isExactlyValue(ConstantFP::getNegativeZero(Ty)->getValueAPF())) { - SDValue Op2 = getValue(I.getOperand(1)); - setValue(&I, DAG.getNode(ISD::FNEG, getCurDebugLoc(), - Op2.getValueType(), Op2)); - return; - } + CaseRange LHSR(CR.Range.first, Pivot); + CaseRange RHSR(Pivot, CR.Range.second); + Constant *C = Pivot->Low; + MachineBasicBlock *FalseBB = 0, *TrueBB = 0; - visitBinary(I, ISD::FSUB); -} + // We know that we branch to the LHS if the Value being switched on is + // less than the Pivot value, C. We use this to optimize our binary + // tree a bit, by recognizing that if SV is greater than or equal to the + // LHS's Case Value, and that Case Value is exactly one less than the + // Pivot's Value, then we can branch directly to the LHS's Target, + // rather than creating a leaf node for it. + if ((LHSR.second - LHSR.first) == 1 && + LHSR.first->High == CR.GE && + cast(C)->getValue() == + (cast(CR.GE)->getValue() + 1LL)) { + TrueBB = LHSR.first->BB; + } else { + TrueBB = CurMF->CreateMachineBasicBlock(LLVMBB); + CurMF->insert(BBI, TrueBB); + WorkList.push_back(CaseRec(TrueBB, C, CR.GE, LHSR)); -void SelectionDAGBuilder::visitBinary(const User &I, unsigned OpCode) { - SDValue Op1 = getValue(I.getOperand(0)); - SDValue Op2 = getValue(I.getOperand(1)); - setValue(&I, DAG.getNode(OpCode, getCurDebugLoc(), - Op1.getValueType(), Op1, Op2)); -} + // Put SV in a virtual register to make it available from the new blocks. + ExportFromCurrentBlock(SV); + } -void SelectionDAGBuilder::visitShift(const User &I, unsigned Opcode) { - SDValue Op1 = getValue(I.getOperand(0)); - SDValue Op2 = getValue(I.getOperand(1)); - if (!I.getType()->isVectorTy() && - Op2.getValueType() != TLI.getShiftAmountTy()) { - // If the operand is smaller than the shift count type, promote it. - EVT PTy = TLI.getPointerTy(); - EVT STy = TLI.getShiftAmountTy(); - if (STy.bitsGT(Op2.getValueType())) - Op2 = DAG.getNode(ISD::ANY_EXTEND, getCurDebugLoc(), - TLI.getShiftAmountTy(), Op2); - // If the operand is larger than the shift count type but the shift - // count type has enough bits to represent any shift value, truncate - // it now. This is a common case and it exposes the truncate to - // optimization early. - else if (STy.getSizeInBits() >= - Log2_32_Ceil(Op2.getValueType().getSizeInBits())) - Op2 = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), - TLI.getShiftAmountTy(), Op2); - // Otherwise we'll need to temporarily settle for some other - // convenient type; type legalization will make adjustments as - // needed. - else if (PTy.bitsLT(Op2.getValueType())) - Op2 = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), - TLI.getPointerTy(), Op2); - else if (PTy.bitsGT(Op2.getValueType())) - Op2 = DAG.getNode(ISD::ANY_EXTEND, getCurDebugLoc(), - TLI.getPointerTy(), Op2); + // Similar to the optimization above, if the Value being switched on is + // known to be less than the Constant CR.LT, and the current Case Value + // is CR.LT - 1, then we can branch directly to the target block for + // the current Case Value, rather than emitting a RHS leaf node for it. + if ((RHSR.second - RHSR.first) == 1 && CR.LT && + cast(RHSR.first->Low)->getValue() == + (cast(CR.LT)->getValue() - 1LL)) { + FalseBB = RHSR.first->BB; + } else { + FalseBB = CurMF->CreateMachineBasicBlock(LLVMBB); + CurMF->insert(BBI, FalseBB); + WorkList.push_back(CaseRec(FalseBB,CR.LT,C,RHSR)); + + // Put SV in a virtual register to make it available from the new blocks. + ExportFromCurrentBlock(SV); } - setValue(&I, DAG.getNode(Opcode, getCurDebugLoc(), - Op1.getValueType(), Op1, Op2)); -} + // Create a CaseBlock record representing a conditional branch to + // the LHS node if the value being switched on SV is less than C. + // Otherwise, branch to LHS. + CaseBlock CB(ISD::SETLT, SV, C, NULL, TrueBB, FalseBB, CR.CaseBB); -void SelectionDAGBuilder::visitICmp(const User &I) { - ICmpInst::Predicate predicate = ICmpInst::BAD_ICMP_PREDICATE; - if (const ICmpInst *IC = dyn_cast(&I)) - predicate = IC->getPredicate(); - else if (const ConstantExpr *IC = dyn_cast(&I)) - predicate = ICmpInst::Predicate(IC->getPredicate()); - SDValue Op1 = getValue(I.getOperand(0)); - SDValue Op2 = getValue(I.getOperand(1)); - ISD::CondCode Opcode = getICmpCondCode(predicate); + if (CR.CaseBB == SwitchBB) + visitSwitchCase(CB, SwitchBB); + else + SwitchCases.push_back(CB); - EVT DestVT = TLI.getValueType(I.getType()); - setValue(&I, DAG.getSetCC(getCurDebugLoc(), DestVT, Op1, Op2, Opcode)); + return true; } -void SelectionDAGBuilder::visitFCmp(const User &I) { - FCmpInst::Predicate predicate = FCmpInst::BAD_FCMP_PREDICATE; - if (const FCmpInst *FC = dyn_cast(&I)) - predicate = FC->getPredicate(); - else if (const ConstantExpr *FC = dyn_cast(&I)) - predicate = FCmpInst::Predicate(FC->getPredicate()); - SDValue Op1 = getValue(I.getOperand(0)); - SDValue Op2 = getValue(I.getOperand(1)); - ISD::CondCode Condition = getFCmpCondCode(predicate); - EVT DestVT = TLI.getValueType(I.getType()); - setValue(&I, DAG.getSetCC(getCurDebugLoc(), DestVT, Op1, Op2, Condition)); -} +/// handleBitTestsSwitchCase - if current case range has few destination and +/// range span less, than machine word bitwidth, encode case range into series +/// of masks and emit bit tests with these masks. +bool SelectionDAGBuilder::handleBitTestsSwitchCase(CaseRec& CR, + CaseRecVector& WorkList, + const Value* SV, + MachineBasicBlock* Default, + MachineBasicBlock *SwitchBB){ + EVT PTy = TLI.getPointerTy(); + unsigned IntPtrBits = PTy.getSizeInBits(); -void SelectionDAGBuilder::visitSelect(const User &I) { - SmallVector ValueVTs; - ComputeValueVTs(TLI, I.getType(), ValueVTs); - unsigned NumValues = ValueVTs.size(); - if (NumValues == 0) return; + Case& FrontCase = *CR.Range.first; + Case& BackCase = *(CR.Range.second-1); - SmallVector Values(NumValues); - SDValue Cond = getValue(I.getOperand(0)); - SDValue TrueVal = getValue(I.getOperand(1)); - SDValue FalseVal = getValue(I.getOperand(2)); + // Get the MachineFunction which holds the current MBB. This is used when + // inserting any additional MBBs necessary to represent the switch. + MachineFunction *CurMF = FuncInfo.MF; - for (unsigned i = 0; i != NumValues; ++i) - Values[i] = DAG.getNode(ISD::SELECT, getCurDebugLoc(), - TrueVal.getNode()->getValueType(TrueVal.getResNo()+i), - Cond, - SDValue(TrueVal.getNode(), - TrueVal.getResNo() + i), - SDValue(FalseVal.getNode(), - FalseVal.getResNo() + i)); + // If target does not have legal shift left, do not emit bit tests at all. + if (!TLI.isOperationLegal(ISD::SHL, TLI.getPointerTy())) + return false; - setValue(&I, DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(), - DAG.getVTList(&ValueVTs[0], NumValues), - &Values[0], NumValues)); -} + size_t numCmps = 0; + for (CaseItr I = CR.Range.first, E = CR.Range.second; + I!=E; ++I) { + // Single case counts one, case range - two. + numCmps += (I->Low == I->High ? 1 : 2); + } -void SelectionDAGBuilder::visitTrunc(const User &I) { - // TruncInst cannot be a no-op cast because sizeof(src) > sizeof(dest). - SDValue N = getValue(I.getOperand(0)); - EVT DestVT = TLI.getValueType(I.getType()); - setValue(&I, DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), DestVT, N)); -} + // Count unique destinations + SmallSet Dests; + for (CaseItr I = CR.Range.first, E = CR.Range.second; I!=E; ++I) { + Dests.insert(I->BB); + if (Dests.size() > 3) + // Don't bother the code below, if there are too much unique destinations + return false; + } + DEBUG(dbgs() << "Total number of unique destinations: " + << Dests.size() << '\n' + << "Total number of comparisons: " << numCmps << '\n'); -void SelectionDAGBuilder::visitZExt(const User &I) { - // ZExt cannot be a no-op cast because sizeof(src) < sizeof(dest). - // ZExt also can't be a cast to bool for same reason. So, nothing much to do - SDValue N = getValue(I.getOperand(0)); - EVT DestVT = TLI.getValueType(I.getType()); - setValue(&I, DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(), DestVT, N)); -} + // Compute span of values. + const APInt& minValue = cast(FrontCase.Low)->getValue(); + const APInt& maxValue = cast(BackCase.High)->getValue(); + APInt cmpRange = maxValue - minValue; -void SelectionDAGBuilder::visitSExt(const User &I) { - // SExt cannot be a no-op cast because sizeof(src) < sizeof(dest). - // SExt also can't be a cast to bool for same reason. So, nothing much to do - SDValue N = getValue(I.getOperand(0)); - EVT DestVT = TLI.getValueType(I.getType()); - setValue(&I, DAG.getNode(ISD::SIGN_EXTEND, getCurDebugLoc(), DestVT, N)); -} + DEBUG(dbgs() << "Compare range: " << cmpRange << '\n' + << "Low bound: " << minValue << '\n' + << "High bound: " << maxValue << '\n'); -void SelectionDAGBuilder::visitFPTrunc(const User &I) { - // FPTrunc is never a no-op cast, no need to check - SDValue N = getValue(I.getOperand(0)); - EVT DestVT = TLI.getValueType(I.getType()); - setValue(&I, DAG.getNode(ISD::FP_ROUND, getCurDebugLoc(), - DestVT, N, DAG.getIntPtrConstant(0))); -} + if (cmpRange.uge(IntPtrBits) || + (!(Dests.size() == 1 && numCmps >= 3) && + !(Dests.size() == 2 && numCmps >= 5) && + !(Dests.size() >= 3 && numCmps >= 6))) + return false; -void SelectionDAGBuilder::visitFPExt(const User &I){ - // FPTrunc is never a no-op cast, no need to check - SDValue N = getValue(I.getOperand(0)); - EVT DestVT = TLI.getValueType(I.getType()); - setValue(&I, DAG.getNode(ISD::FP_EXTEND, getCurDebugLoc(), DestVT, N)); -} + DEBUG(dbgs() << "Emitting bit tests\n"); + APInt lowBound = APInt::getNullValue(cmpRange.getBitWidth()); -void SelectionDAGBuilder::visitFPToUI(const User &I) { - // FPToUI is never a no-op cast, no need to check - SDValue N = getValue(I.getOperand(0)); - EVT DestVT = TLI.getValueType(I.getType()); - setValue(&I, DAG.getNode(ISD::FP_TO_UINT, getCurDebugLoc(), DestVT, N)); -} + // Optimize the case where all the case values fit in a + // word without having to subtract minValue. In this case, + // we can optimize away the subtraction. + if (minValue.isNonNegative() && maxValue.slt(IntPtrBits)) { + cmpRange = maxValue; + } else { + lowBound = minValue; + } -void SelectionDAGBuilder::visitFPToSI(const User &I) { - // FPToSI is never a no-op cast, no need to check - SDValue N = getValue(I.getOperand(0)); - EVT DestVT = TLI.getValueType(I.getType()); - setValue(&I, DAG.getNode(ISD::FP_TO_SINT, getCurDebugLoc(), DestVT, N)); -} + CaseBitsVector CasesBits; + unsigned i, count = 0; -void SelectionDAGBuilder::visitUIToFP(const User &I) { - // UIToFP is never a no-op cast, no need to check - SDValue N = getValue(I.getOperand(0)); - EVT DestVT = TLI.getValueType(I.getType()); - setValue(&I, DAG.getNode(ISD::UINT_TO_FP, getCurDebugLoc(), DestVT, N)); -} + for (CaseItr I = CR.Range.first, E = CR.Range.second; I!=E; ++I) { + MachineBasicBlock* Dest = I->BB; + for (i = 0; i < count; ++i) + if (Dest == CasesBits[i].BB) + break; -void SelectionDAGBuilder::visitSIToFP(const User &I){ - // SIToFP is never a no-op cast, no need to check - SDValue N = getValue(I.getOperand(0)); - EVT DestVT = TLI.getValueType(I.getType()); - setValue(&I, DAG.getNode(ISD::SINT_TO_FP, getCurDebugLoc(), DestVT, N)); -} + if (i == count) { + assert((count < 3) && "Too much destinations to test!"); + CasesBits.push_back(CaseBits(0, Dest, 0)); + count++; + } -void SelectionDAGBuilder::visitPtrToInt(const User &I) { - // What to do depends on the size of the integer and the size of the pointer. - // We can either truncate, zero extend, or no-op, accordingly. - SDValue N = getValue(I.getOperand(0)); - EVT SrcVT = N.getValueType(); - EVT DestVT = TLI.getValueType(I.getType()); - setValue(&I, DAG.getZExtOrTrunc(N, getCurDebugLoc(), DestVT)); -} + const APInt& lowValue = cast(I->Low)->getValue(); + const APInt& highValue = cast(I->High)->getValue(); -void SelectionDAGBuilder::visitIntToPtr(const User &I) { - // What to do depends on the size of the integer and the size of the pointer. - // We can either truncate, zero extend, or no-op, accordingly. - SDValue N = getValue(I.getOperand(0)); - EVT SrcVT = N.getValueType(); - EVT DestVT = TLI.getValueType(I.getType()); - setValue(&I, DAG.getZExtOrTrunc(N, getCurDebugLoc(), DestVT)); -} + uint64_t lo = (lowValue - lowBound).getZExtValue(); + uint64_t hi = (highValue - lowBound).getZExtValue(); -void SelectionDAGBuilder::visitBitCast(const User &I) { - SDValue N = getValue(I.getOperand(0)); - EVT DestVT = TLI.getValueType(I.getType()); + for (uint64_t j = lo; j <= hi; j++) { + CasesBits[i].Mask |= 1ULL << j; + CasesBits[i].Bits++; + } - // BitCast assures us that source and destination are the same size so this is - // either a BIT_CONVERT or a no-op. - if (DestVT != N.getValueType()) - setValue(&I, DAG.getNode(ISD::BIT_CONVERT, getCurDebugLoc(), - DestVT, N)); // convert types. - else - setValue(&I, N); // noop cast. -} + } + std::sort(CasesBits.begin(), CasesBits.end(), CaseBitsCmp()); -void SelectionDAGBuilder::visitInsertElement(const User &I) { - SDValue InVec = getValue(I.getOperand(0)); - SDValue InVal = getValue(I.getOperand(1)); - SDValue InIdx = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(), - TLI.getPointerTy(), - getValue(I.getOperand(2))); - setValue(&I, DAG.getNode(ISD::INSERT_VECTOR_ELT, getCurDebugLoc(), - TLI.getValueType(I.getType()), - InVec, InVal, InIdx)); -} + BitTestInfo BTC; -void SelectionDAGBuilder::visitExtractElement(const User &I) { - SDValue InVec = getValue(I.getOperand(0)); - SDValue InIdx = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(), - TLI.getPointerTy(), - getValue(I.getOperand(1))); - setValue(&I, DAG.getNode(ISD::EXTRACT_VECTOR_ELT, getCurDebugLoc(), - TLI.getValueType(I.getType()), InVec, InIdx)); -} + // Figure out which block is immediately after the current one. + MachineFunction::iterator BBI = CR.CaseBB; + ++BBI; -// Utility for visitShuffleVector - Returns true if the mask is mask starting -// from SIndx and increasing to the element length (undefs are allowed). -static bool SequentialMask(SmallVectorImpl &Mask, unsigned SIndx) { - unsigned MaskNumElts = Mask.size(); - for (unsigned i = 0; i != MaskNumElts; ++i) - if ((Mask[i] >= 0) && (Mask[i] != (int)(i + SIndx))) - return false; - return true; -} + const BasicBlock *LLVMBB = CR.CaseBB->getBasicBlock(); -void SelectionDAGBuilder::visitShuffleVector(const User &I) { - SmallVector Mask; - SDValue Src1 = getValue(I.getOperand(0)); - SDValue Src2 = getValue(I.getOperand(1)); + DEBUG(dbgs() << "Cases:\n"); + for (unsigned i = 0, e = CasesBits.size(); i!=e; ++i) { + DEBUG(dbgs() << "Mask: " << CasesBits[i].Mask + << ", Bits: " << CasesBits[i].Bits + << ", BB: " << CasesBits[i].BB << '\n'); - // Convert the ConstantVector mask operand into an array of ints, with -1 - // representing undef values. - SmallVector MaskElts; - cast(I.getOperand(2))->getVectorElements(MaskElts); - unsigned MaskNumElts = MaskElts.size(); - for (unsigned i = 0; i != MaskNumElts; ++i) { - if (isa(MaskElts[i])) - Mask.push_back(-1); - else - Mask.push_back(cast(MaskElts[i])->getSExtValue()); + MachineBasicBlock *CaseBB = CurMF->CreateMachineBasicBlock(LLVMBB); + CurMF->insert(BBI, CaseBB); + BTC.push_back(BitTestCase(CasesBits[i].Mask, + CaseBB, + CasesBits[i].BB)); + + // Put SV in a virtual register to make it available from the new blocks. + ExportFromCurrentBlock(SV); } - EVT VT = TLI.getValueType(I.getType()); - EVT SrcVT = Src1.getValueType(); - unsigned SrcNumElts = SrcVT.getVectorNumElements(); + BitTestBlock BTB(lowBound, cmpRange, SV, + -1U, (CR.CaseBB == SwitchBB), + CR.CaseBB, Default, BTC); - if (SrcNumElts == MaskNumElts) { - setValue(&I, DAG.getVectorShuffle(VT, getCurDebugLoc(), Src1, Src2, - &Mask[0])); - return; - } + if (CR.CaseBB == SwitchBB) + visitBitTestHeader(BTB, SwitchBB); - // Normalize the shuffle vector since mask and vector length don't match. - if (SrcNumElts < MaskNumElts && MaskNumElts % SrcNumElts == 0) { - // Mask is longer than the source vectors and is a multiple of the source - // vectors. We can use concatenate vector to make the mask and vectors - // lengths match. - if (SrcNumElts*2 == MaskNumElts && SequentialMask(Mask, 0)) { - // The shuffle is concatenating two vectors together. - setValue(&I, DAG.getNode(ISD::CONCAT_VECTORS, getCurDebugLoc(), - VT, Src1, Src2)); - return; - } + BitTestCases.push_back(BTB); - // Pad both vectors with undefs to make them the same length as the mask. - unsigned NumConcat = MaskNumElts / SrcNumElts; - bool Src1U = Src1.getOpcode() == ISD::UNDEF; - bool Src2U = Src2.getOpcode() == ISD::UNDEF; - SDValue UndefVal = DAG.getUNDEF(SrcVT); + return true; +} - SmallVector MOps1(NumConcat, UndefVal); - SmallVector MOps2(NumConcat, UndefVal); - MOps1[0] = Src1; - MOps2[0] = Src2; +/// Clusterify - Transform simple list of Cases into list of CaseRange's +size_t SelectionDAGBuilder::Clusterify(CaseVector& Cases, + const SwitchInst& SI) { + size_t numCmps = 0; - Src1 = Src1U ? DAG.getUNDEF(VT) : DAG.getNode(ISD::CONCAT_VECTORS, - getCurDebugLoc(), VT, - &MOps1[0], NumConcat); - Src2 = Src2U ? DAG.getUNDEF(VT) : DAG.getNode(ISD::CONCAT_VECTORS, - getCurDebugLoc(), VT, - &MOps2[0], NumConcat); + // Start with "simple" cases + for (size_t i = 1; i < SI.getNumSuccessors(); ++i) { + MachineBasicBlock *SMBB = FuncInfo.MBBMap[SI.getSuccessor(i)]; + Cases.push_back(Case(SI.getSuccessorValue(i), + SI.getSuccessorValue(i), + SMBB)); + } + std::sort(Cases.begin(), Cases.end(), CaseCmp()); - // Readjust mask for new input vector length. - SmallVector MappedOps; - for (unsigned i = 0; i != MaskNumElts; ++i) { - int Idx = Mask[i]; - if (Idx < (int)SrcNumElts) - MappedOps.push_back(Idx); - else - MappedOps.push_back(Idx + MaskNumElts - SrcNumElts); + // Merge case into clusters + if (Cases.size() >= 2) + // Must recompute end() each iteration because it may be + // invalidated by erase if we hold on to it + for (CaseItr I = Cases.begin(), J = ++(Cases.begin()); J != Cases.end(); ) { + const APInt& nextValue = cast(J->Low)->getValue(); + const APInt& currentValue = cast(I->High)->getValue(); + MachineBasicBlock* nextBB = J->BB; + MachineBasicBlock* currentBB = I->BB; + + // If the two neighboring cases go to the same destination, merge them + // into a single case. + if ((nextValue - currentValue == 1) && (currentBB == nextBB)) { + I->High = J->High; + J = Cases.erase(J); + } else { + I = J++; + } } - setValue(&I, DAG.getVectorShuffle(VT, getCurDebugLoc(), Src1, Src2, - &MappedOps[0])); - return; + for (CaseItr I=Cases.begin(), E=Cases.end(); I!=E; ++I, ++numCmps) { + if (I->Low != I->High) + // A range counts double, since it requires two compares. + ++numCmps; } - if (SrcNumElts > MaskNumElts) { - // Analyze the access pattern of the vector to see if we can extract - // two subvectors and do the shuffle. The analysis is done by calculating - // the range of elements the mask access on both vectors. - int MinRange[2] = { SrcNumElts+1, SrcNumElts+1}; - int MaxRange[2] = {-1, -1}; + return numCmps; +} - for (unsigned i = 0; i != MaskNumElts; ++i) { - int Idx = Mask[i]; - int Input = 0; - if (Idx < 0) - continue; +void SelectionDAGBuilder::visitSwitch(const SwitchInst &SI) { + MachineBasicBlock *SwitchMBB = FuncInfo.MBBMap[SI.getParent()]; - if (Idx >= (int)SrcNumElts) { - Input = 1; - Idx -= SrcNumElts; - } - if (Idx > MaxRange[Input]) - MaxRange[Input] = Idx; - if (Idx < MinRange[Input]) - MinRange[Input] = Idx; - } + // Figure out which block is immediately after the current one. + MachineBasicBlock *NextBlock = 0; + MachineBasicBlock *Default = FuncInfo.MBBMap[SI.getDefaultDest()]; - // Check if the access is smaller than the vector size and can we find - // a reasonable extract index. - int RangeUse[2] = { 2, 2 }; // 0 = Unused, 1 = Extract, 2 = Can not - // Extract. - int StartIdx[2]; // StartIdx to extract from - for (int Input=0; Input < 2; ++Input) { - if (MinRange[Input] == (int)(SrcNumElts+1) && MaxRange[Input] == -1) { - RangeUse[Input] = 0; // Unused - StartIdx[Input] = 0; - } else if (MaxRange[Input] - MinRange[Input] < (int)MaskNumElts) { - // Fits within range but we should see if we can find a good - // start index that is a multiple of the mask length. - if (MaxRange[Input] < (int)MaskNumElts) { - RangeUse[Input] = 1; // Extract from beginning of the vector - StartIdx[Input] = 0; - } else { - StartIdx[Input] = (MinRange[Input]/MaskNumElts)*MaskNumElts; - if (MaxRange[Input] - StartIdx[Input] < (int)MaskNumElts && - StartIdx[Input] + MaskNumElts < SrcNumElts) - RangeUse[Input] = 1; // Extract from a multiple of the mask length. - } - } - } - - if (RangeUse[0] == 0 && RangeUse[1] == 0) { - setValue(&I, DAG.getUNDEF(VT)); // Vectors are not used. - return; - } - else if (RangeUse[0] < 2 && RangeUse[1] < 2) { - // Extract appropriate subvector and generate a vector shuffle - for (int Input=0; Input < 2; ++Input) { - SDValue &Src = Input == 0 ? Src1 : Src2; - if (RangeUse[Input] == 0) - Src = DAG.getUNDEF(VT); - else - Src = DAG.getNode(ISD::EXTRACT_SUBVECTOR, getCurDebugLoc(), VT, - Src, DAG.getIntPtrConstant(StartIdx[Input])); - } + // If there is only the default destination, branch to it if it is not the + // next basic block. Otherwise, just fall through. + if (SI.getNumOperands() == 2) { + // Update machine-CFG edges. - // Calculate new mask. - SmallVector MappedOps; - for (unsigned i = 0; i != MaskNumElts; ++i) { - int Idx = Mask[i]; - if (Idx < 0) - MappedOps.push_back(Idx); - else if (Idx < (int)SrcNumElts) - MappedOps.push_back(Idx - StartIdx[0]); - else - MappedOps.push_back(Idx - SrcNumElts - StartIdx[1] + MaskNumElts); - } + // If this is not a fall-through branch, emit the branch. + SwitchMBB->addSuccessor(Default); + if (Default != NextBlock) + DAG.setRoot(DAG.getNode(ISD::BR, getCurDebugLoc(), + MVT::Other, getControlRoot(), + DAG.getBasicBlock(Default))); - setValue(&I, DAG.getVectorShuffle(VT, getCurDebugLoc(), Src1, Src2, - &MappedOps[0])); - return; - } + return; } - // We can't use either concat vectors or extract subvectors so fall back to - // replacing the shuffle with extract and build vector. - // to insert and build vector. - EVT EltVT = VT.getVectorElementType(); - EVT PtrVT = TLI.getPointerTy(); - SmallVector Ops; - for (unsigned i = 0; i != MaskNumElts; ++i) { - if (Mask[i] < 0) { - Ops.push_back(DAG.getUNDEF(EltVT)); - } else { - int Idx = Mask[i]; - SDValue Res; - - if (Idx < (int)SrcNumElts) - Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, getCurDebugLoc(), - EltVT, Src1, DAG.getConstant(Idx, PtrVT)); - else - Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, getCurDebugLoc(), - EltVT, Src2, - DAG.getConstant(Idx - SrcNumElts, PtrVT)); - - Ops.push_back(Res); - } - } + // If there are any non-default case statements, create a vector of Cases + // representing each one, and sort the vector so that we can efficiently + // create a binary search tree from them. + CaseVector Cases; + size_t numCmps = Clusterify(Cases, SI); + DEBUG(dbgs() << "Clusterify finished. Total clusters: " << Cases.size() + << ". Total compares: " << numCmps << '\n'); + numCmps = 0; - setValue(&I, DAG.getNode(ISD::BUILD_VECTOR, getCurDebugLoc(), - VT, &Ops[0], Ops.size())); -} + // Get the Value to be switched on and default basic blocks, which will be + // inserted into CaseBlock records, representing basic blocks in the binary + // search tree. + const Value *SV = SI.getOperand(0); -void SelectionDAGBuilder::visitInsertValue(const InsertValueInst &I) { - const Value *Op0 = I.getOperand(0); - const Value *Op1 = I.getOperand(1); - const Type *AggTy = I.getType(); - const Type *ValTy = Op1->getType(); - bool IntoUndef = isa(Op0); - bool FromUndef = isa(Op1); + // Push the initial CaseRec onto the worklist + CaseRecVector WorkList; + WorkList.push_back(CaseRec(SwitchMBB,0,0, + CaseRange(Cases.begin(),Cases.end()))); - unsigned LinearIndex = ComputeLinearIndex(TLI, AggTy, - I.idx_begin(), I.idx_end()); + while (!WorkList.empty()) { + // Grab a record representing a case range to process off the worklist + CaseRec CR = WorkList.back(); + WorkList.pop_back(); - SmallVector AggValueVTs; - ComputeValueVTs(TLI, AggTy, AggValueVTs); - SmallVector ValValueVTs; - ComputeValueVTs(TLI, ValTy, ValValueVTs); + if (handleBitTestsSwitchCase(CR, WorkList, SV, Default, SwitchMBB)) + continue; - unsigned NumAggValues = AggValueVTs.size(); - unsigned NumValValues = ValValueVTs.size(); - SmallVector Values(NumAggValues); + // If the range has few cases (two or less) emit a series of specific + // tests. + if (handleSmallSwitchRange(CR, WorkList, SV, Default, SwitchMBB)) + continue; - SDValue Agg = getValue(Op0); - SDValue Val = getValue(Op1); - unsigned i = 0; - // Copy the beginning value(s) from the original aggregate. - for (; i != LinearIndex; ++i) - Values[i] = IntoUndef ? DAG.getUNDEF(AggValueVTs[i]) : - SDValue(Agg.getNode(), Agg.getResNo() + i); - // Copy values from the inserted value(s). - for (; i != LinearIndex + NumValValues; ++i) - Values[i] = FromUndef ? DAG.getUNDEF(AggValueVTs[i]) : - SDValue(Val.getNode(), Val.getResNo() + i - LinearIndex); - // Copy remaining value(s) from the original aggregate. - for (; i != NumAggValues; ++i) - Values[i] = IntoUndef ? DAG.getUNDEF(AggValueVTs[i]) : - SDValue(Agg.getNode(), Agg.getResNo() + i); + // If the switch has more than 5 blocks, and at least 40% dense, and the + // target supports indirect branches, then emit a jump table rather than + // lowering the switch to a binary tree of conditional branches. + if (handleJTSwitchCase(CR, WorkList, SV, Default, SwitchMBB)) + continue; - setValue(&I, DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(), - DAG.getVTList(&AggValueVTs[0], NumAggValues), - &Values[0], NumAggValues)); + // Emit binary tree. We need to pick a pivot, and push left and right ranges + // onto the worklist. Leafs are handled via handleSmallSwitchRange() call. + handleBTSplitSwitchCase(CR, WorkList, SV, Default, SwitchMBB); + } } -void SelectionDAGBuilder::visitExtractValue(const ExtractValueInst &I) { - const Value *Op0 = I.getOperand(0); - const Type *AggTy = Op0->getType(); - const Type *ValTy = I.getType(); - bool OutOfUndef = isa(Op0); +void SelectionDAGBuilder::visitIndirectBr(const IndirectBrInst &I) { + MachineBasicBlock *IndirectBrMBB = FuncInfo.MBBMap[I.getParent()]; - unsigned LinearIndex = ComputeLinearIndex(TLI, AggTy, - I.idx_begin(), I.idx_end()); + // Update machine-CFG edges with unique successors. + SmallVector succs; + succs.reserve(I.getNumSuccessors()); + for (unsigned i = 0, e = I.getNumSuccessors(); i != e; ++i) + succs.push_back(I.getSuccessor(i)); + array_pod_sort(succs.begin(), succs.end()); + succs.erase(std::unique(succs.begin(), succs.end()), succs.end()); + for (unsigned i = 0, e = succs.size(); i != e; ++i) + IndirectBrMBB->addSuccessor(FuncInfo.MBBMap[succs[i]]); - SmallVector ValValueVTs; - ComputeValueVTs(TLI, ValTy, ValValueVTs); + DAG.setRoot(DAG.getNode(ISD::BRIND, getCurDebugLoc(), + MVT::Other, getControlRoot(), + getValue(I.getAddress()))); +} - unsigned NumValValues = ValValueVTs.size(); - SmallVector Values(NumValValues); +void SelectionDAGBuilder::visitFSub(const User &I) { + // -0.0 - X --> fneg + const Type *Ty = I.getType(); + if (Ty->isVectorTy()) { + if (ConstantVector *CV = dyn_cast(I.getOperand(0))) { + const VectorType *DestTy = cast(I.getType()); + const Type *ElTy = DestTy->getElementType(); + unsigned VL = DestTy->getNumElements(); + std::vector NZ(VL, ConstantFP::getNegativeZero(ElTy)); + Constant *CNZ = ConstantVector::get(&NZ[0], NZ.size()); + if (CV == CNZ) { + SDValue Op2 = getValue(I.getOperand(1)); + setValue(&I, DAG.getNode(ISD::FNEG, getCurDebugLoc(), + Op2.getValueType(), Op2)); + return; + } + } + } - SDValue Agg = getValue(Op0); - // Copy out the selected value(s). - for (unsigned i = LinearIndex; i != LinearIndex + NumValValues; ++i) - Values[i - LinearIndex] = - OutOfUndef ? - DAG.getUNDEF(Agg.getNode()->getValueType(Agg.getResNo() + i)) : - SDValue(Agg.getNode(), Agg.getResNo() + i); + if (ConstantFP *CFP = dyn_cast(I.getOperand(0))) + if (CFP->isExactlyValue(ConstantFP::getNegativeZero(Ty)->getValueAPF())) { + SDValue Op2 = getValue(I.getOperand(1)); + setValue(&I, DAG.getNode(ISD::FNEG, getCurDebugLoc(), + Op2.getValueType(), Op2)); + return; + } - setValue(&I, DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(), - DAG.getVTList(&ValValueVTs[0], NumValValues), - &Values[0], NumValValues)); + visitBinary(I, ISD::FSUB); } -void SelectionDAGBuilder::visitGetElementPtr(const User &I) { - SDValue N = getValue(I.getOperand(0)); - const Type *Ty = I.getOperand(0)->getType(); - - for (GetElementPtrInst::const_op_iterator OI = I.op_begin()+1, E = I.op_end(); - OI != E; ++OI) { - const Value *Idx = *OI; - if (const StructType *StTy = dyn_cast(Ty)) { - unsigned Field = cast(Idx)->getZExtValue(); - if (Field) { - // N = N + Offset - uint64_t Offset = TD->getStructLayout(StTy)->getElementOffset(Field); - N = DAG.getNode(ISD::ADD, getCurDebugLoc(), N.getValueType(), N, - DAG.getIntPtrConstant(Offset)); - } - - Ty = StTy->getElementType(Field); - } else if (const UnionType *UnTy = dyn_cast(Ty)) { - unsigned Field = cast(Idx)->getZExtValue(); - - // Offset canonically 0 for unions, but type changes - Ty = UnTy->getElementType(Field); - } else { - Ty = cast(Ty)->getElementType(); +void SelectionDAGBuilder::visitBinary(const User &I, unsigned OpCode) { + SDValue Op1 = getValue(I.getOperand(0)); + SDValue Op2 = getValue(I.getOperand(1)); + setValue(&I, DAG.getNode(OpCode, getCurDebugLoc(), + Op1.getValueType(), Op1, Op2)); +} - // If this is a constant subscript, handle it quickly. - if (const ConstantInt *CI = dyn_cast(Idx)) { - if (CI->getZExtValue() == 0) continue; - uint64_t Offs = - TD->getTypeAllocSize(Ty)*cast(CI)->getSExtValue(); - SDValue OffsVal; - EVT PTy = TLI.getPointerTy(); - unsigned PtrBits = PTy.getSizeInBits(); - if (PtrBits < 64) - OffsVal = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), - TLI.getPointerTy(), - DAG.getConstant(Offs, MVT::i64)); - else - OffsVal = DAG.getIntPtrConstant(Offs); - - N = DAG.getNode(ISD::ADD, getCurDebugLoc(), N.getValueType(), N, - OffsVal); - continue; - } - - // N = N + Idx * ElementSize; - APInt ElementSize = APInt(TLI.getPointerTy().getSizeInBits(), - TD->getTypeAllocSize(Ty)); - SDValue IdxN = getValue(Idx); - - // If the index is smaller or larger than intptr_t, truncate or extend - // it. - IdxN = DAG.getSExtOrTrunc(IdxN, getCurDebugLoc(), N.getValueType()); - - // If this is a multiply by a power of two, turn it into a shl - // immediately. This is a very common case. - if (ElementSize != 1) { - if (ElementSize.isPowerOf2()) { - unsigned Amt = ElementSize.logBase2(); - IdxN = DAG.getNode(ISD::SHL, getCurDebugLoc(), - N.getValueType(), IdxN, - DAG.getConstant(Amt, TLI.getPointerTy())); - } else { - SDValue Scale = DAG.getConstant(ElementSize, TLI.getPointerTy()); - IdxN = DAG.getNode(ISD::MUL, getCurDebugLoc(), - N.getValueType(), IdxN, Scale); - } - } - - N = DAG.getNode(ISD::ADD, getCurDebugLoc(), - N.getValueType(), N, IdxN); - } +void SelectionDAGBuilder::visitShift(const User &I, unsigned Opcode) { + SDValue Op1 = getValue(I.getOperand(0)); + SDValue Op2 = getValue(I.getOperand(1)); + if (!I.getType()->isVectorTy() && + Op2.getValueType() != TLI.getShiftAmountTy()) { + // If the operand is smaller than the shift count type, promote it. + EVT PTy = TLI.getPointerTy(); + EVT STy = TLI.getShiftAmountTy(); + if (STy.bitsGT(Op2.getValueType())) + Op2 = DAG.getNode(ISD::ANY_EXTEND, getCurDebugLoc(), + TLI.getShiftAmountTy(), Op2); + // If the operand is larger than the shift count type but the shift + // count type has enough bits to represent any shift value, truncate + // it now. This is a common case and it exposes the truncate to + // optimization early. + else if (STy.getSizeInBits() >= + Log2_32_Ceil(Op2.getValueType().getSizeInBits())) + Op2 = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), + TLI.getShiftAmountTy(), Op2); + // Otherwise we'll need to temporarily settle for some other + // convenient type; type legalization will make adjustments as + // needed. + else if (PTy.bitsLT(Op2.getValueType())) + Op2 = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), + TLI.getPointerTy(), Op2); + else if (PTy.bitsGT(Op2.getValueType())) + Op2 = DAG.getNode(ISD::ANY_EXTEND, getCurDebugLoc(), + TLI.getPointerTy(), Op2); } - setValue(&I, N); + setValue(&I, DAG.getNode(Opcode, getCurDebugLoc(), + Op1.getValueType(), Op1, Op2)); } -void SelectionDAGBuilder::visitAlloca(const AllocaInst &I) { - // If this is a fixed sized alloca in the entry block of the function, - // allocate it statically on the stack. - if (FuncInfo.StaticAllocaMap.count(&I)) - return; // getValue will auto-populate this. - - const Type *Ty = I.getAllocatedType(); - uint64_t TySize = TLI.getTargetData()->getTypeAllocSize(Ty); - unsigned Align = - std::max((unsigned)TLI.getTargetData()->getPrefTypeAlignment(Ty), - I.getAlignment()); - - SDValue AllocSize = getValue(I.getArraySize()); - - EVT IntPtr = TLI.getPointerTy(); - if (AllocSize.getValueType() != IntPtr) - AllocSize = DAG.getZExtOrTrunc(AllocSize, getCurDebugLoc(), IntPtr); - - AllocSize = DAG.getNode(ISD::MUL, getCurDebugLoc(), IntPtr, - AllocSize, - DAG.getConstant(TySize, IntPtr)); - - // Handle alignment. If the requested alignment is less than or equal to - // the stack alignment, ignore it. If the size is greater than or equal to - // the stack alignment, we note this in the DYNAMIC_STACKALLOC node. - unsigned StackAlign = TM.getFrameInfo()->getStackAlignment(); - if (Align <= StackAlign) - Align = 0; - - // Round the size of the allocation up to the stack alignment size - // by add SA-1 to the size. - AllocSize = DAG.getNode(ISD::ADD, getCurDebugLoc(), - AllocSize.getValueType(), AllocSize, - DAG.getIntPtrConstant(StackAlign-1)); - - // Mask out the low bits for alignment purposes. - AllocSize = DAG.getNode(ISD::AND, getCurDebugLoc(), - AllocSize.getValueType(), AllocSize, - DAG.getIntPtrConstant(~(uint64_t)(StackAlign-1))); - - SDValue Ops[] = { getRoot(), AllocSize, DAG.getIntPtrConstant(Align) }; - SDVTList VTs = DAG.getVTList(AllocSize.getValueType(), MVT::Other); - SDValue DSA = DAG.getNode(ISD::DYNAMIC_STACKALLOC, getCurDebugLoc(), - VTs, Ops, 3); - setValue(&I, DSA); - DAG.setRoot(DSA.getValue(1)); +void SelectionDAGBuilder::visitICmp(const User &I) { + ICmpInst::Predicate predicate = ICmpInst::BAD_ICMP_PREDICATE; + if (const ICmpInst *IC = dyn_cast(&I)) + predicate = IC->getPredicate(); + else if (const ConstantExpr *IC = dyn_cast(&I)) + predicate = ICmpInst::Predicate(IC->getPredicate()); + SDValue Op1 = getValue(I.getOperand(0)); + SDValue Op2 = getValue(I.getOperand(1)); + ISD::CondCode Opcode = getICmpCondCode(predicate); - // Inform the Frame Information that we have just allocated a variable-sized - // object. - FuncInfo.MF->getFrameInfo()->CreateVariableSizedObject(); + EVT DestVT = TLI.getValueType(I.getType()); + setValue(&I, DAG.getSetCC(getCurDebugLoc(), DestVT, Op1, Op2, Opcode)); } -void SelectionDAGBuilder::visitLoad(const LoadInst &I) { - const Value *SV = I.getOperand(0); - SDValue Ptr = getValue(SV); - - const Type *Ty = I.getType(); - - bool isVolatile = I.isVolatile(); - bool isNonTemporal = I.getMetadata("nontemporal") != 0; - unsigned Alignment = I.getAlignment(); +void SelectionDAGBuilder::visitFCmp(const User &I) { + FCmpInst::Predicate predicate = FCmpInst::BAD_FCMP_PREDICATE; + if (const FCmpInst *FC = dyn_cast(&I)) + predicate = FC->getPredicate(); + else if (const ConstantExpr *FC = dyn_cast(&I)) + predicate = FCmpInst::Predicate(FC->getPredicate()); + SDValue Op1 = getValue(I.getOperand(0)); + SDValue Op2 = getValue(I.getOperand(1)); + ISD::CondCode Condition = getFCmpCondCode(predicate); + EVT DestVT = TLI.getValueType(I.getType()); + setValue(&I, DAG.getSetCC(getCurDebugLoc(), DestVT, Op1, Op2, Condition)); +} +void SelectionDAGBuilder::visitSelect(const User &I) { SmallVector ValueVTs; - SmallVector Offsets; - ComputeValueVTs(TLI, Ty, ValueVTs, &Offsets); + ComputeValueVTs(TLI, I.getType(), ValueVTs); unsigned NumValues = ValueVTs.size(); - if (NumValues == 0) - return; - - SDValue Root; - bool ConstantMemory = false; - if (I.isVolatile()) - // Serialize volatile loads with other side effects. - Root = getRoot(); - else if (AA->pointsToConstantMemory(SV)) { - // Do not serialize (non-volatile) loads of constant memory with anything. - Root = DAG.getEntryNode(); - ConstantMemory = true; - } else { - // Do not serialize non-volatile loads against each other. - Root = DAG.getRoot(); - } + if (NumValues == 0) return; SmallVector Values(NumValues); - SmallVector Chains(NumValues); - EVT PtrVT = Ptr.getValueType(); - for (unsigned i = 0; i != NumValues; ++i) { - SDValue A = DAG.getNode(ISD::ADD, getCurDebugLoc(), - PtrVT, Ptr, - DAG.getConstant(Offsets[i], PtrVT)); - SDValue L = DAG.getLoad(ValueVTs[i], getCurDebugLoc(), Root, - A, SV, Offsets[i], isVolatile, - isNonTemporal, Alignment); - - Values[i] = L; - Chains[i] = L.getValue(1); - } + SDValue Cond = getValue(I.getOperand(0)); + SDValue TrueVal = getValue(I.getOperand(1)); + SDValue FalseVal = getValue(I.getOperand(2)); - if (!ConstantMemory) { - SDValue Chain = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(), - MVT::Other, &Chains[0], NumValues); - if (isVolatile) - DAG.setRoot(Chain); - else - PendingLoads.push_back(Chain); - } + for (unsigned i = 0; i != NumValues; ++i) + Values[i] = DAG.getNode(ISD::SELECT, getCurDebugLoc(), + TrueVal.getNode()->getValueType(TrueVal.getResNo()+i), + Cond, + SDValue(TrueVal.getNode(), + TrueVal.getResNo() + i), + SDValue(FalseVal.getNode(), + FalseVal.getResNo() + i)); setValue(&I, DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(), DAG.getVTList(&ValueVTs[0], NumValues), &Values[0], NumValues)); } -void SelectionDAGBuilder::visitStore(const StoreInst &I) { - const Value *SrcV = I.getOperand(0); - const Value *PtrV = I.getOperand(1); +void SelectionDAGBuilder::visitTrunc(const User &I) { + // TruncInst cannot be a no-op cast because sizeof(src) > sizeof(dest). + SDValue N = getValue(I.getOperand(0)); + EVT DestVT = TLI.getValueType(I.getType()); + setValue(&I, DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), DestVT, N)); +} - SmallVector ValueVTs; - SmallVector Offsets; - ComputeValueVTs(TLI, SrcV->getType(), ValueVTs, &Offsets); - unsigned NumValues = ValueVTs.size(); - if (NumValues == 0) - return; +void SelectionDAGBuilder::visitZExt(const User &I) { + // ZExt cannot be a no-op cast because sizeof(src) < sizeof(dest). + // ZExt also can't be a cast to bool for same reason. So, nothing much to do + SDValue N = getValue(I.getOperand(0)); + EVT DestVT = TLI.getValueType(I.getType()); + setValue(&I, DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(), DestVT, N)); +} - // Get the lowered operands. Note that we do this after - // checking if NumResults is zero, because with zero results - // the operands won't have values in the map. - SDValue Src = getValue(SrcV); - SDValue Ptr = getValue(PtrV); +void SelectionDAGBuilder::visitSExt(const User &I) { + // SExt cannot be a no-op cast because sizeof(src) < sizeof(dest). + // SExt also can't be a cast to bool for same reason. So, nothing much to do + SDValue N = getValue(I.getOperand(0)); + EVT DestVT = TLI.getValueType(I.getType()); + setValue(&I, DAG.getNode(ISD::SIGN_EXTEND, getCurDebugLoc(), DestVT, N)); +} - SDValue Root = getRoot(); - SmallVector Chains(NumValues); - EVT PtrVT = Ptr.getValueType(); - bool isVolatile = I.isVolatile(); - bool isNonTemporal = I.getMetadata("nontemporal") != 0; - unsigned Alignment = I.getAlignment(); +void SelectionDAGBuilder::visitFPTrunc(const User &I) { + // FPTrunc is never a no-op cast, no need to check + SDValue N = getValue(I.getOperand(0)); + EVT DestVT = TLI.getValueType(I.getType()); + setValue(&I, DAG.getNode(ISD::FP_ROUND, getCurDebugLoc(), + DestVT, N, DAG.getIntPtrConstant(0))); +} - for (unsigned i = 0; i != NumValues; ++i) { - SDValue Add = DAG.getNode(ISD::ADD, getCurDebugLoc(), PtrVT, Ptr, - DAG.getConstant(Offsets[i], PtrVT)); - Chains[i] = DAG.getStore(Root, getCurDebugLoc(), - SDValue(Src.getNode(), Src.getResNo() + i), - Add, PtrV, Offsets[i], isVolatile, - isNonTemporal, Alignment); - } - - DAG.setRoot(DAG.getNode(ISD::TokenFactor, getCurDebugLoc(), - MVT::Other, &Chains[0], NumValues)); +void SelectionDAGBuilder::visitFPExt(const User &I){ + // FPTrunc is never a no-op cast, no need to check + SDValue N = getValue(I.getOperand(0)); + EVT DestVT = TLI.getValueType(I.getType()); + setValue(&I, DAG.getNode(ISD::FP_EXTEND, getCurDebugLoc(), DestVT, N)); } -/// visitTargetIntrinsic - Lower a call of a target intrinsic to an INTRINSIC -/// node. -void SelectionDAGBuilder::visitTargetIntrinsic(const CallInst &I, - unsigned Intrinsic) { - bool HasChain = !I.doesNotAccessMemory(); - bool OnlyLoad = HasChain && I.onlyReadsMemory(); - - // Build the operand list. - SmallVector Ops; - if (HasChain) { // If this intrinsic has side-effects, chainify it. - if (OnlyLoad) { - // We don't need to serialize loads against other loads. - Ops.push_back(DAG.getRoot()); - } else { - Ops.push_back(getRoot()); - } - } - - // Info is set by getTgtMemInstrinsic - TargetLowering::IntrinsicInfo Info; - bool IsTgtIntrinsic = TLI.getTgtMemIntrinsic(Info, I, Intrinsic); - - // Add the intrinsic ID as an integer operand if it's not a target intrinsic. - if (!IsTgtIntrinsic) - Ops.push_back(DAG.getConstant(Intrinsic, TLI.getPointerTy())); - - // Add all operands of the call to the operand list. - for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) { - SDValue Op = getValue(I.getOperand(i)); - assert(TLI.isTypeLegal(Op.getValueType()) && - "Intrinsic uses a non-legal type?"); - Ops.push_back(Op); - } +void SelectionDAGBuilder::visitFPToUI(const User &I) { + // FPToUI is never a no-op cast, no need to check + SDValue N = getValue(I.getOperand(0)); + EVT DestVT = TLI.getValueType(I.getType()); + setValue(&I, DAG.getNode(ISD::FP_TO_UINT, getCurDebugLoc(), DestVT, N)); +} - SmallVector ValueVTs; - ComputeValueVTs(TLI, I.getType(), ValueVTs); -#ifndef NDEBUG - for (unsigned Val = 0, E = ValueVTs.size(); Val != E; ++Val) { - assert(TLI.isTypeLegal(ValueVTs[Val]) && - "Intrinsic uses a non-legal type?"); - } -#endif // NDEBUG +void SelectionDAGBuilder::visitFPToSI(const User &I) { + // FPToSI is never a no-op cast, no need to check + SDValue N = getValue(I.getOperand(0)); + EVT DestVT = TLI.getValueType(I.getType()); + setValue(&I, DAG.getNode(ISD::FP_TO_SINT, getCurDebugLoc(), DestVT, N)); +} - if (HasChain) - ValueVTs.push_back(MVT::Other); +void SelectionDAGBuilder::visitUIToFP(const User &I) { + // UIToFP is never a no-op cast, no need to check + SDValue N = getValue(I.getOperand(0)); + EVT DestVT = TLI.getValueType(I.getType()); + setValue(&I, DAG.getNode(ISD::UINT_TO_FP, getCurDebugLoc(), DestVT, N)); +} - SDVTList VTs = DAG.getVTList(ValueVTs.data(), ValueVTs.size()); +void SelectionDAGBuilder::visitSIToFP(const User &I){ + // SIToFP is never a no-op cast, no need to check + SDValue N = getValue(I.getOperand(0)); + EVT DestVT = TLI.getValueType(I.getType()); + setValue(&I, DAG.getNode(ISD::SINT_TO_FP, getCurDebugLoc(), DestVT, N)); +} - // Create the node. - SDValue Result; - if (IsTgtIntrinsic) { - // This is target intrinsic that touches memory - Result = DAG.getMemIntrinsicNode(Info.opc, getCurDebugLoc(), - VTs, &Ops[0], Ops.size(), - Info.memVT, Info.ptrVal, Info.offset, - Info.align, Info.vol, - Info.readMem, Info.writeMem); - } else if (!HasChain) { - Result = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, getCurDebugLoc(), - VTs, &Ops[0], Ops.size()); - } else if (!I.getType()->isVoidTy()) { - Result = DAG.getNode(ISD::INTRINSIC_W_CHAIN, getCurDebugLoc(), - VTs, &Ops[0], Ops.size()); - } else { - Result = DAG.getNode(ISD::INTRINSIC_VOID, getCurDebugLoc(), - VTs, &Ops[0], Ops.size()); - } +void SelectionDAGBuilder::visitPtrToInt(const User &I) { + // What to do depends on the size of the integer and the size of the pointer. + // We can either truncate, zero extend, or no-op, accordingly. + SDValue N = getValue(I.getOperand(0)); + EVT SrcVT = N.getValueType(); + EVT DestVT = TLI.getValueType(I.getType()); + setValue(&I, DAG.getZExtOrTrunc(N, getCurDebugLoc(), DestVT)); +} - if (HasChain) { - SDValue Chain = Result.getValue(Result.getNode()->getNumValues()-1); - if (OnlyLoad) - PendingLoads.push_back(Chain); - else - DAG.setRoot(Chain); - } +void SelectionDAGBuilder::visitIntToPtr(const User &I) { + // What to do depends on the size of the integer and the size of the pointer. + // We can either truncate, zero extend, or no-op, accordingly. + SDValue N = getValue(I.getOperand(0)); + EVT SrcVT = N.getValueType(); + EVT DestVT = TLI.getValueType(I.getType()); + setValue(&I, DAG.getZExtOrTrunc(N, getCurDebugLoc(), DestVT)); +} - if (!I.getType()->isVoidTy()) { - if (const VectorType *PTy = dyn_cast(I.getType())) { - EVT VT = TLI.getValueType(PTy); - Result = DAG.getNode(ISD::BIT_CONVERT, getCurDebugLoc(), VT, Result); - } +void SelectionDAGBuilder::visitBitCast(const User &I) { + SDValue N = getValue(I.getOperand(0)); + EVT DestVT = TLI.getValueType(I.getType()); - setValue(&I, Result); - } + // BitCast assures us that source and destination are the same size so this is + // either a BIT_CONVERT or a no-op. + if (DestVT != N.getValueType()) + setValue(&I, DAG.getNode(ISD::BIT_CONVERT, getCurDebugLoc(), + DestVT, N)); // convert types. + else + setValue(&I, N); // noop cast. } -/// GetSignificand - Get the significand and build it into a floating-point -/// number with exponent of 1: -/// -/// Op = (Op & 0x007fffff) | 0x3f800000; -/// -/// where Op is the hexidecimal representation of floating point value. -static SDValue -GetSignificand(SelectionDAG &DAG, SDValue Op, DebugLoc dl) { - SDValue t1 = DAG.getNode(ISD::AND, dl, MVT::i32, Op, - DAG.getConstant(0x007fffff, MVT::i32)); - SDValue t2 = DAG.getNode(ISD::OR, dl, MVT::i32, t1, - DAG.getConstant(0x3f800000, MVT::i32)); - return DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, t2); +void SelectionDAGBuilder::visitInsertElement(const User &I) { + SDValue InVec = getValue(I.getOperand(0)); + SDValue InVal = getValue(I.getOperand(1)); + SDValue InIdx = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(), + TLI.getPointerTy(), + getValue(I.getOperand(2))); + setValue(&I, DAG.getNode(ISD::INSERT_VECTOR_ELT, getCurDebugLoc(), + TLI.getValueType(I.getType()), + InVec, InVal, InIdx)); } -/// GetExponent - Get the exponent: -/// -/// (float)(int)(((Op & 0x7f800000) >> 23) - 127); -/// -/// where Op is the hexidecimal representation of floating point value. -static SDValue -GetExponent(SelectionDAG &DAG, SDValue Op, const TargetLowering &TLI, - DebugLoc dl) { - SDValue t0 = DAG.getNode(ISD::AND, dl, MVT::i32, Op, - DAG.getConstant(0x7f800000, MVT::i32)); - SDValue t1 = DAG.getNode(ISD::SRL, dl, MVT::i32, t0, - DAG.getConstant(23, TLI.getPointerTy())); - SDValue t2 = DAG.getNode(ISD::SUB, dl, MVT::i32, t1, - DAG.getConstant(127, MVT::i32)); - return DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, t2); +void SelectionDAGBuilder::visitExtractElement(const User &I) { + SDValue InVec = getValue(I.getOperand(0)); + SDValue InIdx = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(), + TLI.getPointerTy(), + getValue(I.getOperand(1))); + setValue(&I, DAG.getNode(ISD::EXTRACT_VECTOR_ELT, getCurDebugLoc(), + TLI.getValueType(I.getType()), InVec, InIdx)); } -/// getF32Constant - Get 32-bit floating point constant. -static SDValue -getF32Constant(SelectionDAG &DAG, unsigned Flt) { - return DAG.getConstantFP(APFloat(APInt(32, Flt)), MVT::f32); +// Utility for visitShuffleVector - Returns true if the mask is mask starting +// from SIndx and increasing to the element length (undefs are allowed). +static bool SequentialMask(SmallVectorImpl &Mask, unsigned SIndx) { + unsigned MaskNumElts = Mask.size(); + for (unsigned i = 0; i != MaskNumElts; ++i) + if ((Mask[i] >= 0) && (Mask[i] != (int)(i + SIndx))) + return false; + return true; } -/// Inlined utility function to implement binary input atomic intrinsics for -/// visitIntrinsicCall: I is a call instruction -/// Op is the associated NodeType for I -const char * -SelectionDAGBuilder::implVisitBinaryAtomic(const CallInst& I, - ISD::NodeType Op) { - SDValue Root = getRoot(); - SDValue L = - DAG.getAtomic(Op, getCurDebugLoc(), - getValue(I.getOperand(2)).getValueType().getSimpleVT(), - Root, - getValue(I.getOperand(1)), - getValue(I.getOperand(2)), - I.getOperand(1)); - setValue(&I, L); - DAG.setRoot(L.getValue(1)); - return 0; -} +void SelectionDAGBuilder::visitShuffleVector(const User &I) { + SmallVector Mask; + SDValue Src1 = getValue(I.getOperand(0)); + SDValue Src2 = getValue(I.getOperand(1)); -// implVisitAluOverflow - Lower arithmetic overflow instrinsics. -const char * -SelectionDAGBuilder::implVisitAluOverflow(const CallInst &I, ISD::NodeType Op) { - SDValue Op1 = getValue(I.getOperand(1)); - SDValue Op2 = getValue(I.getOperand(2)); + // Convert the ConstantVector mask operand into an array of ints, with -1 + // representing undef values. + SmallVector MaskElts; + cast(I.getOperand(2))->getVectorElements(MaskElts); + unsigned MaskNumElts = MaskElts.size(); + for (unsigned i = 0; i != MaskNumElts; ++i) { + if (isa(MaskElts[i])) + Mask.push_back(-1); + else + Mask.push_back(cast(MaskElts[i])->getSExtValue()); + } - SDVTList VTs = DAG.getVTList(Op1.getValueType(), MVT::i1); - setValue(&I, DAG.getNode(Op, getCurDebugLoc(), VTs, Op1, Op2)); - return 0; -} + EVT VT = TLI.getValueType(I.getType()); + EVT SrcVT = Src1.getValueType(); + unsigned SrcNumElts = SrcVT.getVectorNumElements(); -/// visitExp - Lower an exp intrinsic. Handles the special sequences for -/// limited-precision mode. -void -SelectionDAGBuilder::visitExp(const CallInst &I) { - SDValue result; - DebugLoc dl = getCurDebugLoc(); + if (SrcNumElts == MaskNumElts) { + setValue(&I, DAG.getVectorShuffle(VT, getCurDebugLoc(), Src1, Src2, + &Mask[0])); + return; + } - if (getValue(I.getOperand(1)).getValueType() == MVT::f32 && - LimitFloatPrecision > 0 && LimitFloatPrecision <= 18) { + // Normalize the shuffle vector since mask and vector length don't match. + if (SrcNumElts < MaskNumElts && MaskNumElts % SrcNumElts == 0) { + // Mask is longer than the source vectors and is a multiple of the source + // vectors. We can use concatenate vector to make the mask and vectors + // lengths match. + if (SrcNumElts*2 == MaskNumElts && SequentialMask(Mask, 0)) { + // The shuffle is concatenating two vectors together. + setValue(&I, DAG.getNode(ISD::CONCAT_VECTORS, getCurDebugLoc(), + VT, Src1, Src2)); + return; + } + + // Pad both vectors with undefs to make them the same length as the mask. + unsigned NumConcat = MaskNumElts / SrcNumElts; + bool Src1U = Src1.getOpcode() == ISD::UNDEF; + bool Src2U = Src2.getOpcode() == ISD::UNDEF; + SDValue UndefVal = DAG.getUNDEF(SrcVT); + + SmallVector MOps1(NumConcat, UndefVal); + SmallVector MOps2(NumConcat, UndefVal); + MOps1[0] = Src1; + MOps2[0] = Src2; + + Src1 = Src1U ? DAG.getUNDEF(VT) : DAG.getNode(ISD::CONCAT_VECTORS, + getCurDebugLoc(), VT, + &MOps1[0], NumConcat); + Src2 = Src2U ? DAG.getUNDEF(VT) : DAG.getNode(ISD::CONCAT_VECTORS, + getCurDebugLoc(), VT, + &MOps2[0], NumConcat); + + // Readjust mask for new input vector length. + SmallVector MappedOps; + for (unsigned i = 0; i != MaskNumElts; ++i) { + int Idx = Mask[i]; + if (Idx < (int)SrcNumElts) + MappedOps.push_back(Idx); + else + MappedOps.push_back(Idx + MaskNumElts - SrcNumElts); + } + + setValue(&I, DAG.getVectorShuffle(VT, getCurDebugLoc(), Src1, Src2, + &MappedOps[0])); + return; + } + + if (SrcNumElts > MaskNumElts) { + // Analyze the access pattern of the vector to see if we can extract + // two subvectors and do the shuffle. The analysis is done by calculating + // the range of elements the mask access on both vectors. + int MinRange[2] = { SrcNumElts+1, SrcNumElts+1}; + int MaxRange[2] = {-1, -1}; + + for (unsigned i = 0; i != MaskNumElts; ++i) { + int Idx = Mask[i]; + int Input = 0; + if (Idx < 0) + continue; + + if (Idx >= (int)SrcNumElts) { + Input = 1; + Idx -= SrcNumElts; + } + if (Idx > MaxRange[Input]) + MaxRange[Input] = Idx; + if (Idx < MinRange[Input]) + MinRange[Input] = Idx; + } + + // Check if the access is smaller than the vector size and can we find + // a reasonable extract index. + int RangeUse[2] = { 2, 2 }; // 0 = Unused, 1 = Extract, 2 = Can not + // Extract. + int StartIdx[2]; // StartIdx to extract from + for (int Input=0; Input < 2; ++Input) { + if (MinRange[Input] == (int)(SrcNumElts+1) && MaxRange[Input] == -1) { + RangeUse[Input] = 0; // Unused + StartIdx[Input] = 0; + } else if (MaxRange[Input] - MinRange[Input] < (int)MaskNumElts) { + // Fits within range but we should see if we can find a good + // start index that is a multiple of the mask length. + if (MaxRange[Input] < (int)MaskNumElts) { + RangeUse[Input] = 1; // Extract from beginning of the vector + StartIdx[Input] = 0; + } else { + StartIdx[Input] = (MinRange[Input]/MaskNumElts)*MaskNumElts; + if (MaxRange[Input] - StartIdx[Input] < (int)MaskNumElts && + StartIdx[Input] + MaskNumElts < SrcNumElts) + RangeUse[Input] = 1; // Extract from a multiple of the mask length. + } + } + } + + if (RangeUse[0] == 0 && RangeUse[1] == 0) { + setValue(&I, DAG.getUNDEF(VT)); // Vectors are not used. + return; + } + else if (RangeUse[0] < 2 && RangeUse[1] < 2) { + // Extract appropriate subvector and generate a vector shuffle + for (int Input=0; Input < 2; ++Input) { + SDValue &Src = Input == 0 ? Src1 : Src2; + if (RangeUse[Input] == 0) + Src = DAG.getUNDEF(VT); + else + Src = DAG.getNode(ISD::EXTRACT_SUBVECTOR, getCurDebugLoc(), VT, + Src, DAG.getIntPtrConstant(StartIdx[Input])); + } + + // Calculate new mask. + SmallVector MappedOps; + for (unsigned i = 0; i != MaskNumElts; ++i) { + int Idx = Mask[i]; + if (Idx < 0) + MappedOps.push_back(Idx); + else if (Idx < (int)SrcNumElts) + MappedOps.push_back(Idx - StartIdx[0]); + else + MappedOps.push_back(Idx - SrcNumElts - StartIdx[1] + MaskNumElts); + } + + setValue(&I, DAG.getVectorShuffle(VT, getCurDebugLoc(), Src1, Src2, + &MappedOps[0])); + return; + } + } + + // We can't use either concat vectors or extract subvectors so fall back to + // replacing the shuffle with extract and build vector. + // to insert and build vector. + EVT EltVT = VT.getVectorElementType(); + EVT PtrVT = TLI.getPointerTy(); + SmallVector Ops; + for (unsigned i = 0; i != MaskNumElts; ++i) { + if (Mask[i] < 0) { + Ops.push_back(DAG.getUNDEF(EltVT)); + } else { + int Idx = Mask[i]; + SDValue Res; + + if (Idx < (int)SrcNumElts) + Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, getCurDebugLoc(), + EltVT, Src1, DAG.getConstant(Idx, PtrVT)); + else + Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, getCurDebugLoc(), + EltVT, Src2, + DAG.getConstant(Idx - SrcNumElts, PtrVT)); + + Ops.push_back(Res); + } + } + + setValue(&I, DAG.getNode(ISD::BUILD_VECTOR, getCurDebugLoc(), + VT, &Ops[0], Ops.size())); +} + +void SelectionDAGBuilder::visitInsertValue(const InsertValueInst &I) { + const Value *Op0 = I.getOperand(0); + const Value *Op1 = I.getOperand(1); + const Type *AggTy = I.getType(); + const Type *ValTy = Op1->getType(); + bool IntoUndef = isa(Op0); + bool FromUndef = isa(Op1); + + unsigned LinearIndex = ComputeLinearIndex(TLI, AggTy, + I.idx_begin(), I.idx_end()); + + SmallVector AggValueVTs; + ComputeValueVTs(TLI, AggTy, AggValueVTs); + SmallVector ValValueVTs; + ComputeValueVTs(TLI, ValTy, ValValueVTs); + + unsigned NumAggValues = AggValueVTs.size(); + unsigned NumValValues = ValValueVTs.size(); + SmallVector Values(NumAggValues); + + SDValue Agg = getValue(Op0); + SDValue Val = getValue(Op1); + unsigned i = 0; + // Copy the beginning value(s) from the original aggregate. + for (; i != LinearIndex; ++i) + Values[i] = IntoUndef ? DAG.getUNDEF(AggValueVTs[i]) : + SDValue(Agg.getNode(), Agg.getResNo() + i); + // Copy values from the inserted value(s). + for (; i != LinearIndex + NumValValues; ++i) + Values[i] = FromUndef ? DAG.getUNDEF(AggValueVTs[i]) : + SDValue(Val.getNode(), Val.getResNo() + i - LinearIndex); + // Copy remaining value(s) from the original aggregate. + for (; i != NumAggValues; ++i) + Values[i] = IntoUndef ? DAG.getUNDEF(AggValueVTs[i]) : + SDValue(Agg.getNode(), Agg.getResNo() + i); + + setValue(&I, DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(), + DAG.getVTList(&AggValueVTs[0], NumAggValues), + &Values[0], NumAggValues)); +} + +void SelectionDAGBuilder::visitExtractValue(const ExtractValueInst &I) { + const Value *Op0 = I.getOperand(0); + const Type *AggTy = Op0->getType(); + const Type *ValTy = I.getType(); + bool OutOfUndef = isa(Op0); + + unsigned LinearIndex = ComputeLinearIndex(TLI, AggTy, + I.idx_begin(), I.idx_end()); + + SmallVector ValValueVTs; + ComputeValueVTs(TLI, ValTy, ValValueVTs); + + unsigned NumValValues = ValValueVTs.size(); + SmallVector Values(NumValValues); + + SDValue Agg = getValue(Op0); + // Copy out the selected value(s). + for (unsigned i = LinearIndex; i != LinearIndex + NumValValues; ++i) + Values[i - LinearIndex] = + OutOfUndef ? + DAG.getUNDEF(Agg.getNode()->getValueType(Agg.getResNo() + i)) : + SDValue(Agg.getNode(), Agg.getResNo() + i); + + setValue(&I, DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(), + DAG.getVTList(&ValValueVTs[0], NumValValues), + &Values[0], NumValValues)); +} + +void SelectionDAGBuilder::visitGetElementPtr(const User &I) { + SDValue N = getValue(I.getOperand(0)); + const Type *Ty = I.getOperand(0)->getType(); + + for (GetElementPtrInst::const_op_iterator OI = I.op_begin()+1, E = I.op_end(); + OI != E; ++OI) { + const Value *Idx = *OI; + if (const StructType *StTy = dyn_cast(Ty)) { + unsigned Field = cast(Idx)->getZExtValue(); + if (Field) { + // N = N + Offset + uint64_t Offset = TD->getStructLayout(StTy)->getElementOffset(Field); + N = DAG.getNode(ISD::ADD, getCurDebugLoc(), N.getValueType(), N, + DAG.getIntPtrConstant(Offset)); + } + + Ty = StTy->getElementType(Field); + } else if (const UnionType *UnTy = dyn_cast(Ty)) { + unsigned Field = cast(Idx)->getZExtValue(); + + // Offset canonically 0 for unions, but type changes + Ty = UnTy->getElementType(Field); + } else { + Ty = cast(Ty)->getElementType(); + + // If this is a constant subscript, handle it quickly. + if (const ConstantInt *CI = dyn_cast(Idx)) { + if (CI->getZExtValue() == 0) continue; + uint64_t Offs = + TD->getTypeAllocSize(Ty)*cast(CI)->getSExtValue(); + SDValue OffsVal; + EVT PTy = TLI.getPointerTy(); + unsigned PtrBits = PTy.getSizeInBits(); + if (PtrBits < 64) + OffsVal = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), + TLI.getPointerTy(), + DAG.getConstant(Offs, MVT::i64)); + else + OffsVal = DAG.getIntPtrConstant(Offs); + + N = DAG.getNode(ISD::ADD, getCurDebugLoc(), N.getValueType(), N, + OffsVal); + continue; + } + + // N = N + Idx * ElementSize; + APInt ElementSize = APInt(TLI.getPointerTy().getSizeInBits(), + TD->getTypeAllocSize(Ty)); + SDValue IdxN = getValue(Idx); + + // If the index is smaller or larger than intptr_t, truncate or extend + // it. + IdxN = DAG.getSExtOrTrunc(IdxN, getCurDebugLoc(), N.getValueType()); + + // If this is a multiply by a power of two, turn it into a shl + // immediately. This is a very common case. + if (ElementSize != 1) { + if (ElementSize.isPowerOf2()) { + unsigned Amt = ElementSize.logBase2(); + IdxN = DAG.getNode(ISD::SHL, getCurDebugLoc(), + N.getValueType(), IdxN, + DAG.getConstant(Amt, TLI.getPointerTy())); + } else { + SDValue Scale = DAG.getConstant(ElementSize, TLI.getPointerTy()); + IdxN = DAG.getNode(ISD::MUL, getCurDebugLoc(), + N.getValueType(), IdxN, Scale); + } + } + + N = DAG.getNode(ISD::ADD, getCurDebugLoc(), + N.getValueType(), N, IdxN); + } + } + + setValue(&I, N); +} + +void SelectionDAGBuilder::visitAlloca(const AllocaInst &I) { + // If this is a fixed sized alloca in the entry block of the function, + // allocate it statically on the stack. + if (FuncInfo.StaticAllocaMap.count(&I)) + return; // getValue will auto-populate this. + + const Type *Ty = I.getAllocatedType(); + uint64_t TySize = TLI.getTargetData()->getTypeAllocSize(Ty); + unsigned Align = + std::max((unsigned)TLI.getTargetData()->getPrefTypeAlignment(Ty), + I.getAlignment()); + + SDValue AllocSize = getValue(I.getArraySize()); + + EVT IntPtr = TLI.getPointerTy(); + if (AllocSize.getValueType() != IntPtr) + AllocSize = DAG.getZExtOrTrunc(AllocSize, getCurDebugLoc(), IntPtr); + + AllocSize = DAG.getNode(ISD::MUL, getCurDebugLoc(), IntPtr, + AllocSize, + DAG.getConstant(TySize, IntPtr)); + + // Handle alignment. If the requested alignment is less than or equal to + // the stack alignment, ignore it. If the size is greater than or equal to + // the stack alignment, we note this in the DYNAMIC_STACKALLOC node. + unsigned StackAlign = TM.getFrameInfo()->getStackAlignment(); + if (Align <= StackAlign) + Align = 0; + + // Round the size of the allocation up to the stack alignment size + // by add SA-1 to the size. + AllocSize = DAG.getNode(ISD::ADD, getCurDebugLoc(), + AllocSize.getValueType(), AllocSize, + DAG.getIntPtrConstant(StackAlign-1)); + + // Mask out the low bits for alignment purposes. + AllocSize = DAG.getNode(ISD::AND, getCurDebugLoc(), + AllocSize.getValueType(), AllocSize, + DAG.getIntPtrConstant(~(uint64_t)(StackAlign-1))); + + SDValue Ops[] = { getRoot(), AllocSize, DAG.getIntPtrConstant(Align) }; + SDVTList VTs = DAG.getVTList(AllocSize.getValueType(), MVT::Other); + SDValue DSA = DAG.getNode(ISD::DYNAMIC_STACKALLOC, getCurDebugLoc(), + VTs, Ops, 3); + setValue(&I, DSA); + DAG.setRoot(DSA.getValue(1)); + + // Inform the Frame Information that we have just allocated a variable-sized + // object. + FuncInfo.MF->getFrameInfo()->CreateVariableSizedObject(); +} + +void SelectionDAGBuilder::visitLoad(const LoadInst &I) { + const Value *SV = I.getOperand(0); + SDValue Ptr = getValue(SV); + + const Type *Ty = I.getType(); + + bool isVolatile = I.isVolatile(); + bool isNonTemporal = I.getMetadata("nontemporal") != 0; + unsigned Alignment = I.getAlignment(); + + SmallVector ValueVTs; + SmallVector Offsets; + ComputeValueVTs(TLI, Ty, ValueVTs, &Offsets); + unsigned NumValues = ValueVTs.size(); + if (NumValues == 0) + return; + + SDValue Root; + bool ConstantMemory = false; + if (I.isVolatile()) + // Serialize volatile loads with other side effects. + Root = getRoot(); + else if (AA->pointsToConstantMemory(SV)) { + // Do not serialize (non-volatile) loads of constant memory with anything. + Root = DAG.getEntryNode(); + ConstantMemory = true; + } else { + // Do not serialize non-volatile loads against each other. + Root = DAG.getRoot(); + } + + SmallVector Values(NumValues); + SmallVector Chains(NumValues); + EVT PtrVT = Ptr.getValueType(); + for (unsigned i = 0; i != NumValues; ++i) { + SDValue A = DAG.getNode(ISD::ADD, getCurDebugLoc(), + PtrVT, Ptr, + DAG.getConstant(Offsets[i], PtrVT)); + SDValue L = DAG.getLoad(ValueVTs[i], getCurDebugLoc(), Root, + A, SV, Offsets[i], isVolatile, + isNonTemporal, Alignment); + + Values[i] = L; + Chains[i] = L.getValue(1); + } + + if (!ConstantMemory) { + SDValue Chain = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(), + MVT::Other, &Chains[0], NumValues); + if (isVolatile) + DAG.setRoot(Chain); + else + PendingLoads.push_back(Chain); + } + + setValue(&I, DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(), + DAG.getVTList(&ValueVTs[0], NumValues), + &Values[0], NumValues)); +} + +void SelectionDAGBuilder::visitStore(const StoreInst &I) { + const Value *SrcV = I.getOperand(0); + const Value *PtrV = I.getOperand(1); + + SmallVector ValueVTs; + SmallVector Offsets; + ComputeValueVTs(TLI, SrcV->getType(), ValueVTs, &Offsets); + unsigned NumValues = ValueVTs.size(); + if (NumValues == 0) + return; + + // Get the lowered operands. Note that we do this after + // checking if NumResults is zero, because with zero results + // the operands won't have values in the map. + SDValue Src = getValue(SrcV); + SDValue Ptr = getValue(PtrV); + + SDValue Root = getRoot(); + SmallVector Chains(NumValues); + EVT PtrVT = Ptr.getValueType(); + bool isVolatile = I.isVolatile(); + bool isNonTemporal = I.getMetadata("nontemporal") != 0; + unsigned Alignment = I.getAlignment(); + + for (unsigned i = 0; i != NumValues; ++i) { + SDValue Add = DAG.getNode(ISD::ADD, getCurDebugLoc(), PtrVT, Ptr, + DAG.getConstant(Offsets[i], PtrVT)); + Chains[i] = DAG.getStore(Root, getCurDebugLoc(), + SDValue(Src.getNode(), Src.getResNo() + i), + Add, PtrV, Offsets[i], isVolatile, + isNonTemporal, Alignment); + } + + DAG.setRoot(DAG.getNode(ISD::TokenFactor, getCurDebugLoc(), + MVT::Other, &Chains[0], NumValues)); +} + +/// visitTargetIntrinsic - Lower a call of a target intrinsic to an INTRINSIC +/// node. +void SelectionDAGBuilder::visitTargetIntrinsic(const CallInst &I, + unsigned Intrinsic) { + bool HasChain = !I.doesNotAccessMemory(); + bool OnlyLoad = HasChain && I.onlyReadsMemory(); + + // Build the operand list. + SmallVector Ops; + if (HasChain) { // If this intrinsic has side-effects, chainify it. + if (OnlyLoad) { + // We don't need to serialize loads against other loads. + Ops.push_back(DAG.getRoot()); + } else { + Ops.push_back(getRoot()); + } + } + + // Info is set by getTgtMemInstrinsic + TargetLowering::IntrinsicInfo Info; + bool IsTgtIntrinsic = TLI.getTgtMemIntrinsic(Info, I, Intrinsic); + + // Add the intrinsic ID as an integer operand if it's not a target intrinsic. + if (!IsTgtIntrinsic) + Ops.push_back(DAG.getConstant(Intrinsic, TLI.getPointerTy())); + + // Add all operands of the call to the operand list. + for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) { + SDValue Op = getValue(I.getOperand(i)); + assert(TLI.isTypeLegal(Op.getValueType()) && + "Intrinsic uses a non-legal type?"); + Ops.push_back(Op); + } + + SmallVector ValueVTs; + ComputeValueVTs(TLI, I.getType(), ValueVTs); +#ifndef NDEBUG + for (unsigned Val = 0, E = ValueVTs.size(); Val != E; ++Val) { + assert(TLI.isTypeLegal(ValueVTs[Val]) && + "Intrinsic uses a non-legal type?"); + } +#endif // NDEBUG + + if (HasChain) + ValueVTs.push_back(MVT::Other); + + SDVTList VTs = DAG.getVTList(ValueVTs.data(), ValueVTs.size()); + + // Create the node. + SDValue Result; + if (IsTgtIntrinsic) { + // This is target intrinsic that touches memory + Result = DAG.getMemIntrinsicNode(Info.opc, getCurDebugLoc(), + VTs, &Ops[0], Ops.size(), + Info.memVT, Info.ptrVal, Info.offset, + Info.align, Info.vol, + Info.readMem, Info.writeMem); + } else if (!HasChain) { + Result = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, getCurDebugLoc(), + VTs, &Ops[0], Ops.size()); + } else if (!I.getType()->isVoidTy()) { + Result = DAG.getNode(ISD::INTRINSIC_W_CHAIN, getCurDebugLoc(), + VTs, &Ops[0], Ops.size()); + } else { + Result = DAG.getNode(ISD::INTRINSIC_VOID, getCurDebugLoc(), + VTs, &Ops[0], Ops.size()); + } + + if (HasChain) { + SDValue Chain = Result.getValue(Result.getNode()->getNumValues()-1); + if (OnlyLoad) + PendingLoads.push_back(Chain); + else + DAG.setRoot(Chain); + } + + if (!I.getType()->isVoidTy()) { + if (const VectorType *PTy = dyn_cast(I.getType())) { + EVT VT = TLI.getValueType(PTy); + Result = DAG.getNode(ISD::BIT_CONVERT, getCurDebugLoc(), VT, Result); + } + + setValue(&I, Result); + } +} + +/// GetSignificand - Get the significand and build it into a floating-point +/// number with exponent of 1: +/// +/// Op = (Op & 0x007fffff) | 0x3f800000; +/// +/// where Op is the hexidecimal representation of floating point value. +static SDValue +GetSignificand(SelectionDAG &DAG, SDValue Op, DebugLoc dl) { + SDValue t1 = DAG.getNode(ISD::AND, dl, MVT::i32, Op, + DAG.getConstant(0x007fffff, MVT::i32)); + SDValue t2 = DAG.getNode(ISD::OR, dl, MVT::i32, t1, + DAG.getConstant(0x3f800000, MVT::i32)); + return DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, t2); +} + +/// GetExponent - Get the exponent: +/// +/// (float)(int)(((Op & 0x7f800000) >> 23) - 127); +/// +/// where Op is the hexidecimal representation of floating point value. +static SDValue +GetExponent(SelectionDAG &DAG, SDValue Op, const TargetLowering &TLI, + DebugLoc dl) { + SDValue t0 = DAG.getNode(ISD::AND, dl, MVT::i32, Op, + DAG.getConstant(0x7f800000, MVT::i32)); + SDValue t1 = DAG.getNode(ISD::SRL, dl, MVT::i32, t0, + DAG.getConstant(23, TLI.getPointerTy())); + SDValue t2 = DAG.getNode(ISD::SUB, dl, MVT::i32, t1, + DAG.getConstant(127, MVT::i32)); + return DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, t2); +} + +/// getF32Constant - Get 32-bit floating point constant. +static SDValue +getF32Constant(SelectionDAG &DAG, unsigned Flt) { + return DAG.getConstantFP(APFloat(APInt(32, Flt)), MVT::f32); +} + +/// Inlined utility function to implement binary input atomic intrinsics for +/// visitIntrinsicCall: I is a call instruction +/// Op is the associated NodeType for I +const char * +SelectionDAGBuilder::implVisitBinaryAtomic(const CallInst& I, + ISD::NodeType Op) { + SDValue Root = getRoot(); + SDValue L = + DAG.getAtomic(Op, getCurDebugLoc(), + getValue(I.getOperand(2)).getValueType().getSimpleVT(), + Root, + getValue(I.getOperand(1)), + getValue(I.getOperand(2)), + I.getOperand(1)); + setValue(&I, L); + DAG.setRoot(L.getValue(1)); + return 0; +} + +// implVisitAluOverflow - Lower arithmetic overflow instrinsics. +const char * +SelectionDAGBuilder::implVisitAluOverflow(const CallInst &I, ISD::NodeType Op) { + SDValue Op1 = getValue(I.getOperand(1)); + SDValue Op2 = getValue(I.getOperand(2)); + + SDVTList VTs = DAG.getVTList(Op1.getValueType(), MVT::i1); + setValue(&I, DAG.getNode(Op, getCurDebugLoc(), VTs, Op1, Op2)); + return 0; +} + +/// visitExp - Lower an exp intrinsic. Handles the special sequences for +/// limited-precision mode. +void +SelectionDAGBuilder::visitExp(const CallInst &I) { + SDValue result; + DebugLoc dl = getCurDebugLoc(); + + if (getValue(I.getOperand(1)).getValueType() == MVT::f32 && + LimitFloatPrecision > 0 && LimitFloatPrecision <= 18) { SDValue Op = getValue(I.getOperand(1)); // Put the exponent in the right bit position for later addition to the @@ -4320,642 +4480,432 @@ case Intrinsic::atomic_load_umax: return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_UMAX); case Intrinsic::atomic_swap: - return implVisitBinaryAtomic(I, ISD::ATOMIC_SWAP); - - case Intrinsic::invariant_start: - case Intrinsic::lifetime_start: - // Discard region information. - setValue(&I, DAG.getUNDEF(TLI.getPointerTy())); - return 0; - case Intrinsic::invariant_end: - case Intrinsic::lifetime_end: - // Discard region information. - return 0; - } -} - -void SelectionDAGBuilder::LowerCallTo(ImmutableCallSite CS, SDValue Callee, - bool isTailCall, - MachineBasicBlock *LandingPad) { - const PointerType *PT = cast(CS.getCalledValue()->getType()); - const FunctionType *FTy = cast(PT->getElementType()); - const Type *RetTy = FTy->getReturnType(); - MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI(); - MCSymbol *BeginLabel = 0; - - TargetLowering::ArgListTy Args; - TargetLowering::ArgListEntry Entry; - Args.reserve(CS.arg_size()); - - // Check whether the function can return without sret-demotion. - SmallVector OutVTs; - SmallVector OutsFlags; - SmallVector Offsets; - getReturnInfo(RetTy, CS.getAttributes().getRetAttributes(), - OutVTs, OutsFlags, TLI, &Offsets); - - bool CanLowerReturn = TLI.CanLowerReturn(CS.getCallingConv(), - FTy->isVarArg(), OutVTs, OutsFlags, DAG); - - SDValue DemoteStackSlot; - - if (!CanLowerReturn) { - uint64_t TySize = TLI.getTargetData()->getTypeAllocSize( - FTy->getReturnType()); - unsigned Align = TLI.getTargetData()->getPrefTypeAlignment( - FTy->getReturnType()); - MachineFunction &MF = DAG.getMachineFunction(); - int SSFI = MF.getFrameInfo()->CreateStackObject(TySize, Align, false); - const Type *StackSlotPtrType = PointerType::getUnqual(FTy->getReturnType()); - - DemoteStackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy()); - Entry.Node = DemoteStackSlot; - Entry.Ty = StackSlotPtrType; - Entry.isSExt = false; - Entry.isZExt = false; - Entry.isInReg = false; - Entry.isSRet = true; - Entry.isNest = false; - Entry.isByVal = false; - Entry.Alignment = Align; - Args.push_back(Entry); - RetTy = Type::getVoidTy(FTy->getContext()); - } - - for (ImmutableCallSite::arg_iterator i = CS.arg_begin(), e = CS.arg_end(); - i != e; ++i) { - SDValue ArgNode = getValue(*i); - Entry.Node = ArgNode; Entry.Ty = (*i)->getType(); - - unsigned attrInd = i - CS.arg_begin() + 1; - Entry.isSExt = CS.paramHasAttr(attrInd, Attribute::SExt); - Entry.isZExt = CS.paramHasAttr(attrInd, Attribute::ZExt); - Entry.isInReg = CS.paramHasAttr(attrInd, Attribute::InReg); - Entry.isSRet = CS.paramHasAttr(attrInd, Attribute::StructRet); - Entry.isNest = CS.paramHasAttr(attrInd, Attribute::Nest); - Entry.isByVal = CS.paramHasAttr(attrInd, Attribute::ByVal); - Entry.Alignment = CS.getParamAlignment(attrInd); - Args.push_back(Entry); - } - - if (LandingPad) { - // Insert a label before the invoke call to mark the try range. This can be - // used to detect deletion of the invoke via the MachineModuleInfo. - BeginLabel = MMI.getContext().CreateTempSymbol(); - - // For SjLj, keep track of which landing pads go with which invokes - // so as to maintain the ordering of pads in the LSDA. - unsigned CallSiteIndex = MMI.getCurrentCallSite(); - if (CallSiteIndex) { - MMI.setCallSiteBeginLabel(BeginLabel, CallSiteIndex); - // Now that the call site is handled, stop tracking it. - MMI.setCurrentCallSite(0); - } - - // Both PendingLoads and PendingExports must be flushed here; - // this call might not return. - (void)getRoot(); - DAG.setRoot(DAG.getEHLabel(getCurDebugLoc(), getControlRoot(), BeginLabel)); - } - - // Check if target-independent constraints permit a tail call here. - // Target-dependent constraints are checked within TLI.LowerCallTo. - if (isTailCall && - !isInTailCallPosition(CS, CS.getAttributes().getRetAttributes(), TLI)) - isTailCall = false; - - std::pair Result = - TLI.LowerCallTo(getRoot(), RetTy, - CS.paramHasAttr(0, Attribute::SExt), - CS.paramHasAttr(0, Attribute::ZExt), FTy->isVarArg(), - CS.paramHasAttr(0, Attribute::InReg), FTy->getNumParams(), - CS.getCallingConv(), - isTailCall, - !CS.getInstruction()->use_empty(), - Callee, Args, DAG, getCurDebugLoc()); - assert((isTailCall || Result.second.getNode()) && - "Non-null chain expected with non-tail call!"); - assert((Result.second.getNode() || !Result.first.getNode()) && - "Null value expected with tail call!"); - if (Result.first.getNode()) { - setValue(CS.getInstruction(), Result.first); - } else if (!CanLowerReturn && Result.second.getNode()) { - // The instruction result is the result of loading from the - // hidden sret parameter. - SmallVector PVTs; - const Type *PtrRetTy = PointerType::getUnqual(FTy->getReturnType()); - - ComputeValueVTs(TLI, PtrRetTy, PVTs); - assert(PVTs.size() == 1 && "Pointers should fit in one register"); - EVT PtrVT = PVTs[0]; - unsigned NumValues = OutVTs.size(); - SmallVector Values(NumValues); - SmallVector Chains(NumValues); - - for (unsigned i = 0; i < NumValues; ++i) { - SDValue Add = DAG.getNode(ISD::ADD, getCurDebugLoc(), PtrVT, - DemoteStackSlot, - DAG.getConstant(Offsets[i], PtrVT)); - SDValue L = DAG.getLoad(OutVTs[i], getCurDebugLoc(), Result.second, - Add, NULL, Offsets[i], false, false, 1); - Values[i] = L; - Chains[i] = L.getValue(1); - } - - SDValue Chain = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(), - MVT::Other, &Chains[0], NumValues); - PendingLoads.push_back(Chain); - - // Collect the legal value parts into potentially illegal values - // that correspond to the original function's return values. - SmallVector RetTys; - RetTy = FTy->getReturnType(); - ComputeValueVTs(TLI, RetTy, RetTys); - ISD::NodeType AssertOp = ISD::DELETED_NODE; - SmallVector ReturnValues; - unsigned CurReg = 0; - for (unsigned I = 0, E = RetTys.size(); I != E; ++I) { - EVT VT = RetTys[I]; - EVT RegisterVT = TLI.getRegisterType(RetTy->getContext(), VT); - unsigned NumRegs = TLI.getNumRegisters(RetTy->getContext(), VT); - - SDValue ReturnValue = - getCopyFromParts(DAG, getCurDebugLoc(), &Values[CurReg], NumRegs, - RegisterVT, VT, AssertOp); - ReturnValues.push_back(ReturnValue); - CurReg += NumRegs; - } - - setValue(CS.getInstruction(), - DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(), - DAG.getVTList(&RetTys[0], RetTys.size()), - &ReturnValues[0], ReturnValues.size())); - - } - - // As a special case, a null chain means that a tail call has been emitted and - // the DAG root is already updated. - if (Result.second.getNode()) - DAG.setRoot(Result.second); - else - HasTailCall = true; - - if (LandingPad) { - // Insert a label at the end of the invoke call to mark the try range. This - // can be used to detect deletion of the invoke via the MachineModuleInfo. - MCSymbol *EndLabel = MMI.getContext().CreateTempSymbol(); - DAG.setRoot(DAG.getEHLabel(getCurDebugLoc(), getRoot(), EndLabel)); - - // Inform MachineModuleInfo of range. - MMI.addInvoke(LandingPad, BeginLabel, EndLabel); - } -} - -/// IsOnlyUsedInZeroEqualityComparison - Return true if it only matters that the -/// value is equal or not-equal to zero. -static bool IsOnlyUsedInZeroEqualityComparison(const Value *V) { - for (Value::const_use_iterator UI = V->use_begin(), E = V->use_end(); - UI != E; ++UI) { - if (const ICmpInst *IC = dyn_cast(*UI)) - if (IC->isEquality()) - if (const Constant *C = dyn_cast(IC->getOperand(1))) - if (C->isNullValue()) - continue; - // Unknown instruction. - return false; - } - return true; -} - -static SDValue getMemCmpLoad(const Value *PtrVal, MVT LoadVT, - const Type *LoadTy, - SelectionDAGBuilder &Builder) { - - // Check to see if this load can be trivially constant folded, e.g. if the - // input is from a string literal. - if (const Constant *LoadInput = dyn_cast(PtrVal)) { - // Cast pointer to the type we really want to load. - LoadInput = ConstantExpr::getBitCast(const_cast(LoadInput), - PointerType::getUnqual(LoadTy)); - - if (const Constant *LoadCst = - ConstantFoldLoadFromConstPtr(const_cast(LoadInput), - Builder.TD)) - return Builder.getValue(LoadCst); - } - - // Otherwise, we have to emit the load. If the pointer is to unfoldable but - // still constant memory, the input chain can be the entry node. - SDValue Root; - bool ConstantMemory = false; + return implVisitBinaryAtomic(I, ISD::ATOMIC_SWAP); - // Do not serialize (non-volatile) loads of constant memory with anything. - if (Builder.AA->pointsToConstantMemory(PtrVal)) { - Root = Builder.DAG.getEntryNode(); - ConstantMemory = true; - } else { - // Do not serialize non-volatile loads against each other. - Root = Builder.DAG.getRoot(); + case Intrinsic::invariant_start: + case Intrinsic::lifetime_start: + // Discard region information. + setValue(&I, DAG.getUNDEF(TLI.getPointerTy())); + return 0; + case Intrinsic::invariant_end: + case Intrinsic::lifetime_end: + // Discard region information. + return 0; } - - SDValue Ptr = Builder.getValue(PtrVal); - SDValue LoadVal = Builder.DAG.getLoad(LoadVT, Builder.getCurDebugLoc(), Root, - Ptr, PtrVal /*SrcValue*/, 0/*SVOffset*/, - false /*volatile*/, - false /*nontemporal*/, 1 /* align=1 */); - - if (!ConstantMemory) - Builder.PendingLoads.push_back(LoadVal.getValue(1)); - return LoadVal; } +void SelectionDAGBuilder::LowerCallTo(ImmutableCallSite CS, SDValue Callee, + bool isTailCall, + MachineBasicBlock *LandingPad) { + const PointerType *PT = cast(CS.getCalledValue()->getType()); + const FunctionType *FTy = cast(PT->getElementType()); + const Type *RetTy = FTy->getReturnType(); + MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI(); + MCSymbol *BeginLabel = 0; -/// visitMemCmpCall - See if we can lower a call to memcmp in an optimized form. -/// If so, return true and lower it, otherwise return false and it will be -/// lowered like a normal call. -bool SelectionDAGBuilder::visitMemCmpCall(const CallInst &I) { - // Verify that the prototype makes sense. int memcmp(void*,void*,size_t) - if (I.getNumOperands() != 4) - return false; + TargetLowering::ArgListTy Args; + TargetLowering::ArgListEntry Entry; + Args.reserve(CS.arg_size()); - const Value *LHS = I.getOperand(1), *RHS = I.getOperand(2); - if (!LHS->getType()->isPointerTy() || !RHS->getType()->isPointerTy() || - !I.getOperand(3)->getType()->isIntegerTy() || - !I.getType()->isIntegerTy()) - return false; + // Check whether the function can return without sret-demotion. + SmallVector OutVTs; + SmallVector OutsFlags; + SmallVector Offsets; + getReturnInfo(RetTy, CS.getAttributes().getRetAttributes(), + OutVTs, OutsFlags, TLI, &Offsets); - const ConstantInt *Size = dyn_cast(I.getOperand(3)); + bool CanLowerReturn = TLI.CanLowerReturn(CS.getCallingConv(), + FTy->isVarArg(), OutVTs, OutsFlags, DAG); - // memcmp(S1,S2,2) != 0 -> (*(short*)LHS != *(short*)RHS) != 0 - // memcmp(S1,S2,4) != 0 -> (*(int*)LHS != *(int*)RHS) != 0 - if (Size && IsOnlyUsedInZeroEqualityComparison(&I)) { - bool ActuallyDoIt = true; - MVT LoadVT; - const Type *LoadTy; - switch (Size->getZExtValue()) { - default: - LoadVT = MVT::Other; - LoadTy = 0; - ActuallyDoIt = false; - break; - case 2: - LoadVT = MVT::i16; - LoadTy = Type::getInt16Ty(Size->getContext()); - break; - case 4: - LoadVT = MVT::i32; - LoadTy = Type::getInt32Ty(Size->getContext()); - break; - case 8: - LoadVT = MVT::i64; - LoadTy = Type::getInt64Ty(Size->getContext()); - break; - /* - case 16: - LoadVT = MVT::v4i32; - LoadTy = Type::getInt32Ty(Size->getContext()); - LoadTy = VectorType::get(LoadTy, 4); - break; - */ - } + SDValue DemoteStackSlot; - // This turns into unaligned loads. We only do this if the target natively - // supports the MVT we'll be loading or if it is small enough (<= 4) that - // we'll only produce a small number of byte loads. + if (!CanLowerReturn) { + uint64_t TySize = TLI.getTargetData()->getTypeAllocSize( + FTy->getReturnType()); + unsigned Align = TLI.getTargetData()->getPrefTypeAlignment( + FTy->getReturnType()); + MachineFunction &MF = DAG.getMachineFunction(); + int SSFI = MF.getFrameInfo()->CreateStackObject(TySize, Align, false); + const Type *StackSlotPtrType = PointerType::getUnqual(FTy->getReturnType()); - // Require that we can find a legal MVT, and only do this if the target - // supports unaligned loads of that type. Expanding into byte loads would - // bloat the code. - if (ActuallyDoIt && Size->getZExtValue() > 4) { - // TODO: Handle 5 byte compare as 4-byte + 1 byte. - // TODO: Handle 8 byte compare on x86-32 as two 32-bit loads. - if (!TLI.isTypeLegal(LoadVT) ||!TLI.allowsUnalignedMemoryAccesses(LoadVT)) - ActuallyDoIt = false; - } + DemoteStackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy()); + Entry.Node = DemoteStackSlot; + Entry.Ty = StackSlotPtrType; + Entry.isSExt = false; + Entry.isZExt = false; + Entry.isInReg = false; + Entry.isSRet = true; + Entry.isNest = false; + Entry.isByVal = false; + Entry.Alignment = Align; + Args.push_back(Entry); + RetTy = Type::getVoidTy(FTy->getContext()); + } - if (ActuallyDoIt) { - SDValue LHSVal = getMemCmpLoad(LHS, LoadVT, LoadTy, *this); - SDValue RHSVal = getMemCmpLoad(RHS, LoadVT, LoadTy, *this); + for (ImmutableCallSite::arg_iterator i = CS.arg_begin(), e = CS.arg_end(); + i != e; ++i) { + SDValue ArgNode = getValue(*i); + Entry.Node = ArgNode; Entry.Ty = (*i)->getType(); - SDValue Res = DAG.getSetCC(getCurDebugLoc(), MVT::i1, LHSVal, RHSVal, - ISD::SETNE); - EVT CallVT = TLI.getValueType(I.getType(), true); - setValue(&I, DAG.getZExtOrTrunc(Res, getCurDebugLoc(), CallVT)); - return true; - } + unsigned attrInd = i - CS.arg_begin() + 1; + Entry.isSExt = CS.paramHasAttr(attrInd, Attribute::SExt); + Entry.isZExt = CS.paramHasAttr(attrInd, Attribute::ZExt); + Entry.isInReg = CS.paramHasAttr(attrInd, Attribute::InReg); + Entry.isSRet = CS.paramHasAttr(attrInd, Attribute::StructRet); + Entry.isNest = CS.paramHasAttr(attrInd, Attribute::Nest); + Entry.isByVal = CS.paramHasAttr(attrInd, Attribute::ByVal); + Entry.Alignment = CS.getParamAlignment(attrInd); + Args.push_back(Entry); } + if (LandingPad) { + // Insert a label before the invoke call to mark the try range. This can be + // used to detect deletion of the invoke via the MachineModuleInfo. + BeginLabel = MMI.getContext().CreateTempSymbol(); - return false; -} + // For SjLj, keep track of which landing pads go with which invokes + // so as to maintain the ordering of pads in the LSDA. + unsigned CallSiteIndex = MMI.getCurrentCallSite(); + if (CallSiteIndex) { + MMI.setCallSiteBeginLabel(BeginLabel, CallSiteIndex); + // Now that the call site is handled, stop tracking it. + MMI.setCurrentCallSite(0); + } + // Both PendingLoads and PendingExports must be flushed here; + // this call might not return. + (void)getRoot(); + DAG.setRoot(DAG.getEHLabel(getCurDebugLoc(), getControlRoot(), BeginLabel)); + } -void SelectionDAGBuilder::visitCall(const CallInst &I) { - const char *RenameFn = 0; - if (Function *F = I.getCalledFunction()) { - if (F->isDeclaration()) { - const TargetIntrinsicInfo *II = TM.getIntrinsicInfo(); - if (II) { - if (unsigned IID = II->getIntrinsicID(F)) { - RenameFn = visitIntrinsicCall(I, IID); - if (!RenameFn) - return; - } - } - if (unsigned IID = F->getIntrinsicID()) { - RenameFn = visitIntrinsicCall(I, IID); - if (!RenameFn) - return; - } - } + // Check if target-independent constraints permit a tail call here. + // Target-dependent constraints are checked within TLI.LowerCallTo. + if (isTailCall && + !isInTailCallPosition(CS, CS.getAttributes().getRetAttributes(), TLI)) + isTailCall = false; - // Check for well-known libc/libm calls. If the function is internal, it - // can't be a library call. - if (!F->hasLocalLinkage() && F->hasName()) { - StringRef Name = F->getName(); - if (Name == "copysign" || Name == "copysignf" || Name == "copysignl") { - if (I.getNumOperands() == 3 && // Basic sanity checks. - I.getOperand(1)->getType()->isFloatingPointTy() && - I.getType() == I.getOperand(1)->getType() && - I.getType() == I.getOperand(2)->getType()) { - SDValue LHS = getValue(I.getOperand(1)); - SDValue RHS = getValue(I.getOperand(2)); - setValue(&I, DAG.getNode(ISD::FCOPYSIGN, getCurDebugLoc(), - LHS.getValueType(), LHS, RHS)); - return; - } - } else if (Name == "fabs" || Name == "fabsf" || Name == "fabsl") { - if (I.getNumOperands() == 2 && // Basic sanity checks. - I.getOperand(1)->getType()->isFloatingPointTy() && - I.getType() == I.getOperand(1)->getType()) { - SDValue Tmp = getValue(I.getOperand(1)); - setValue(&I, DAG.getNode(ISD::FABS, getCurDebugLoc(), - Tmp.getValueType(), Tmp)); - return; - } - } else if (Name == "sin" || Name == "sinf" || Name == "sinl") { - if (I.getNumOperands() == 2 && // Basic sanity checks. - I.getOperand(1)->getType()->isFloatingPointTy() && - I.getType() == I.getOperand(1)->getType() && - I.onlyReadsMemory()) { - SDValue Tmp = getValue(I.getOperand(1)); - setValue(&I, DAG.getNode(ISD::FSIN, getCurDebugLoc(), - Tmp.getValueType(), Tmp)); - return; - } - } else if (Name == "cos" || Name == "cosf" || Name == "cosl") { - if (I.getNumOperands() == 2 && // Basic sanity checks. - I.getOperand(1)->getType()->isFloatingPointTy() && - I.getType() == I.getOperand(1)->getType() && - I.onlyReadsMemory()) { - SDValue Tmp = getValue(I.getOperand(1)); - setValue(&I, DAG.getNode(ISD::FCOS, getCurDebugLoc(), - Tmp.getValueType(), Tmp)); - return; - } - } else if (Name == "sqrt" || Name == "sqrtf" || Name == "sqrtl") { - if (I.getNumOperands() == 2 && // Basic sanity checks. - I.getOperand(1)->getType()->isFloatingPointTy() && - I.getType() == I.getOperand(1)->getType() && - I.onlyReadsMemory()) { - SDValue Tmp = getValue(I.getOperand(1)); - setValue(&I, DAG.getNode(ISD::FSQRT, getCurDebugLoc(), - Tmp.getValueType(), Tmp)); - return; - } - } else if (Name == "memcmp") { - if (visitMemCmpCall(I)) - return; - } + std::pair Result = + TLI.LowerCallTo(getRoot(), RetTy, + CS.paramHasAttr(0, Attribute::SExt), + CS.paramHasAttr(0, Attribute::ZExt), FTy->isVarArg(), + CS.paramHasAttr(0, Attribute::InReg), FTy->getNumParams(), + CS.getCallingConv(), + isTailCall, + !CS.getInstruction()->use_empty(), + Callee, Args, DAG, getCurDebugLoc()); + assert((isTailCall || Result.second.getNode()) && + "Non-null chain expected with non-tail call!"); + assert((Result.second.getNode() || !Result.first.getNode()) && + "Null value expected with tail call!"); + if (Result.first.getNode()) { + setValue(CS.getInstruction(), Result.first); + } else if (!CanLowerReturn && Result.second.getNode()) { + // The instruction result is the result of loading from the + // hidden sret parameter. + SmallVector PVTs; + const Type *PtrRetTy = PointerType::getUnqual(FTy->getReturnType()); + + ComputeValueVTs(TLI, PtrRetTy, PVTs); + assert(PVTs.size() == 1 && "Pointers should fit in one register"); + EVT PtrVT = PVTs[0]; + unsigned NumValues = OutVTs.size(); + SmallVector Values(NumValues); + SmallVector Chains(NumValues); + + for (unsigned i = 0; i < NumValues; ++i) { + SDValue Add = DAG.getNode(ISD::ADD, getCurDebugLoc(), PtrVT, + DemoteStackSlot, + DAG.getConstant(Offsets[i], PtrVT)); + SDValue L = DAG.getLoad(OutVTs[i], getCurDebugLoc(), Result.second, + Add, NULL, Offsets[i], false, false, 1); + Values[i] = L; + Chains[i] = L.getValue(1); } - } else if (isa(I.getOperand(0))) { - visitInlineAsm(&I); - return; - } - SDValue Callee; - if (!RenameFn) - Callee = getValue(I.getOperand(0)); - else - Callee = DAG.getExternalSymbol(RenameFn, TLI.getPointerTy()); + SDValue Chain = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(), + MVT::Other, &Chains[0], NumValues); + PendingLoads.push_back(Chain); + + // Collect the legal value parts into potentially illegal values + // that correspond to the original function's return values. + SmallVector RetTys; + RetTy = FTy->getReturnType(); + ComputeValueVTs(TLI, RetTy, RetTys); + ISD::NodeType AssertOp = ISD::DELETED_NODE; + SmallVector ReturnValues; + unsigned CurReg = 0; + for (unsigned I = 0, E = RetTys.size(); I != E; ++I) { + EVT VT = RetTys[I]; + EVT RegisterVT = TLI.getRegisterType(RetTy->getContext(), VT); + unsigned NumRegs = TLI.getNumRegisters(RetTy->getContext(), VT); + + SDValue ReturnValue = + getCopyFromParts(DAG, getCurDebugLoc(), &Values[CurReg], NumRegs, + RegisterVT, VT, AssertOp); + ReturnValues.push_back(ReturnValue); + CurReg += NumRegs; + } - // Check if we can potentially perform a tail call. More detailed checking is - // be done within LowerCallTo, after more information about the call is known. - LowerCallTo(&I, Callee, I.isTailCall()); -} + setValue(CS.getInstruction(), + DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(), + DAG.getVTList(&RetTys[0], RetTys.size()), + &ReturnValues[0], ReturnValues.size())); -/// getCopyFromRegs - Emit a series of CopyFromReg nodes that copies from -/// this value and returns the result as a ValueVT value. This uses -/// Chain/Flag as the input and updates them for the output Chain/Flag. -/// If the Flag pointer is NULL, no flag is used. -SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG, - FunctionLoweringInfo &FuncInfo, - DebugLoc dl, - SDValue &Chain, SDValue *Flag) const { - const TargetLowering &TLI = DAG.getTargetLoweringInfo(); + } - // Assemble the legal parts into the final values. - SmallVector Values(ValueVTs.size()); - SmallVector Parts; - for (unsigned Value = 0, Part = 0, e = ValueVTs.size(); Value != e; ++Value) { - // Copy the legal parts from the registers. - EVT ValueVT = ValueVTs[Value]; - unsigned NumRegs = TLI.getNumRegisters(*DAG.getContext(), ValueVT); - EVT RegisterVT = RegVTs[Value]; + // As a special case, a null chain means that a tail call has been emitted and + // the DAG root is already updated. + if (Result.second.getNode()) + DAG.setRoot(Result.second); + else + HasTailCall = true; - Parts.resize(NumRegs); - for (unsigned i = 0; i != NumRegs; ++i) { - SDValue P; - if (Flag == 0) { - P = DAG.getCopyFromReg(Chain, dl, Regs[Part+i], RegisterVT); - } else { - P = DAG.getCopyFromReg(Chain, dl, Regs[Part+i], RegisterVT, *Flag); - *Flag = P.getValue(2); - } + if (LandingPad) { + // Insert a label at the end of the invoke call to mark the try range. This + // can be used to detect deletion of the invoke via the MachineModuleInfo. + MCSymbol *EndLabel = MMI.getContext().CreateTempSymbol(); + DAG.setRoot(DAG.getEHLabel(getCurDebugLoc(), getRoot(), EndLabel)); - Chain = P.getValue(1); + // Inform MachineModuleInfo of range. + MMI.addInvoke(LandingPad, BeginLabel, EndLabel); + } +} - // If the source register was virtual and if we know something about it, - // add an assert node. - if (TargetRegisterInfo::isVirtualRegister(Regs[Part+i]) && - RegisterVT.isInteger() && !RegisterVT.isVector()) { - unsigned SlotNo = Regs[Part+i]-TargetRegisterInfo::FirstVirtualRegister; - if (FuncInfo.LiveOutRegInfo.size() > SlotNo) { - const FunctionLoweringInfo::LiveOutInfo &LOI = - FuncInfo.LiveOutRegInfo[SlotNo]; +/// IsOnlyUsedInZeroEqualityComparison - Return true if it only matters that the +/// value is equal or not-equal to zero. +static bool IsOnlyUsedInZeroEqualityComparison(const Value *V) { + for (Value::const_use_iterator UI = V->use_begin(), E = V->use_end(); + UI != E; ++UI) { + if (const ICmpInst *IC = dyn_cast(*UI)) + if (IC->isEquality()) + if (const Constant *C = dyn_cast(IC->getOperand(1))) + if (C->isNullValue()) + continue; + // Unknown instruction. + return false; + } + return true; +} - unsigned RegSize = RegisterVT.getSizeInBits(); - unsigned NumSignBits = LOI.NumSignBits; - unsigned NumZeroBits = LOI.KnownZero.countLeadingOnes(); +static SDValue getMemCmpLoad(const Value *PtrVal, MVT LoadVT, + const Type *LoadTy, + SelectionDAGBuilder &Builder) { - // FIXME: We capture more information than the dag can represent. For - // now, just use the tightest assertzext/assertsext possible. - bool isSExt = true; - EVT FromVT(MVT::Other); - if (NumSignBits == RegSize) - isSExt = true, FromVT = MVT::i1; // ASSERT SEXT 1 - else if (NumZeroBits >= RegSize-1) - isSExt = false, FromVT = MVT::i1; // ASSERT ZEXT 1 - else if (NumSignBits > RegSize-8) - isSExt = true, FromVT = MVT::i8; // ASSERT SEXT 8 - else if (NumZeroBits >= RegSize-8) - isSExt = false, FromVT = MVT::i8; // ASSERT ZEXT 8 - else if (NumSignBits > RegSize-16) - isSExt = true, FromVT = MVT::i16; // ASSERT SEXT 16 - else if (NumZeroBits >= RegSize-16) - isSExt = false, FromVT = MVT::i16; // ASSERT ZEXT 16 - else if (NumSignBits > RegSize-32) - isSExt = true, FromVT = MVT::i32; // ASSERT SEXT 32 - else if (NumZeroBits >= RegSize-32) - isSExt = false, FromVT = MVT::i32; // ASSERT ZEXT 32 + // Check to see if this load can be trivially constant folded, e.g. if the + // input is from a string literal. + if (const Constant *LoadInput = dyn_cast(PtrVal)) { + // Cast pointer to the type we really want to load. + LoadInput = ConstantExpr::getBitCast(const_cast(LoadInput), + PointerType::getUnqual(LoadTy)); - if (FromVT != MVT::Other) - P = DAG.getNode(isSExt ? ISD::AssertSext : ISD::AssertZext, dl, - RegisterVT, P, DAG.getValueType(FromVT)); - } - } + if (const Constant *LoadCst = + ConstantFoldLoadFromConstPtr(const_cast(LoadInput), + Builder.TD)) + return Builder.getValue(LoadCst); + } - Parts[i] = P; - } + // Otherwise, we have to emit the load. If the pointer is to unfoldable but + // still constant memory, the input chain can be the entry node. + SDValue Root; + bool ConstantMemory = false; - Values[Value] = getCopyFromParts(DAG, dl, Parts.begin(), - NumRegs, RegisterVT, ValueVT); - Part += NumRegs; - Parts.clear(); + // Do not serialize (non-volatile) loads of constant memory with anything. + if (Builder.AA->pointsToConstantMemory(PtrVal)) { + Root = Builder.DAG.getEntryNode(); + ConstantMemory = true; + } else { + // Do not serialize non-volatile loads against each other. + Root = Builder.DAG.getRoot(); } - return DAG.getNode(ISD::MERGE_VALUES, dl, - DAG.getVTList(&ValueVTs[0], ValueVTs.size()), - &Values[0], ValueVTs.size()); + SDValue Ptr = Builder.getValue(PtrVal); + SDValue LoadVal = Builder.DAG.getLoad(LoadVT, Builder.getCurDebugLoc(), Root, + Ptr, PtrVal /*SrcValue*/, 0/*SVOffset*/, + false /*volatile*/, + false /*nontemporal*/, 1 /* align=1 */); + + if (!ConstantMemory) + Builder.PendingLoads.push_back(LoadVal.getValue(1)); + return LoadVal; } -/// getCopyToRegs - Emit a series of CopyToReg nodes that copies the -/// specified value into the registers specified by this object. This uses -/// Chain/Flag as the input and updates them for the output Chain/Flag. -/// If the Flag pointer is NULL, no flag is used. -void RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG, DebugLoc dl, - SDValue &Chain, SDValue *Flag) const { - const TargetLowering &TLI = DAG.getTargetLoweringInfo(); - // Get the list of the values's legal parts. - unsigned NumRegs = Regs.size(); - SmallVector Parts(NumRegs); - for (unsigned Value = 0, Part = 0, e = ValueVTs.size(); Value != e; ++Value) { - EVT ValueVT = ValueVTs[Value]; - unsigned NumParts = TLI.getNumRegisters(*DAG.getContext(), ValueVT); - EVT RegisterVT = RegVTs[Value]; +/// visitMemCmpCall - See if we can lower a call to memcmp in an optimized form. +/// If so, return true and lower it, otherwise return false and it will be +/// lowered like a normal call. +bool SelectionDAGBuilder::visitMemCmpCall(const CallInst &I) { + // Verify that the prototype makes sense. int memcmp(void*,void*,size_t) + if (I.getNumOperands() != 4) + return false; - getCopyToParts(DAG, dl, - Val.getValue(Val.getResNo() + Value), - &Parts[Part], NumParts, RegisterVT); - Part += NumParts; - } + const Value *LHS = I.getOperand(1), *RHS = I.getOperand(2); + if (!LHS->getType()->isPointerTy() || !RHS->getType()->isPointerTy() || + !I.getOperand(3)->getType()->isIntegerTy() || + !I.getType()->isIntegerTy()) + return false; - // Copy the parts into the registers. - SmallVector Chains(NumRegs); - for (unsigned i = 0; i != NumRegs; ++i) { - SDValue Part; - if (Flag == 0) { - Part = DAG.getCopyToReg(Chain, dl, Regs[i], Parts[i]); - } else { - Part = DAG.getCopyToReg(Chain, dl, Regs[i], Parts[i], *Flag); - *Flag = Part.getValue(1); + const ConstantInt *Size = dyn_cast(I.getOperand(3)); + + // memcmp(S1,S2,2) != 0 -> (*(short*)LHS != *(short*)RHS) != 0 + // memcmp(S1,S2,4) != 0 -> (*(int*)LHS != *(int*)RHS) != 0 + if (Size && IsOnlyUsedInZeroEqualityComparison(&I)) { + bool ActuallyDoIt = true; + MVT LoadVT; + const Type *LoadTy; + switch (Size->getZExtValue()) { + default: + LoadVT = MVT::Other; + LoadTy = 0; + ActuallyDoIt = false; + break; + case 2: + LoadVT = MVT::i16; + LoadTy = Type::getInt16Ty(Size->getContext()); + break; + case 4: + LoadVT = MVT::i32; + LoadTy = Type::getInt32Ty(Size->getContext()); + break; + case 8: + LoadVT = MVT::i64; + LoadTy = Type::getInt64Ty(Size->getContext()); + break; + /* + case 16: + LoadVT = MVT::v4i32; + LoadTy = Type::getInt32Ty(Size->getContext()); + LoadTy = VectorType::get(LoadTy, 4); + break; + */ } - Chains[i] = Part.getValue(0); - } - - if (NumRegs == 1 || Flag) - // If NumRegs > 1 && Flag is used then the use of the last CopyToReg is - // flagged to it. That is the CopyToReg nodes and the user are considered - // a single scheduling unit. If we create a TokenFactor and return it as - // chain, then the TokenFactor is both a predecessor (operand) of the - // user as well as a successor (the TF operands are flagged to the user). - // c1, f1 = CopyToReg - // c2, f2 = CopyToReg - // c3 = TokenFactor c1, c2 - // ... - // = op c3, ..., f2 - Chain = Chains[NumRegs-1]; - else - Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Chains[0], NumRegs); -} + // This turns into unaligned loads. We only do this if the target natively + // supports the MVT we'll be loading or if it is small enough (<= 4) that + // we'll only produce a small number of byte loads. -/// AddInlineAsmOperands - Add this value to the specified inlineasm node -/// operand list. This adds the code marker and includes the number of -/// values added into it. -void RegsForValue::AddInlineAsmOperands(unsigned Code, bool HasMatching, - unsigned MatchingIdx, - SelectionDAG &DAG, - std::vector &Ops) const { - const TargetLowering &TLI = DAG.getTargetLoweringInfo(); + // Require that we can find a legal MVT, and only do this if the target + // supports unaligned loads of that type. Expanding into byte loads would + // bloat the code. + if (ActuallyDoIt && Size->getZExtValue() > 4) { + // TODO: Handle 5 byte compare as 4-byte + 1 byte. + // TODO: Handle 8 byte compare on x86-32 as two 32-bit loads. + if (!TLI.isTypeLegal(LoadVT) ||!TLI.allowsUnalignedMemoryAccesses(LoadVT)) + ActuallyDoIt = false; + } - unsigned Flag = InlineAsm::getFlagWord(Code, Regs.size()); - if (HasMatching) - Flag = InlineAsm::getFlagWordForMatchingOp(Flag, MatchingIdx); - SDValue Res = DAG.getTargetConstant(Flag, MVT::i32); - Ops.push_back(Res); + if (ActuallyDoIt) { + SDValue LHSVal = getMemCmpLoad(LHS, LoadVT, LoadTy, *this); + SDValue RHSVal = getMemCmpLoad(RHS, LoadVT, LoadTy, *this); - for (unsigned Value = 0, Reg = 0, e = ValueVTs.size(); Value != e; ++Value) { - unsigned NumRegs = TLI.getNumRegisters(*DAG.getContext(), ValueVTs[Value]); - EVT RegisterVT = RegVTs[Value]; - for (unsigned i = 0; i != NumRegs; ++i) { - assert(Reg < Regs.size() && "Mismatch in # registers expected"); - Ops.push_back(DAG.getRegister(Regs[Reg++], RegisterVT)); + SDValue Res = DAG.getSetCC(getCurDebugLoc(), MVT::i1, LHSVal, RHSVal, + ISD::SETNE); + EVT CallVT = TLI.getValueType(I.getType(), true); + setValue(&I, DAG.getZExtOrTrunc(Res, getCurDebugLoc(), CallVT)); + return true; } } + + + return false; } -/// isAllocatableRegister - If the specified register is safe to allocate, -/// i.e. it isn't a stack pointer or some other special register, return the -/// register class for the register. Otherwise, return null. -static const TargetRegisterClass * -isAllocatableRegister(unsigned Reg, MachineFunction &MF, - const TargetLowering &TLI, - const TargetRegisterInfo *TRI) { - EVT FoundVT = MVT::Other; - const TargetRegisterClass *FoundRC = 0; - for (TargetRegisterInfo::regclass_iterator RCI = TRI->regclass_begin(), - E = TRI->regclass_end(); RCI != E; ++RCI) { - EVT ThisVT = MVT::Other; - const TargetRegisterClass *RC = *RCI; - // If none of the value types for this register class are valid, we - // can't use it. For example, 64-bit reg classes on 32-bit targets. - for (TargetRegisterClass::vt_iterator I = RC->vt_begin(), E = RC->vt_end(); - I != E; ++I) { - if (TLI.isTypeLegal(*I)) { - // If we have already found this register in a different register class, - // choose the one with the largest VT specified. For example, on - // PowerPC, we favor f64 register classes over f32. - if (FoundVT == MVT::Other || FoundVT.bitsLT(*I)) { - ThisVT = *I; - break; +void SelectionDAGBuilder::visitCall(const CallInst &I) { + const char *RenameFn = 0; + if (Function *F = I.getCalledFunction()) { + if (F->isDeclaration()) { + const TargetIntrinsicInfo *II = TM.getIntrinsicInfo(); + if (II) { + if (unsigned IID = II->getIntrinsicID(F)) { + RenameFn = visitIntrinsicCall(I, IID); + if (!RenameFn) + return; } } + if (unsigned IID = F->getIntrinsicID()) { + RenameFn = visitIntrinsicCall(I, IID); + if (!RenameFn) + return; + } } - if (ThisVT == MVT::Other) continue; - - // NOTE: This isn't ideal. In particular, this might allocate the - // frame pointer in functions that need it (due to them not being taken - // out of allocation, because a variable sized allocation hasn't been seen - // yet). This is a slight code pessimization, but should still work. - for (TargetRegisterClass::iterator I = RC->allocation_order_begin(MF), - E = RC->allocation_order_end(MF); I != E; ++I) - if (*I == Reg) { - // We found a matching register class. Keep looking at others in case - // we find one with larger registers that this physreg is also in. - FoundRC = RC; - FoundVT = ThisVT; - break; + // Check for well-known libc/libm calls. If the function is internal, it + // can't be a library call. + if (!F->hasLocalLinkage() && F->hasName()) { + StringRef Name = F->getName(); + if (Name == "copysign" || Name == "copysignf" || Name == "copysignl") { + if (I.getNumOperands() == 3 && // Basic sanity checks. + I.getOperand(1)->getType()->isFloatingPointTy() && + I.getType() == I.getOperand(1)->getType() && + I.getType() == I.getOperand(2)->getType()) { + SDValue LHS = getValue(I.getOperand(1)); + SDValue RHS = getValue(I.getOperand(2)); + setValue(&I, DAG.getNode(ISD::FCOPYSIGN, getCurDebugLoc(), + LHS.getValueType(), LHS, RHS)); + return; + } + } else if (Name == "fabs" || Name == "fabsf" || Name == "fabsl") { + if (I.getNumOperands() == 2 && // Basic sanity checks. + I.getOperand(1)->getType()->isFloatingPointTy() && + I.getType() == I.getOperand(1)->getType()) { + SDValue Tmp = getValue(I.getOperand(1)); + setValue(&I, DAG.getNode(ISD::FABS, getCurDebugLoc(), + Tmp.getValueType(), Tmp)); + return; + } + } else if (Name == "sin" || Name == "sinf" || Name == "sinl") { + if (I.getNumOperands() == 2 && // Basic sanity checks. + I.getOperand(1)->getType()->isFloatingPointTy() && + I.getType() == I.getOperand(1)->getType() && + I.onlyReadsMemory()) { + SDValue Tmp = getValue(I.getOperand(1)); + setValue(&I, DAG.getNode(ISD::FSIN, getCurDebugLoc(), + Tmp.getValueType(), Tmp)); + return; + } + } else if (Name == "cos" || Name == "cosf" || Name == "cosl") { + if (I.getNumOperands() == 2 && // Basic sanity checks. + I.getOperand(1)->getType()->isFloatingPointTy() && + I.getType() == I.getOperand(1)->getType() && + I.onlyReadsMemory()) { + SDValue Tmp = getValue(I.getOperand(1)); + setValue(&I, DAG.getNode(ISD::FCOS, getCurDebugLoc(), + Tmp.getValueType(), Tmp)); + return; + } + } else if (Name == "sqrt" || Name == "sqrtf" || Name == "sqrtl") { + if (I.getNumOperands() == 2 && // Basic sanity checks. + I.getOperand(1)->getType()->isFloatingPointTy() && + I.getType() == I.getOperand(1)->getType() && + I.onlyReadsMemory()) { + SDValue Tmp = getValue(I.getOperand(1)); + setValue(&I, DAG.getNode(ISD::FSQRT, getCurDebugLoc(), + Tmp.getValueType(), Tmp)); + return; + } + } else if (Name == "memcmp") { + if (visitMemCmpCall(I)) + return; } + } + } else if (isa(I.getOperand(0))) { + visitInlineAsm(&I); + return; } - return FoundRC; -} + SDValue Callee; + if (!RenameFn) + Callee = getValue(I.getOperand(0)); + else + Callee = DAG.getExternalSymbol(RenameFn, TLI.getPointerTy()); + + // Check if we can potentially perform a tail call. More detailed checking is + // be done within LowerCallTo, after more information about the call is known. + LowerCallTo(&I, Callee, I.isTailCall()); +} namespace llvm { + /// AsmOperandInfo - This contains information for each constraint that we are /// lowering. class LLVM_LIBRARY_VISIBILITY SDISelAsmOperandInfo : @@ -5044,8 +4994,56 @@ Regs.insert(*Aliases); } }; + } // end llvm namespace. +/// isAllocatableRegister - If the specified register is safe to allocate, +/// i.e. it isn't a stack pointer or some other special register, return the +/// register class for the register. Otherwise, return null. +static const TargetRegisterClass * +isAllocatableRegister(unsigned Reg, MachineFunction &MF, + const TargetLowering &TLI, + const TargetRegisterInfo *TRI) { + EVT FoundVT = MVT::Other; + const TargetRegisterClass *FoundRC = 0; + for (TargetRegisterInfo::regclass_iterator RCI = TRI->regclass_begin(), + E = TRI->regclass_end(); RCI != E; ++RCI) { + EVT ThisVT = MVT::Other; + + const TargetRegisterClass *RC = *RCI; + // If none of the value types for this register class are valid, we + // can't use it. For example, 64-bit reg classes on 32-bit targets. + for (TargetRegisterClass::vt_iterator I = RC->vt_begin(), E = RC->vt_end(); + I != E; ++I) { + if (TLI.isTypeLegal(*I)) { + // If we have already found this register in a different register class, + // choose the one with the largest VT specified. For example, on + // PowerPC, we favor f64 register classes over f32. + if (FoundVT == MVT::Other || FoundVT.bitsLT(*I)) { + ThisVT = *I; + break; + } + } + } + + if (ThisVT == MVT::Other) continue; + + // NOTE: This isn't ideal. In particular, this might allocate the + // frame pointer in functions that need it (due to them not being taken + // out of allocation, because a variable sized allocation hasn't been seen + // yet). This is a slight code pessimization, but should still work. + for (TargetRegisterClass::iterator I = RC->allocation_order_begin(MF), + E = RC->allocation_order_end(MF); I != E; ++I) + if (*I == Reg) { + // We found a matching register class. Keep looking at others in case + // we find one with larger registers that this physreg is also in. + FoundRC = RC; + FoundVT = ThisVT; + break; + } + } + return FoundRC; +} /// GetRegistersForValue - Assign registers (virtual or physical) for the /// specified operand. We prefer to assign virtual registers, to allow the From asl at math.spbu.ru Sat May 29 14:25:17 2010 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Sat, 29 May 2010 19:25:17 -0000 Subject: [llvm-commits] [llvm] r105106 - /llvm/trunk/lib/Target/ARM/ARMScheduleA9.td Message-ID: <20100529192517.DC729312800A@llvm.org> Author: asl Date: Sat May 29 14:25:17 2010 New Revision: 105106 URL: http://llvm.org/viewvc/llvm-project?rev=105106&view=rev Log: Add some integer instruction itineraries for A9 Modified: llvm/trunk/lib/Target/ARM/ARMScheduleA9.td Modified: llvm/trunk/lib/Target/ARM/ARMScheduleA9.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMScheduleA9.td?rev=105106&r1=105105&r2=105106&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMScheduleA9.td (original) +++ llvm/trunk/lib/Target/ARM/ARMScheduleA9.td Sat May 29 14:25:17 2010 @@ -28,6 +28,61 @@ // def CortexA9Itineraries : ProcessorItineraries< [A9_NPipe, A9_DRegsN, A9_DRegsVFP, A9_LSPipe, A9_Pipe0, A9_Pipe1, A9_Issue], [ + // Two fully-pipelined integer ALU pipelines + // FIXME: There are no operand latencies for these instructions at all! + // + // Move instructions, unconditional + InstrItinData], [1]>, + InstrItinData], [1, 1]>, + InstrItinData], [1, 1]>, + InstrItinData], [2, 2, 1]>, + // + // No operand cycles + InstrItinData]>, + // + // Binary Instructions that produce a result + InstrItinData], [2, 2]>, + InstrItinData], [2, 2, 2]>, + InstrItinData], [2, 2, 1]>, + InstrItinData], [2, 2, 1, 1]>, + // + // Unary Instructions that produce a result + InstrItinData], [2, 2]>, + InstrItinData], [2, 1]>, + InstrItinData], [2, 1, 1]>, + // + // Compare instructions + InstrItinData], [2]>, + InstrItinData], [2, 2]>, + InstrItinData], [2, 1]>, + InstrItinData], [2, 1, 1]>, + // + // Move instructions, conditional + InstrItinData], [2]>, + InstrItinData], [2, 1]>, + InstrItinData], [2, 1]>, + InstrItinData], [2, 1, 1]>, + + // Integer multiply pipeline + // + InstrItinData, + InstrStage<2, [A9_Pipe0]>], [4, 1, 1]>, + InstrItinData, + InstrStage<2, [A9_Pipe0]>], [4, 1, 1, 2]>, + InstrItinData, + InstrStage<2, [A9_Pipe0]>], [4, 1, 1]>, + InstrItinData, + InstrStage<2, [A9_Pipe0]>], [4, 1, 1, 2]>, + InstrItinData, + InstrStage<3, [A9_Pipe0]>], [4, 5, 1, 1]>, + InstrItinData, + InstrStage<3, [A9_Pipe0]>], [4, 5, 1, 1]>, + + // Branch + // + // no delay slots, so the latency of a branch is unimportant + InstrItinData]>, + // VFP and NEON shares the same register file. This means that every VFP // instruction should wait for full completion of the consecutive NEON // instruction and vice-versa. We model this behavior with two artificial FUs: From asl at math.spbu.ru Sat May 29 14:25:29 2010 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Sat, 29 May 2010 19:25:29 -0000 Subject: [llvm-commits] [llvm] r105107 - /llvm/trunk/lib/Target/ARM/ARMScheduleA9.td Message-ID: <20100529192529.673CB312800A@llvm.org> Author: asl Date: Sat May 29 14:25:29 2010 New Revision: 105107 URL: http://llvm.org/viewvc/llvm-project?rev=105107&view=rev Log: NEON/VFP stuff can be issued only via Pipe1 on A9 Modified: llvm/trunk/lib/Target/ARM/ARMScheduleA9.td Modified: llvm/trunk/lib/Target/ARM/ARMScheduleA9.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMScheduleA9.td?rev=105107&r1=105106&r2=105107&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMScheduleA9.td (original) +++ llvm/trunk/lib/Target/ARM/ARMScheduleA9.td Sat May 29 14:25:29 2010 @@ -103,21 +103,21 @@ // FP Special Register to Integer Register File Move InstrItinData, InstrStage<2, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>]>, // // Single-precision FP Unary InstrItinData, // Extra latency cycles since wbck is 2 cycles InstrStage<3, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [1, 1]>, // // Double-precision FP Unary InstrItinData, // Extra latency cycles since wbck is 2 cycles InstrStage<3, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [1, 1]>, // @@ -125,124 +125,124 @@ InstrItinData, // Extra latency cycles since wbck is 4 cycles InstrStage<5, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [1, 1]>, // // Double-precision FP Compare InstrItinData, // Extra latency cycles since wbck is 4 cycles InstrStage<5, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [1, 1]>, // // Single to Double FP Convert InstrItinData, InstrStage<5, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [4, 1]>, // // Double to Single FP Convert InstrItinData, InstrStage<5, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [4, 1]>, // // Single to Half FP Convert InstrItinData, InstrStage<5, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [4, 1]>, // // Half to Single FP Convert InstrItinData, InstrStage<3, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [2, 1]>, // // Single-Precision FP to Integer Convert InstrItinData, InstrStage<5, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [4, 1]>, // // Double-Precision FP to Integer Convert InstrItinData, InstrStage<5, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [4, 1]>, // // Integer to Single-Precision FP Convert InstrItinData, InstrStage<5, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [4, 1]>, // // Integer to Double-Precision FP Convert InstrItinData, InstrStage<5, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [4, 1]>, // // Single-precision FP ALU InstrItinData, InstrStage<5, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [4, 1, 1]>, // // Double-precision FP ALU InstrItinData, InstrStage<5, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [4, 1, 1]>, // // Single-precision FP Multiply InstrItinData, InstrStage<6, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [5, 1, 1]>, // // Double-precision FP Multiply InstrItinData, InstrStage<7, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<2, [A9_NPipe]>], [6, 1, 1]>, // // Single-precision FP MAC InstrItinData, InstrStage<9, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [8, 0, 1, 1]>, // // Double-precision FP MAC InstrItinData, InstrStage<10, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<2, [A9_NPipe]>], [9, 0, 1, 1]>, // // Single-precision FP DIV InstrItinData, InstrStage<16, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<10, [A9_NPipe]>], [15, 1, 1]>, // // Double-precision FP DIV InstrItinData, InstrStage<26, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<20, [A9_NPipe]>], [25, 1, 1]>, // // Single-precision FP SQRT InstrItinData, InstrStage<18, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, - InstrStage<13, [A9_NPipe]>], [17, 1]>, + InstrStage<1, [A9_Pipe1]>, + InstrStage<13, [A9_NPipe]>], [17, 1]>, // // Double-precision FP SQRT InstrItinData, InstrStage<33, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<28, [A9_NPipe]>], [32, 1]>, // @@ -250,26 +250,26 @@ InstrItinData, // Extra 1 latency cycle since wbck is 2 cycles InstrStage<3, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [1, 1]>, // // Integer to Double-precision Move InstrItinData, // Extra 1 latency cycle since wbck is 2 cycles InstrStage<3, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [1, 1, 1]>, // // Single-precision to Integer Move InstrItinData, InstrStage<2, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [1, 1]>, // // Double-precision to Integer Move InstrItinData, InstrStage<2, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [1, 1, 1]>, // // Single-precision FP Load @@ -382,112 +382,112 @@ InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [4, 2]>, // // Quad-register Integer Unary InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [4, 2]>, // // Double-register Integer Q-Unary InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [4, 1]>, // // Quad-register Integer CountQ-Unary InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [4, 1]>, // // Double-register Integer Binary InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [3, 2, 2]>, // // Quad-register Integer Binary InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [3, 2, 2]>, // // Double-register Integer Subtract InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [3, 2, 1]>, // // Quad-register Integer Subtract InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [3, 2, 1]>, // // Double-register Integer Shift InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [3, 1, 1]>, // // Quad-register Integer Shift InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [3, 1, 1]>, // // Double-register Integer Shift (4 cycle) InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [4, 1, 1]>, // // Quad-register Integer Shift (4 cycle) InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [4, 1, 1]>, // // Double-register Integer Binary (4 cycle) InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [4, 2, 2]>, // // Quad-register Integer Binary (4 cycle) InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [4, 2, 2]>, // // Double-register Integer Subtract (4 cycle) InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [4, 2, 1]>, // // Quad-register Integer Subtract (4 cycle) InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [4, 2, 1]>, // @@ -495,7 +495,7 @@ InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [3, 2, 2]>, // // Quad-register Integer Count @@ -504,35 +504,35 @@ InstrItinData, // Extra latency cycles since wbck is 7 cycles InstrStage<8, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<2, [A9_NPipe]>], [4, 2, 2]>, // // Double-register Absolute Difference and Accumulate InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [6, 3, 2, 1]>, // // Quad-register Absolute Difference and Accumulate InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<2, [A9_NPipe]>], [6, 3, 2, 1]>, // // Double-register Integer Pair Add Long InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [6, 3, 1]>, // // Quad-register Integer Pair Add Long InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<2, [A9_NPipe]>], [6, 3, 1]>, // @@ -540,14 +540,14 @@ InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [6, 2, 2]>, // // Quad-register Integer Multiply (.8, .16) InstrItinData, // Extra latency cycles since wbck is 7 cycles InstrStage<8, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<2, [A9_NPipe]>], [7, 2, 2]>, // @@ -555,56 +555,56 @@ InstrItinData, // Extra latency cycles since wbck is 7 cycles InstrStage<8, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<2, [A9_NPipe]>], [7, 2, 1]>, // // Quad-register Integer Multiply (.32) InstrItinData, // Extra latency cycles since wbck is 9 cycles InstrStage<10, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<4, [A9_NPipe]>], [9, 2, 1]>, // // Double-register Integer Multiply-Accumulate (.8, .16) InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [6, 3, 2, 2]>, // // Double-register Integer Multiply-Accumulate (.32) InstrItinData, // Extra latency cycles since wbck is 7 cycles InstrStage<8, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<2, [A9_NPipe]>], [7, 3, 2, 1]>, // // Quad-register Integer Multiply-Accumulate (.8, .16) InstrItinData, // Extra latency cycles since wbck is 7 cycles InstrStage<8, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<2, [A9_NPipe]>], [7, 3, 2, 2]>, // // Quad-register Integer Multiply-Accumulate (.32) InstrItinData, // Extra latency cycles since wbck is 9 cycles InstrStage<10, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<4, [A9_NPipe]>], [9, 3, 2, 1]>, // // Move Immediate InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [3]>, // // Double-register Permute Move InstrItinData, // FIXME: all latencies are arbitrary, no information is available InstrStage<3, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_LSPipe]>], [2, 1]>, // // Quad-register Permute Move @@ -613,42 +613,42 @@ InstrItinData, // FIXME: all latencies are arbitrary, no information is available InstrStage<4, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<2, [A9_NPipe]>], [3, 1]>, // // Integer to Single-precision Move InstrItinData, // FIXME: all latencies are arbitrary, no information is available InstrStage<3, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [2, 1]>, // // Integer to Double-precision Move InstrItinData, // FIXME: all latencies are arbitrary, no information is available InstrStage<3, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [2, 1, 1]>, // // Single-precision to Integer Move InstrItinData, // FIXME: all latencies are arbitrary, no information is available InstrStage<3, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [2, 1]>, // // Double-precision to Integer Move InstrItinData, // FIXME: all latencies are arbitrary, no information is available InstrStage<3, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [2, 2, 1]>, // // Integer to Lane Move InstrItinData, // FIXME: all latencies are arbitrary, no information is available InstrStage<4, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<2, [A9_NPipe]>], [3, 1, 1]>, // @@ -656,7 +656,7 @@ InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [5, 2]>, // // Quad-register FP Unary @@ -665,7 +665,7 @@ InstrItinData, // Extra latency cycles since wbck is 7 cycles InstrStage<8, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<2, [A9_NPipe]>], [6, 2]>, // // Double-register FP Binary @@ -674,7 +674,7 @@ InstrItinData, // Extra latency cycles since wbck is 7 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [5, 2, 2]>, // // Quad-register FP Binary @@ -685,14 +685,14 @@ InstrItinData, // Extra latency cycles since wbck is 8 cycles InstrStage<8, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<2, [A9_NPipe]>], [6, 2, 2]>, // // Double-register FP Multiple-Accumulate InstrItinData, // Extra latency cycles since wbck is 7 cycles InstrStage<8, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<2, [A9_NPipe]>], [6, 3, 2, 1]>, // // Quad-register FP Multiple-Accumulate @@ -701,28 +701,28 @@ InstrItinData, // Extra latency cycles since wbck is 9 cycles InstrStage<10, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<4, [A9_NPipe]>], [8, 4, 2, 1]>, // // Double-register Reciprical Step InstrItinData, // Extra latency cycles since wbck is 7 cycles InstrStage<8, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<2, [A9_NPipe]>], [6, 2, 2]>, // // Quad-register Reciprical Step InstrItinData, // Extra latency cycles since wbck is 9 cycles InstrStage<10, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<4, [A9_NPipe]>], [8, 2, 2]>, // // Double-register Permute InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [2, 2, 1, 1]>, // // Quad-register Permute @@ -731,7 +731,7 @@ InstrItinData, // Extra latency cycles since wbck is 7 cycles InstrStage<8, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<2, [A9_NPipe]>], [3, 3, 1, 1]>, // // Quad-register Permute (3 cycle issue) @@ -740,7 +740,7 @@ InstrItinData, // Extra latency cycles since wbck is 8 cycles InstrStage<9, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<3, [A9_LSPipe]>], [4, 4, 1, 1]>, // @@ -748,57 +748,57 @@ InstrItinData, // Extra latency cycles since wbck is 7 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<1, [A9_NPipe]>], [2, 1, 1]>, // // Quad-register VEXT InstrItinData, // Extra latency cycles since wbck is 9 cycles InstrStage<8, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<2, [A9_NPipe]>], [3, 1, 1]>, // // VTB InstrItinData, // Extra latency cycles since wbck is 7 cycles InstrStage<8, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<2, [A9_NPipe]>], [3, 2, 1]>, InstrItinData, // Extra latency cycles since wbck is 7 cycles InstrStage<8, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<2, [A9_NPipe]>], [3, 2, 2, 1]>, InstrItinData, // Extra latency cycles since wbck is 8 cycles InstrStage<9, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<3, [A9_NPipe]>], [4, 2, 2, 3, 1]>, InstrItinData, // Extra latency cycles since wbck is 8 cycles InstrStage<9, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<3, [A9_NPipe]>], [4, 2, 2, 3, 3, 1]>, // // VTBX InstrItinData, // Extra latency cycles since wbck is 7 cycles InstrStage<8, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<2, [A9_NPipe]>], [3, 1, 2, 1]>, InstrItinData, // Extra latency cycles since wbck is 7 cycles InstrStage<8, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<2, [A9_NPipe]>], [3, 1, 2, 2, 1]>, InstrItinData, // Extra latency cycles since wbck is 8 cycles InstrStage<9, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<3, [A9_NPipe]>], [4, 1, 2, 2, 3, 1]>, InstrItinData, // Extra latency cycles since wbck is 8 cycles InstrStage<9, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, + InstrStage<1, [A9_Pipe1]>, InstrStage<2, [A9_NPipe]>], [4, 1, 2, 2, 3, 3, 1]> ]>; From asl at math.spbu.ru Sat May 29 14:25:34 2010 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Sat, 29 May 2010 19:25:34 -0000 Subject: [llvm-commits] [llvm] r105108 - /llvm/trunk/lib/Target/ARM/ARMScheduleA9.td Message-ID: <20100529192534.74A343128018@llvm.org> Author: asl Date: Sat May 29 14:25:34 2010 New Revision: 105108 URL: http://llvm.org/viewvc/llvm-project?rev=105108&view=rev Log: Some rough approximations for load/stores on A9 Modified: llvm/trunk/lib/Target/ARM/ARMScheduleA9.td Modified: llvm/trunk/lib/Target/ARM/ARMScheduleA9.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMScheduleA9.td?rev=105108&r1=105107&r2=105108&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMScheduleA9.td (original) +++ llvm/trunk/lib/Target/ARM/ARMScheduleA9.td Sat May 29 14:25:34 2010 @@ -77,7 +77,66 @@ InstrStage<3, [A9_Pipe0]>], [4, 5, 1, 1]>, InstrItinData, InstrStage<3, [A9_Pipe0]>], [4, 5, 1, 1]>, - + // Integer load pipeline + // FIXME: The timings are some rough approximations + // + // Immediate offset + InstrItinData, + InstrStage<1, [A9_LSPipe]>], [3, 1]>, + // + // Register offset + InstrItinData, + InstrStage<1, [A9_LSPipe]>], [3, 1, 1]>, + // + // Scaled register offset + InstrItinData, + InstrStage<2, [A9_LSPipe]>], [4, 1, 1]>, + // + // Immediate offset with update + InstrItinData, + InstrStage<2, [A9_LSPipe]>], [3, 2, 1]>, + // + // Register offset with update + InstrItinData, + InstrStage<2, [A9_LSPipe]>], [3, 2, 1, 1]>, + // + // Scaled register offset with update + InstrItinData, + InstrStage<2, [A9_LSPipe]>], [4, 3, 1, 1]>, + // + // Load multiple + InstrItinData, + InstrStage<1, [A9_LSPipe]>]>, + + // Integer store pipeline + /// + // Immediate offset + InstrItinData, + InstrStage<1, [A9_LSPipe]>], [3, 1]>, + // + // Register offset + InstrItinData, + InstrStage<1, [A9_LSPipe]>], [3, 1, 1]>, + // + // Scaled register offset + InstrItinData, + InstrStage<2, [A9_LSPipe]>], [3, 1, 1]>, + // + // Immediate offset with update + InstrItinData, + InstrStage<1, [A9_LSPipe]>], [2, 3, 1]>, + // + // Register offset with update + InstrItinData, + InstrStage<1, [A9_LSPipe]>], [2, 3, 1, 1]>, + // + // Scaled register offset with update + InstrItinData, + InstrStage<2, [A9_LSPipe]>], [3, 3, 1, 1]>, + // + // Store multiple + InstrItinData, + InstrStage<1, [A9_LSPipe]>]>, // Branch // // no delay slots, so the latency of a branch is unimportant From asl at math.spbu.ru Sat May 29 14:25:40 2010 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Sat, 29 May 2010 19:25:40 -0000 Subject: [llvm-commits] [llvm] r105109 - /llvm/trunk/lib/Target/ARM/ARMScheduleA9.td Message-ID: <20100529192540.1378F312800A@llvm.org> Author: asl Date: Sat May 29 14:25:39 2010 New Revision: 105109 URL: http://llvm.org/viewvc/llvm-project?rev=105109&view=rev Log: Some A9 load/store cleanups Modified: llvm/trunk/lib/Target/ARM/ARMScheduleA9.td Modified: llvm/trunk/lib/Target/ARM/ARMScheduleA9.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMScheduleA9.td?rev=105109&r1=105108&r2=105109&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMScheduleA9.td (original) +++ llvm/trunk/lib/Target/ARM/ARMScheduleA9.td Sat May 29 14:25:39 2010 @@ -16,7 +16,6 @@ // Reference Manual". // // Functional units -def A9_Issue : FuncUnit; // issue def A9_Pipe0 : FuncUnit; // pipeline 0 def A9_Pipe1 : FuncUnit; // pipeline 1 def A9_LSPipe : FuncUnit; // LS pipe @@ -27,7 +26,7 @@ // Dual issue pipeline represented by A9_Pipe0 | A9_Pipe1 // def CortexA9Itineraries : ProcessorItineraries< - [A9_NPipe, A9_DRegsN, A9_DRegsVFP, A9_LSPipe, A9_Pipe0, A9_Pipe1, A9_Issue], [ + [A9_NPipe, A9_DRegsN, A9_DRegsVFP, A9_LSPipe, A9_Pipe0, A9_Pipe1], [ // Two fully-pipelined integer ALU pipelines // FIXME: There are no operand latencies for these instructions at all! // @@ -332,57 +331,45 @@ InstrStage<1, [A9_NPipe]>], [1, 1, 1]>, // // Single-precision FP Load - // use A9_Issue to enforce the 1 load/store per cycle limit InstrItinData, InstrStage<2, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Issue], 0>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, - InstrStage<1, [A9_LSPipe], 0>, + InstrStage<1, [A9_Pipe1], 0>, + InstrStage<1, [A9_LSPipe]>, InstrStage<1, [A9_NPipe]>]>, // // Double-precision FP Load - // use A9_Issue to enforce the 1 load/store per cycle limit InstrItinData, InstrStage<2, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Issue], 0>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, - InstrStage<1, [A9_LSPipe], 0>, + InstrStage<1, [A9_Pipe1], 0>, + InstrStage<1, [A9_LSPipe]>, InstrStage<1, [A9_NPipe]>]>, // // FP Load Multiple - // use A9_Issue to enforce the 1 load/store per cycle limit InstrItinData, InstrStage<2, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Issue], 0>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, - InstrStage<1, [A9_LSPipe], 0>, + InstrStage<1, [A9_Pipe1], 0>, + InstrStage<1, [A9_LSPipe]>, InstrStage<1, [A9_NPipe]>]>, // // Single-precision FP Store - // use A9_Issue to enforce the 1 load/store per cycle limit InstrItinData, InstrStage<2, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Issue], 0>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, - InstrStage<1, [A9_LSPipe], 0>, + InstrStage<1, [A9_Pipe1], 0>, + InstrStage<1, [A9_LSPipe]>, InstrStage<1, [A9_NPipe]>]>, // // Double-precision FP Store - // use A9_Issue to enforce the 1 load/store per cycle limit InstrItinData, InstrStage<2, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Issue], 0>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, - InstrStage<1, [A9_LSPipe], 0>, + InstrStage<1, [A9_Pipe1], 0>, + InstrStage<1, [A9_LSPipe]>, InstrStage<1, [A9_NPipe]>]>, // // FP Store Multiple - // use A9_Issue to enforce the 1 load/store per cycle limit InstrItinData, InstrStage<2, [A9_DRegsN], 0, Reserved>, - InstrStage<1, [A9_Issue], 0>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, - InstrStage<1, [A9_LSPipe], 0>, + InstrStage<1, [A9_Pipe1], 0>, + InstrStage<1, [A9_LSPipe]>, InstrStage<1, [A9_NPipe]>]>, // NEON // Issue through integer pipeline, and execute in NEON unit. @@ -392,9 +379,8 @@ // FIXME: We don't model this instruction properly InstrItinData, InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Issue], 0>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, - InstrStage<1, [A9_LSPipe], 0>, + InstrStage<1, [A9_Pipe1], 0>, + InstrStage<1, [A9_LSPipe]>, InstrStage<1, [A9_NPipe]>]>, // // VLD2 @@ -402,9 +388,8 @@ InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Issue], 0>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, - InstrStage<1, [A9_LSPipe], 0>, + InstrStage<1, [A9_Pipe1], 0>, + InstrStage<1, [A9_LSPipe]>, InstrStage<1, [A9_NPipe]>], [2, 2, 1]>, // // VLD3 @@ -412,9 +397,8 @@ InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Issue], 0>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, - InstrStage<1, [A9_LSPipe], 0>, + InstrStage<1, [A9_Pipe1], 0>, + InstrStage<1, [A9_LSPipe]>, InstrStage<1, [A9_NPipe]>], [2, 2, 2, 1]>, // // VLD4 @@ -422,9 +406,8 @@ InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Issue], 0>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, - InstrStage<1, [A9_LSPipe], 0>, + InstrStage<1, [A9_Pipe1], 0>, + InstrStage<1, [A9_LSPipe]>, InstrStage<1, [A9_NPipe]>], [2, 2, 2, 2, 1]>, // // VST @@ -432,9 +415,8 @@ InstrItinData, // Extra latency cycles since wbck is 6 cycles InstrStage<7, [A9_DRegsVFP], 0, Reserved>, - InstrStage<1, [A9_Issue], 0>, - InstrStage<1, [A9_Pipe0, A9_Pipe1]>, - InstrStage<1, [A9_LSPipe], 0>, + InstrStage<1, [A9_Pipe1], 0>, + InstrStage<1, [A9_LSPipe]>, InstrStage<1, [A9_NPipe]>]>, // // Double-register Integer Unary From daniel at zuster.org Sat May 29 19:48:15 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Sun, 30 May 2010 00:48:15 -0000 Subject: [llvm-commits] [test-suite] r105124 - in /test-suite/trunk: Makefile.programs MultiSource/Makefile.multisrc SingleSource/Makefile.singlesrc TEST.simple.Makefile TEST.simple.report Message-ID: <20100530004815.8B762312800A@llvm.org> Author: ddunbar Date: Sat May 29 19:48:15 2010 New Revision: 105124 URL: http://llvm.org/viewvc/llvm-project?rev=105124&view=rev Log: Add 'TEST=simple', which runs a nightly test that only uses the compiler under test to build files, and doesn't rely on 'llc', 'opt', etc... Added: test-suite/trunk/TEST.simple.Makefile test-suite/trunk/TEST.simple.report Modified: test-suite/trunk/Makefile.programs test-suite/trunk/MultiSource/Makefile.multisrc test-suite/trunk/SingleSource/Makefile.singlesrc Modified: test-suite/trunk/Makefile.programs URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.programs?rev=105124&r1=105123&r2=105124&view=diff ============================================================================== --- test-suite/trunk/Makefile.programs (original) +++ test-suite/trunk/Makefile.programs Sat May 29 19:48:15 2010 @@ -42,7 +42,7 @@ include $(LEVEL)/Makefile.tests -.PRECIOUS: Output/%.llvm Output/%.native Output/%.llc Output/%.llc.s +.PRECIOUS: Output/%.llvm Output/%.native Output/%.simple Output/%.llc Output/%.llc.s .PRECIOUS: Output/%.cbe Output/%.cbe.c Output/%.llvm.bc Output/%.linked.bc .PRECIOUS: Output/%.linked.optbeta.bc Output/%.llvm.optbeta.bc @@ -91,8 +91,10 @@ ifdef GET_STABLE_NUMBERS RUNSAFELY := $(PROGDIR)/RunSafelyAndStable.sh $(RUNTIMELIMIT) $(EXIT_OK) +RUNSAFELYLOCAL := $(PROGDIR)/RunSafelyAndStable.sh $(RUNTIMELIMIT) $(EXIT_OK) else RUNSAFELY := $(PROGDIR)/RunSafely.sh +RUNSAFELYLOCAL := $(PROGDIR)/RunSafely.sh ifdef REMOTE_HOST RUNSAFELY := $(RUNSAFELY) -r $(REMOTE_HOST) @@ -118,6 +120,7 @@ endif RUNSAFELY := $(RUNSAFELY) $(RUNTIMELIMIT) $(EXIT_OK) +RUNSAFELYLOCAL := $(RUNSAFELYLOCAL) $(RUNTIMELIMIT) $(EXIT_OK) endif RUNTOOLSAFELY := $(PROGDIR)/RunToolSafely.sh $(RUNTIMELIMIT) @@ -508,6 +511,10 @@ endif endif +$(PROGRAMS_TO_TEST:%=Output/%.out-simple): \ +Output/%.out-simple: Output/%.simple + $(RUNSAFELY) $(STDIN_FILENAME) $@ $< $(RUN_OPTIONS) + $(PROGRAMS_TO_TEST:%=Output/%.out-lli): \ Output/%.out-lli: Output/%.llvm.bc $(LLI) $(RUNSAFELY) $(STDIN_FILENAME) $@ $(LLI) -info-output-file=$(CURDIR)/$@.info $(STATS) $(LLI_OPTS) $< $(RUN_OPTIONS) @@ -669,6 +676,10 @@ DIFFPROG = touch $@ \# endif +$(PROGRAMS_TO_TEST:%=Output/%.diff-simple): \ +Output/%.diff-simple: Output/%.out-nat Output/%.out-simple + -$(DIFFPROG) simple $* $(HIDEDIFF) + $(PROGRAMS_TO_TEST:%=Output/%.diff-lli): \ Output/%.diff-lli: Output/%.out-nat Output/%.out-lli -$(DIFFPROG) lli $* $(HIDEDIFF) @@ -698,6 +709,11 @@ -$(DIFFPROG) cbe $* $(HIDEDIFF) ifndef DISABLE_DIFFS +$(PROGRAMS_TO_TEST:%=Output/%.exe-simple): \ +Output/%.exe-simple: Output/%.diff-simple + -rm -f $@ + -cp $< $@ + $(PROGRAMS_TO_TEST:%=Output/%.exe-lli): \ Output/%.exe-lli: Output/%.diff-lli -rm -f $@ Modified: test-suite/trunk/MultiSource/Makefile.multisrc URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Makefile.multisrc?rev=105124&r1=105123&r2=105124&view=diff ============================================================================== --- test-suite/trunk/MultiSource/Makefile.multisrc (original) +++ test-suite/trunk/MultiSource/Makefile.multisrc Sat May 29 19:48:15 2010 @@ -25,7 +25,10 @@ NObjs := $(sort $(addsuffix .o, $(notdir $(basename $(Source))))) NObjects := $(addprefix Output/,$(NObjs)) -.PRECIOUS: $(LObjects) $(NObjects) +NLObjs := $(sort $(addsuffix .llvm.o, $(notdir $(basename $(Source))))) +NLObjects := $(addprefix Output/,$(NLObjs)) + +.PRECIOUS: $(LObjects) $(NObjects) $(NLObjects) Output/%.o: %.c Output/.dir -$(CC) $(CPPFLAGS) $(CFLAGS) $(OPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ @@ -39,6 +42,25 @@ Output/%.o: %.cc Output/.dir -$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(OPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ +Output/%.llvm.o: %.c Output/.dir + $(RUNSAFELYLOCAL) /dev/null $@.compile \ + $(LCC) $(CPPFLAGS) $(CFLAGS) $(OPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ +Output/%.llvm.o: %.m Output/.dir + $(RUNSAFELYLOCAL) /dev/null $@.compile \ + $(LCC) $(CPPFLAGS) $(CFLAGS) $(OPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ +Output/%.llvm.o: %.C Output/.dir + $(RUNSAFELYLOCAL) /dev/null $@.compile \ + $(LCXX) $(CPPFLAGS) $(CXXFLAGS) $(OPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ +Output/%.llvm.o: %.cpp Output/.dir + $(RUNSAFELYLOCAL) /dev/null $@.compile \ + $(LCXX) $(CPPFLAGS) $(CXXFLAGS) $(OPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ +Output/%.llvm.o: %.cc Output/.dir + $(RUNSAFELYLOCAL) /dev/null $@.compile \ + $(LCXX) $(CPPFLAGS) $(CXXFLAGS) $(OPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ +Output/%.llvm.o: %.mm Output/.dir + $(RUNSAFELYLOCAL) /dev/null $@.compile \ + $(LCXX) $(CPPFLAGS) $(CXXFLAGS) $(OPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ + bugpoint-opt: Output/$(PROG).bugpoint-opt bugpoint-gccas: Output/$(PROG).bugpoint-opt bugpoint-llvm-ld: Output/$(PROG).bugpoint-llvm-ld @@ -62,6 +84,14 @@ endif +Output/%.simple: $(NLObjects) + @-cat $(NLObjects:%=%.compile.time) | awk -- '\ +BEGIN { sum = 0.0; }\ +/^program/ { sum += $$2; }\ +!/^program/ { print; }\ +END { printf("program %f\n", sum); }' > $@.compile.time + -$(LCXX) -o $@ $^ $(LDFLAGS) $(CFLAGS) $(TARGET_FLAGS) + Output/%.native: $(NObjects) -$(CXX) -o $@ $(NObjects) $(LDFLAGS) $(CFLAGS) $(TARGET_FLAGS) Modified: test-suite/trunk/SingleSource/Makefile.singlesrc URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/Makefile.singlesrc?rev=105124&r1=105123&r2=105124&view=diff ============================================================================== --- test-suite/trunk/SingleSource/Makefile.singlesrc (original) +++ test-suite/trunk/SingleSource/Makefile.singlesrc Sat May 29 19:48:15 2010 @@ -48,6 +48,30 @@ cat $< | wc -l > $@ endif +Output/%.llvm.o: %.c Output/.dir + $(RUNSAFELYLOCAL) /dev/null $@.compile \ + $(LCC) $(CPPFLAGS) $(CFLAGS) $(OPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ +Output/%.llvm.o: %.m Output/.dir + $(RUNSAFELYLOCAL) /dev/null $@.compile \ + $(LCC) $(CPPFLAGS) $(CFLAGS) $(OPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ +Output/%.llvm.o: %.C Output/.dir + $(RUNSAFELYLOCAL) /dev/null $@.compile \ + $(LCXX) $(CPPFLAGS) $(CXXFLAGS) $(OPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ +Output/%.llvm.o: %.cpp Output/.dir + $(RUNSAFELYLOCAL) /dev/null $@.compile \ + $(LCXX) $(CPPFLAGS) $(CXXFLAGS) $(OPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ +Output/%.llvm.o: %.cc Output/.dir + $(RUNSAFELYLOCAL) /dev/null $@.compile \ + $(LCXX) $(CPPFLAGS) $(CXXFLAGS) $(OPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ +Output/%.llvm.o: %.mm Output/.dir + $(RUNSAFELYLOCAL) /dev/null $@.compile \ + $(LCXX) $(CPPFLAGS) $(CXXFLAGS) $(OPTFLAGS) $(TARGET_FLAGS) -c $< -o $@ +.PRECIOUS: Output/%.llvm.o + +Output/%.simple: Output/%.llvm.o Output/.dir + -$(CP) $<.compile.time $@.compile.time + -$(LCXX) -o $@ $< $(LDFLAGS) $(CFLAGS) $(TARGET_FLAGS) + # FIXME: LIBS should be specified, not hardcoded to -lm Output/%.native: $(SourceDir)/%.c Output/.dir -$(CC) $(CPPFLAGS) $(CFLAGS) $(OPTFLAGS) $(TARGET_FLAGS) $< -lm -o $@ $(LDFLAGS) Added: test-suite/trunk/TEST.simple.Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/TEST.simple.Makefile?rev=105124&view=auto ============================================================================== --- test-suite/trunk/TEST.simple.Makefile (added) +++ test-suite/trunk/TEST.simple.Makefile Sat May 29 19:48:15 2010 @@ -0,0 +1,57 @@ +##===- TEST.nightly.Makefile ------------------------------*- Makefile -*--===## +# +# This test is used in conjunction with the llvm/utils/NightlyTest* stuff to +# generate information about program status for the nightly report. +# +##===----------------------------------------------------------------------===## + +CURDIR := $(shell cd .; pwd) +PROGDIR := $(PROJ_SRC_ROOT) +RELDIR := $(subst $(PROGDIR),,$(CURDIR)) + +REPORTS_TO_GEN := compile exec +REPORTS_SUFFIX := $(addsuffix .report.txt, $(REPORTS_TO_GEN)) + +#$(PROGRAMS_TO_TEST:%=Output/%.simple.compile.report.txt): \ +#Output/%.simple.compile.report.txt: Output/%.out-simple +# @echo > $@ +# @printf "TEST-RESULT-compile-time: " >> $@ +# -grep "^program" Output/$*.simple.compile.time >> $@ + +$(PROGRAMS_TO_TEST:%=Output/%.simple.compile.report.txt): \ +Output/%.simple.compile.report.txt: Output/%.out-simple + @echo > $@ + @-if test -f Output/$*.simple; then \ + echo "TEST-PASS: compile $(RELDIR)/$*" >> $@; \ + echo "TEST-RESULT-compile-success: pass" >> $@;\ + else \ + echo "TEST-FAIL: compile $(RELDIR)/$*" >> $@; \ + fi + @-printf "TEST-RESULT-compile-time: " >> $@ + @-grep "^program" Output/$*.simple.compile.time >> $@ + +$(PROGRAMS_TO_TEST:%=Output/%.simple.exec.report.txt): \ +Output/%.simple.exec.report.txt: Output/%.exe-simple + @echo > $@ + @-if test -f Output/$*.exe-simple; then \ + head -n 100 Output/$*.exe-simple >> $@; \ + echo "TEST-PASS: exec $(RELDIR)/$*" >> $@;\ + echo "TEST-RESULT-exec-success: pass" >> $@;\ + else \ + echo "TEST-FAIL: exec $(RELDIR)/$*" >> $@;\ + fi + @-printf "TEST-RESULT-exec-time: " >> $@ + @-grep "^program" Output/$*.out-simple.time >> $@ + +# Overall tests: just run subordinate tests +$(PROGRAMS_TO_TEST:%=Output/%.$(TEST).report.txt): \ +Output/%.$(TEST).report.txt: $(addprefix Output/%.simple., $(REPORTS_SUFFIX)) + $(VERB) $(RM) -f $@ + @echo "---------------------------------------------------------------" >> $@ + @echo ">>> ========= '$(RELDIR)/$*' Program" >> $@ + @echo "---------------------------------------------------------------" >> $@ + -cat $(addprefix Output/$*.simple., $(REPORTS_SUFFIX)) >> $@ + +$(PROGRAMS_TO_TEST:%=test.$(TEST).%): \ +test.$(TEST).%: Output/%.$(TEST).report.txt + @-cat $< Added: test-suite/trunk/TEST.simple.report URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/TEST.simple.report?rev=105124&view=auto ============================================================================== --- test-suite/trunk/TEST.simple.report (added) +++ test-suite/trunk/TEST.simple.report Sat May 29 19:48:15 2010 @@ -0,0 +1,30 @@ +##=== TEST.nightly.report - Report description for nightly -----*- perl -*-===## +# +# This file defines a report to be generated for the nightly tests. +# +##===----------------------------------------------------------------------===## + +# Sort by program name +$SortCol = 0; +$TrimRepeatedPrefix = 1; + +my $WallTimeRE = "Time: ([0-9.]+) seconds \\([0-9.]+ wall clock"; + +# FormatTime - Convert a time from 1m23.45 into 83.45 +sub FormatTime { + my $Time = shift; + if ($Time =~ m/([0-9]+)[m:]([0-9.]+)/) { + return sprintf("%7.4f", $1*60.0+$2); + } + + return sprintf("%7.4f", $Time); +} + +( + ["Program" , '\'([^\']+)\' Program'], + [], + ["CC" , 'TEST-RESULT-compile-success: (pass)'], + ["CC_Time" , 'TEST-RESULT-compile-time: program\s*([.0-9m:]+)', \&FormatTime], + ["Exec" , 'TEST-RESULT-exec-success: (pass)'], + ["Exec_Time", 'TEST-RESULT-exec-time: program\s*([.0-9m:]+)', \&FormatTime], +); From daniel at zuster.org Sat May 29 19:48:18 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Sun, 30 May 2010 00:48:18 -0000 Subject: [llvm-commits] [test-suite] r105125 - in /test-suite/trunk: HashProgramOutput.sh Makefile.programs Message-ID: <20100530004818.461983128018@llvm.org> Author: ddunbar Date: Sat May 29 19:48:18 2010 New Revision: 105125 URL: http://llvm.org/viewvc/llvm-project?rev=105125&view=rev Log: Add HASH_PROGRAM_OUTPUT makefile variable, which uses md5sum/md5 to hash the program output before comparing. This is useful for tests which have ridiculously large expected output files (as in