From lattner at cs.uiuc.edu Mon May 22 20:15:05 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 22 May 2006 20:15:05 -0500 Subject: [llvm-commits] CVS: llvm-test/TEST.libcalls.report TEST.libcalls.Makefile Message-ID: <200605230115.UAA19344@zion.cs.uiuc.edu> Changes in directory llvm-test: TEST.libcalls.report added (r1.1) TEST.libcalls.Makefile updated: 1.2 -> 1.3 --- Log message: Add a report for the libcalls test and make it work like normal tests. It is now a useful example for an LLVM optimizer pass. --- Diffs of the changes: (+32 -2) TEST.libcalls.Makefile | 11 +++++++++-- TEST.libcalls.report | 23 +++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) Index: llvm-test/TEST.libcalls.report diff -c /dev/null llvm-test/TEST.libcalls.report:1.1 *** /dev/null Mon May 22 20:15:01 2006 --- llvm-test/TEST.libcalls.report Mon May 22 20:14:51 2006 *************** *** 0 **** --- 1,23 ---- + ##=== TEST.libcalls.report - Report desc for libcalls tests ----*- perl -*-===## + # + # This file defines a report to be generated for the libcalls test. + # + ##===----------------------------------------------------------------------===## + + # Sort by name + $SortCol = 1; + $TrimRepeatedPrefix = 1; + + # These are the columns for the report. The first entry is the header for the + # column, the second is the regex to use to match the value. Empty list create + # seperators, and closures may be put in for custom processing. + ( + # Name + ["Name" , '\'([^\']+)\' Program'], + [], + ["total", '([0-9]+).*Number of library calls simplified'], + [], + # Specifics + ["#exit", '([0-9]+).*Number of .exit. calls simplified'], + [] + ); Index: llvm-test/TEST.libcalls.Makefile diff -u llvm-test/TEST.libcalls.Makefile:1.2 llvm-test/TEST.libcalls.Makefile:1.3 --- llvm-test/TEST.libcalls.Makefile:1.2 Sat May 14 13:46:10 2005 +++ llvm-test/TEST.libcalls.Makefile Mon May 22 20:14:51 2006 @@ -7,13 +7,20 @@ # Usage: # make TEST=libcalls summary (short summary) # make TEST=libcalls (detailed list with time passes, etc.) +# make TEST=libcalls report +# make TEST=libcalls report.html # ##===----------------------------------------------------------------------===## -TDIR:=$(patsubst $(PROJ_OBJ_ROOT)/%,%,$(shell pwd)) +CURDIR := $(shell cd .; pwd) +PROGDIR := $(PROJ_SRC_ROOT) +RELDIR := $(subst $(PROGDIR),,$(CURDIR)) + $(PROGRAMS_TO_TEST:%=test.$(TEST).%): \ test.$(TEST).%: Output/%.$(TEST).report.txt - @echo "======= $(TDIR)/$*' Program" + @echo "---------------------------------------------------------------" + @echo ">>> ========= '$(RELDIR)/$*' Program" + @echo "---------------------------------------------------------------" @cat $< $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).report.txt): \ From lattner at cs.uiuc.edu Mon May 22 20:25:23 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 22 May 2006 20:25:23 -0500 Subject: [llvm-commits] CVS: llvm/docs/TestingGuide.html Message-ID: <200605230125.UAA19405@zion.cs.uiuc.edu> Changes in directory llvm/docs: TestingGuide.html updated: 1.35 -> 1.36 --- Log message: Wrap long lines fix typo --- Diffs of the changes: (+20 -13) TestingGuide.html | 33 ++++++++++++++++++++------------- 1 files changed, 20 insertions(+), 13 deletions(-) Index: llvm/docs/TestingGuide.html diff -u llvm/docs/TestingGuide.html:1.35 llvm/docs/TestingGuide.html:1.36 --- llvm/docs/TestingGuide.html:1.35 Wed Apr 19 23:47:55 2006 +++ llvm/docs/TestingGuide.html Mon May 22 20:25:11 2006 @@ -108,9 +108,10 @@ programs in C and C++ is in the llvm-test module. This module should be checked out to the llvm/projects directory. When you configure the llvm module, the llvm-test module -will be automatically configured. Alternatively, you can configure the llvm-test module manually.

-

To run all of the simple tests in LLVM using DejaGNU, use the master Makefile in the -llvm/test directory:

+will be automatically configured. Alternatively, you can configure the + llvm-test module manually.

+

To run all of the simple tests in LLVM using DejaGNU, use the master Makefile + in the llvm/test directory:

 % gmake -C llvm/test
 
@@ -323,11 +324,13 @@ that you might find useful when writing RUN lines.

Lastly, you can easily mark a test that is expected to fail on a -specific platform or with a specific version of llvmgcc by using the XFAIL keyword. Xfail lines are +specific platform or with a specific version of llvmgcc by using the + XFAIL keyword. Xfail lines are specified in the comments of the test program using XFAIL, followed by a colon, and one or more regular expressions (separated by a comma) that will match against the target triplet or llvmgcc version for the -machine. You can use * to match all targets. You can specify the major or full version (i.e. 3.4) for llvmgcc. Here is an example of an +machine. You can use * to match all targets. You can specify the major or full + version (i.e. 3.4) for llvmgcc. Here is an example of an XFAIL line:

 ; XFAIL: darwin,sun,llvmgcc4
@@ -402,8 +405,8 @@
 are not executed inside of the LLVM source tree. This is because the
 test suite creates temporary files during execution.

-

The master Makefile in llvm/test is capable of running only the DejaGNU driven -tests. By default, it will run all of these tests.

+

The master Makefile in llvm/test is capable of running only the DejaGNU +driven tests. By default, it will run all of these tests.

To run only the DejaGNU driven tests, run gmake at the command line in llvm/test. To run a specific directory of tests, use @@ -432,7 +435,8 @@ properly configured.

  • Use the configure script found in the llvm-test source directory:
    - $LLVM_SRC_ROOT/projects/llvm-test/configure --with-llvmsrc=$LLVM_SRC_ROOT --with-llvmobj=$LLVM_OBJ_ROOT + $LLVM_SRC_ROOT/projects/llvm-test/configure + --with-llvmsrc=$LLVM_SRC_ROOT --with-llvmobj=$LLVM_OBJ_ROOT
  • gmake
  • @@ -483,11 +487,12 @@

    If you'd like to set up an instance of the nightly tester to run on your machine, take a look at the comments at the top of the utils/NightlyTester.pl file. We usually run it from a crontab entry -that looks ilke this:

    +that looks like this:

    -5 3 * * *  $HOME/llvm/utils/NightlyTest.pl -parallel $CVSROOT $HOME/buildtest-X86 $HOME/cvs/testresults-X86
    +5 3 * * *  $HOME/llvm/utils/NightlyTest.pl -parallel $CVSROOT \
    +           $HOME/buildtest $HOME/cvs/testresults
     
    @@ -506,8 +511,10 @@ export LD_LIBRARY_PATH=/proj/install/lib cd $BASE cp /proj/work/llvm/llvm/utils/NightlyTest.pl . -nice ./NightlyTest.pl -nice -release -verbose -parallel -enable-linscan -noexternals 2>&1 > output.log -mail -s 'X86 nightly tester results' llvm-testresults at cs.uiuc.edu < output.log +nice ./NightlyTest.pl -nice -release -verbose -parallel -enable-linscan \ + -noexternals 2>&1 > output.log +mail -s 'X86 nightly tester results' llvm-testresults at cs.uiuc.edu < output.log
    @@ -528,7 +535,7 @@ John T. Criswell, Reid Spencer, and Tanya Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2006/04/20 04:47:55 $ + Last modified: $Date: 2006/05/23 01:25:11 $ From lattner at cs.uiuc.edu Mon May 22 20:40:32 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 22 May 2006 20:40:32 -0500 Subject: [llvm-commits] CVS: llvm/docs/TestingGuide.html Message-ID: <200605230140.UAA19507@zion.cs.uiuc.edu> Changes in directory llvm/docs: TestingGuide.html updated: 1.36 -> 1.37 --- Log message: Describe how to add a custom test. --- Diffs of the changes: (+83 -4) TestingGuide.html | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 83 insertions(+), 4 deletions(-) Index: llvm/docs/TestingGuide.html diff -u llvm/docs/TestingGuide.html:1.36 llvm/docs/TestingGuide.html:1.37 --- llvm/docs/TestingGuide.html:1.36 Mon May 22 20:25:11 2006 +++ llvm/docs/TestingGuide.html Mon May 22 20:40:20 2006 @@ -24,7 +24,11 @@
  • LLVM Test Suite Tree
  • DejaGNU Structure
  • llvm-test Structure
  • -
  • Running the LLVM Tests
  • +
  • Running the LLVM Tests + +
  • Running the nightly tester
  • @@ -157,8 +161,9 @@ -
    Code Fragments -
    + +
    Code Fragments
    +
    @@ -175,7 +180,9 @@
    +
    Whole Programs
    +
    @@ -471,6 +478,78 @@
    + +
    +Writing custom tests for llvm-test
    + + +
    + +

    Assuming you can run llvm-test, (e.g. "gmake TEST=nightly report" +should work), it is really easy to run optimizations or code generator +components against every program in the tree, collecting statistics or running +custom checks for correctness. At base, this is how the nightly tester works, +it's just one example of a general framework.

    + +

    Lets say that you have an LLVM optimization pass, and you want to see how +many times it triggers. First thing you should do is add an LLVM +statistic to your pass, which +will tally counts of things you care about.

    + +

    Following this, you can set up a test and a report that collects these and +formats them for easy viewing. This consists of two files, an +"llvm-test/TEST.XXX.Makefile" fragment (where XXX is the name of your +test) and an "llvm-test/TEST.XXX.report" file that indicates how to +format the output into a table. There are many example reports of various +levels of sophistication included with llvm-test, and the framework is very +general.

    + +

    If you are interested in testing an optimization pass, check out the +"libcalls" test as an example. It can be run like this:

    + +

    +
    +% cd llvm/projects/llvm-test/MultiSource/Benchmarks  # or some other level
    +% make TEST=libcalls report
    +
    +
    + +

    This will do a bunch of stuff, then eventually print a table like this:

    + +
    +
    +Name                                  | total | #exit |
    +...
    +FreeBench/analyzer/analyzer           | 51    | 6     | 
    +FreeBench/fourinarow/fourinarow       | 1     | 1     | 
    +FreeBench/neural/neural               | 19    | 9     | 
    +FreeBench/pifft/pifft                 | 5     | 3     | 
    +MallocBench/cfrac/cfrac               | 1     | *     | 
    +MallocBench/espresso/espresso         | 52    | 12    | 
    +MallocBench/gs/gs                     | 4     | *     | 
    +Prolangs-C/TimberWolfMC/timberwolfmc  | 302   | *     | 
    +Prolangs-C/agrep/agrep                | 33    | 12    | 
    +Prolangs-C/allroots/allroots          | *     | *     | 
    +Prolangs-C/assembler/assembler        | 47    | *     | 
    +Prolangs-C/bison/mybison              | 74    | *     | 
    +...
    +
    +
    + +

    This basically is grepping the -stats output and displaying it in a table. +You can also use the "TEST=libcalls report.html" target to get the table in HTML +form, similarly for report.csv and report.tex.

    + +

    The source for this is in llvm-test/TEST.libcalls.*. The format is pretty +simple: the Makefile indicates how to run the test (in this case, +"opt -simplify-libcalls -stats"), and the report contains one line for +each column of the output. The first value is the header for the column and the +second is the regex to grep the output of the command for. There are lots of +example reports that can do fancy stuff.

    + +
    + +
    Running the nightly tester
    @@ -535,7 +614,7 @@ John T. Criswell, Reid Spencer, and Tanya Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2006/05/23 01:25:11 $ + Last modified: $Date: 2006/05/23 01:40:20 $ From rafael.espindola at gmail.com Mon May 22 21:48:33 2006 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Mon, 22 May 2006 21:48:33 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/ARM/ARMAsmPrinter.cpp ARMISelDAGToDAG.cpp ARMInstrInfo.cpp Message-ID: <200605230248.VAA19792@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/ARM: ARMAsmPrinter.cpp updated: 1.1 -> 1.2 ARMISelDAGToDAG.cpp updated: 1.3 -> 1.4 ARMInstrInfo.cpp updated: 1.1 -> 1.2 --- Log message: implement minimal versions of ARMAsmPrinter::runOnMachineFunction LowerFORMAL_ARGUMENTS ARMInstrInfo::isMoveInstr --- Diffs of the changes: (+80 -9) ARMAsmPrinter.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++++--- ARMISelDAGToDAG.cpp | 37 ++++++++++++++++++++++++++++++++++++- ARMInstrInfo.cpp | 5 ----- 3 files changed, 80 insertions(+), 9 deletions(-) Index: llvm/lib/Target/ARM/ARMAsmPrinter.cpp diff -u llvm/lib/Target/ARM/ARMAsmPrinter.cpp:1.1 llvm/lib/Target/ARM/ARMAsmPrinter.cpp:1.2 --- llvm/lib/Target/ARM/ARMAsmPrinter.cpp:1.1 Sun May 14 17:18:28 2006 +++ llvm/lib/Target/ARM/ARMAsmPrinter.cpp Mon May 22 21:48:20 2006 @@ -85,8 +85,50 @@ /// method to print assembly for each instruction. /// bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { - assert(0 && "not implemented"); - // We didn't modify anything. + SetupMachineFunction(MF); + O << "\n\n"; + + // Print out constants referenced by the function + EmitConstantPool(MF.getConstantPool()); + + // Print out jump tables referenced by the function + EmitJumpTableInfo(MF.getJumpTableInfo()); + + // Print out labels for the function. + const Function *F = MF.getFunction(); + switch (F->getLinkage()) { + default: assert(0 && "Unknown linkage type!"); + case Function::InternalLinkage: + SwitchToTextSection("\t.text", F); + break; + case Function::ExternalLinkage: + SwitchToTextSection("\t.text", F); + O << "\t.globl\t" << CurrentFnName << "\n"; + break; + case Function::WeakLinkage: + case Function::LinkOnceLinkage: + assert(0 && "Not implemented"); + break; + } + EmitAlignment(4, F); + O << CurrentFnName << ":\n"; + + // Print out code for the function. + for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); + I != E; ++I) { + // Print a label for the basic block. + if (I != MF.begin()) { + printBasicBlockLabel(I, true); + O << '\n'; + } + for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); + II != E; ++II) { + // Print the assembly for the instruction. + O << "\t"; + printInstruction(II); + } + } + return false; } @@ -109,7 +151,6 @@ } bool ARMAsmPrinter::doFinalization(Module &M) { - assert(0 && "not implemented"); AsmPrinter::doFinalization(M); return false; // success } Index: llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp diff -u llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp:1.3 llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp:1.4 --- llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp:1.3 Thu May 18 16:45:49 2006 +++ llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp Mon May 22 21:48:20 2006 @@ -82,7 +82,42 @@ } static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG) { - assert(0 && "Not implemented"); + MachineFunction &MF = DAG.getMachineFunction(); + SSARegMap *RegMap = MF.getSSARegMap(); + std::vector ArgValues; + SDOperand Root = Op.getOperand(0); + + unsigned reg_idx = 0; + unsigned num_regs = 4; + + static const unsigned REGS[] = { + ARM::R0, ARM::R1, ARM::R2, ARM::R3 + }; + + for (unsigned ArgNo = 0, e = Op.Val->getNumValues()-1; ArgNo != e; ++ArgNo) { + SDOperand ArgVal; + + MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType(); + assert (ObjectVT == MVT::i32); + + assert(reg_idx < num_regs); + unsigned VReg = RegMap->createVirtualRegister(&ARM::IntRegsRegClass); + MF.addLiveIn(REGS[reg_idx], VReg); + ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i32); + ++reg_idx; + + ArgValues.push_back(ArgVal); + } + + bool isVarArg = cast(Op.getOperand(2))->getValue() != 0; + assert(!isVarArg); + + ArgValues.push_back(Root); + + // Return the new list of results. + std::vector RetVT(Op.Val->value_begin(), + Op.Val->value_end()); + return DAG.getNode(ISD::MERGE_VALUES, RetVT, ArgValues); } SDOperand ARMTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { Index: llvm/lib/Target/ARM/ARMInstrInfo.cpp diff -u llvm/lib/Target/ARM/ARMInstrInfo.cpp:1.1 llvm/lib/Target/ARM/ARMInstrInfo.cpp:1.2 --- llvm/lib/Target/ARM/ARMInstrInfo.cpp:1.1 Sun May 14 17:18:28 2006 +++ llvm/lib/Target/ARM/ARMInstrInfo.cpp Mon May 22 21:48:20 2006 @@ -27,11 +27,6 @@ /// bool ARMInstrInfo::isMoveInstr(const MachineInstr &MI, unsigned &SrcReg, unsigned &DstReg) const { - // We look for 3 kinds of patterns here: - // or with G0 or 0 - // add with G0 or 0 - // fmovs or FpMOVD (pseudo double move). - assert(0 && "not implemented"); return false; } From evan.cheng at apple.com Tue May 23 01:39:24 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 23 May 2006 01:39:24 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetMachine.cpp Message-ID: <200605230639.BAA20665@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetMachine.cpp updated: 1.44 -> 1.45 --- Log message: Added option -enable-finite-only-fp-math. When on, the codegen can assume that FP arithmetic arguments and results are never NaNs or +=Infs. This includes ignoring parity flag (PF) when checking for FP equality. --- Diffs of the changes: (+6 -0) TargetMachine.cpp | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/lib/Target/TargetMachine.cpp diff -u llvm/lib/Target/TargetMachine.cpp:1.44 llvm/lib/Target/TargetMachine.cpp:1.45 --- llvm/lib/Target/TargetMachine.cpp:1.44 Tue May 2 20:29:56 2006 +++ llvm/lib/Target/TargetMachine.cpp Tue May 23 01:39:12 2006 @@ -26,6 +26,7 @@ bool NoFramePointerElim; bool NoExcessFPPrecision; bool UnsafeFPMath; + bool FiniteOnlyFPMath; Reloc::Model RelocationModel; }; namespace { @@ -48,6 +49,11 @@ cl::desc("Enable optimizations that may decrease FP precision"), cl::location(UnsafeFPMath), cl::init(false)); + cl::opt + EnableFiniteOnltFPMath("enable-finite-only-fp-math", + cl::desc("Enable optimizations that assumes non- NaNs / +-Infs"), + cl::location(FiniteOnlyFPMath), + cl::init(false)); cl::opt DefRelocationModel( "relocation-model", From evan.cheng at apple.com Tue May 23 01:39:25 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 23 May 2006 01:39:25 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetOptions.h Message-ID: <200605230639.BAA20669@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetOptions.h updated: 1.8 -> 1.9 --- Log message: Added option -enable-finite-only-fp-math. When on, the codegen can assume that FP arithmetic arguments and results are never NaNs or +=Infs. This includes ignoring parity flag (PF) when checking for FP equality. --- Diffs of the changes: (+7 -0) TargetOptions.h | 7 +++++++ 1 files changed, 7 insertions(+) Index: llvm/include/llvm/Target/TargetOptions.h diff -u llvm/include/llvm/Target/TargetOptions.h:1.8 llvm/include/llvm/Target/TargetOptions.h:1.9 --- llvm/include/llvm/Target/TargetOptions.h:1.8 Wed Feb 22 14:19:42 2006 +++ llvm/include/llvm/Target/TargetOptions.h Tue May 23 01:39:12 2006 @@ -40,6 +40,13 @@ /// produce results that are "less precise" than IEEE allows. This includes /// use of X86 instructions like FSIN and FCOS instead of libcalls. extern bool UnsafeFPMath; + + /// FiniteOnlyFPMath - This is enabled when the -enable-finite-only-fp-math + /// flag is specified on the command line. When this flag is off (default), + /// the code generator is not allowed to assume that FP arithmetic arguments + /// and results are never NaNs or +-Infs. This includes ignoring parity flag + /// (PF) when checking for FP equality. + extern bool FiniteOnlyFPMath; } // End llvm namespace #endif From evan.cheng at apple.com Tue May 23 01:40:59 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 23 May 2006 01:40:59 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200605230640.BAA20696@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.247 -> 1.248 --- Log message: Incorrect SETCC CondCode used for FP comparisons. --- Diffs of the changes: (+20 -9) SelectionDAGISel.cpp | 29 ++++++++++++++++++++--------- 1 files changed, 20 insertions(+), 9 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.247 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.248 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.247 Wed May 17 15:49:36 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue May 23 01:40:47 2006 @@ -512,13 +512,20 @@ visitShift(I, I.getType()->isUnsigned() ? ISD::SRL : ISD::SRA); } - void visitSetCC(User &I, ISD::CondCode SignedOpc, ISD::CondCode UnsignedOpc); - void visitSetEQ(User &I) { visitSetCC(I, ISD::SETEQ, ISD::SETEQ); } - void visitSetNE(User &I) { visitSetCC(I, ISD::SETNE, ISD::SETNE); } - void visitSetLE(User &I) { visitSetCC(I, ISD::SETLE, ISD::SETULE); } - void visitSetGE(User &I) { visitSetCC(I, ISD::SETGE, ISD::SETUGE); } - void visitSetLT(User &I) { visitSetCC(I, ISD::SETLT, ISD::SETULT); } - void visitSetGT(User &I) { visitSetCC(I, ISD::SETGT, ISD::SETUGT); } + void visitSetCC(User &I, ISD::CondCode SignedOpc, ISD::CondCode UnsignedOpc, + ISD::CondCode FPOpc); + void visitSetEQ(User &I) { visitSetCC(I, ISD::SETEQ, ISD::SETEQ, + ISD::SETOEQ); } + void visitSetNE(User &I) { visitSetCC(I, ISD::SETNE, ISD::SETNE, + ISD::SETUNE); } + void visitSetLE(User &I) { visitSetCC(I, ISD::SETLE, ISD::SETULE, + ISD::SETOLE); } + void visitSetGE(User &I) { visitSetCC(I, ISD::SETGE, ISD::SETUGE, + ISD::SETOGE); } + void visitSetLT(User &I) { visitSetCC(I, ISD::SETLT, ISD::SETULT, + ISD::SETOLT); } + void visitSetGT(User &I) { visitSetCC(I, ISD::SETGT, ISD::SETUGT, + ISD::SETOGT); } void visitExtractElement(User &I); void visitInsertElement(User &I); @@ -1092,11 +1099,15 @@ } void SelectionDAGLowering::visitSetCC(User &I,ISD::CondCode SignedOpcode, - ISD::CondCode UnsignedOpcode) { + ISD::CondCode UnsignedOpcode, + ISD::CondCode FPOpcode) { SDOperand Op1 = getValue(I.getOperand(0)); SDOperand Op2 = getValue(I.getOperand(1)); ISD::CondCode Opcode = SignedOpcode; - if (I.getOperand(0)->getType()->isUnsigned()) + if ((!UnsafeFPMath && !FiniteOnlyFPMath) && + I.getOperand(0)->getType()->isFloatingPoint()) + Opcode = FPOpcode; + else if (I.getOperand(0)->getType()->isUnsigned()) Opcode = UnsignedOpcode; setValue(&I, DAG.getSetCC(MVT::i1, Op1, Op2, Opcode)); } From evan.cheng at apple.com Tue May 23 01:41:35 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 23 May 2006 01:41:35 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/2006-05-22-FPSetEQ.ll Message-ID: <200605230641.BAA20714@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: 2006-05-22-FPSetEQ.ll added (r1.1) --- Log message: Added a test case for FP equality check. --- Diffs of the changes: (+9 -0) 2006-05-22-FPSetEQ.ll | 9 +++++++++ 1 files changed, 9 insertions(+) Index: llvm/test/Regression/CodeGen/X86/2006-05-22-FPSetEQ.ll diff -c /dev/null llvm/test/Regression/CodeGen/X86/2006-05-22-FPSetEQ.ll:1.1 *** /dev/null Tue May 23 01:41:33 2006 --- llvm/test/Regression/CodeGen/X86/2006-05-22-FPSetEQ.ll Tue May 23 01:41:23 2006 *************** *** 0 **** --- 1,9 ---- + ; RUN: llvm-as < %s | llc -march=x86 && + ; RUN: llvm-as < %s | llc -march=x86 | grep 'setnp' + ; RUN: llvm-as < %s | llc -march=x86 -enable-unsafe-fp-math | not grep 'setnp' + + uint %test(float %f) { + %tmp = seteq float %f, 0.000000e+00 + %tmp = cast bool %tmp to uint + ret uint %tmp + } From ghost at cs.msu.su Tue May 23 08:43:27 2006 From: ghost at cs.msu.su (Vladimir Prus) Date: Tue, 23 May 2006 08:43:27 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200605231343.IAA32156@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.248 -> 1.249 --- Log message: Fix missing include --- Diffs of the changes: (+1 -0) SelectionDAGISel.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.248 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.249 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.248 Tue May 23 01:40:47 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue May 23 08:43:15 2006 @@ -37,6 +37,7 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetOptions.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/MathExtras.h" From ghost at cs.msu.su Tue May 23 10:32:27 2006 From: ghost at cs.msu.su (Vladimir Prus) Date: Tue, 23 May 2006 10:32:27 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineFrameInfo.h Message-ID: <200605231532.KAA32731@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineFrameInfo.h updated: 1.17 -> 1.18 --- Log message: Make class comment visible in Doxygen. --- Diffs of the changes: (+31 -28) MachineFrameInfo.h | 59 +++++++++++++++++++++++++++-------------------------- 1 files changed, 31 insertions(+), 28 deletions(-) Index: llvm/include/llvm/CodeGen/MachineFrameInfo.h diff -u llvm/include/llvm/CodeGen/MachineFrameInfo.h:1.17 llvm/include/llvm/CodeGen/MachineFrameInfo.h:1.18 --- llvm/include/llvm/CodeGen/MachineFrameInfo.h:1.17 Fri Apr 7 11:34:45 2006 +++ llvm/include/llvm/CodeGen/MachineFrameInfo.h Tue May 23 10:32:15 2006 @@ -6,34 +6,7 @@ // the University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// The MachineFrameInfo class represents an abstract stack frame until -// prolog/epilog code is inserted. This class is key to allowing stack frame -// representation optimizations, such as frame pointer elimination. It also -// allows more mundane (but still important) optimizations, such as reordering -// of abstract objects on the stack frame. -// -// To support this, the class assigns unique integer identifiers to stack -// objects requested clients. These identifiers are negative integers for fixed -// stack objects (such as arguments passed on the stack) or positive for objects -// that may be reordered. Instructions which refer to stack objects use a -// special MO_FrameIndex operand to represent these frame indexes. -// -// Because this class keeps track of all references to the stack frame, it knows -// when a variable sized object is allocated on the stack. This is the sole -// condition which prevents frame pointer elimination, which is an important -// optimization on register-poor architectures. Because original variable sized -// alloca's in the source program are the only source of variable sized stack -// objects, it is safe to decide whether there will be any variable sized -// objects before all stack objects are known (for example, register allocator -// spill code never needs variable sized objects). -// -// When prolog/epilog code emission is performed, the final stack frame is built -// and the machine instructions are modified to refer to the actual stack -// offsets of the object, eliminating all MO_FrameIndex operands from the -// program. -// -//===----------------------------------------------------------------------===// + #ifndef LLVM_CODEGEN_MACHINEFRAMEINFO_H #define LLVM_CODEGEN_MACHINEFRAMEINFO_H @@ -47,6 +20,36 @@ class MachineDebugInfo; class MachineFunction; + +/// The MachineFrameInfo class represents an abstract stack frame until +/// prolog/epilog code is inserted. This class is key to allowing stack frame +/// representation optimizations, such as frame pointer elimination. It also +/// allows more mundane (but still important) optimizations, such as reordering +/// of abstract objects on the stack frame. +/// +/// To support this, the class assigns unique integer identifiers to stack +/// objects requested clients. These identifiers are negative integers for +/// fixed stack objects (such as arguments passed on the stack) or positive +/// for objects that may be reordered. Instructions which refer to stack +/// objects use a special MO_FrameIndex operand to represent these frame +/// indexes. +/// +/// Because this class keeps track of all references to the stack frame, it +/// knows when a variable sized object is allocated on the stack. This is the +/// sole condition which prevents frame pointer elimination, which is an +/// important optimization on register-poor architectures. Because original +/// variable sized alloca's in the source program are the only source of +/// variable sized stack objects, it is safe to decide whether there will be +/// any variable sized objects before all stack objects are known (for +/// example, register allocator spill code never needs variable sized +/// objects). +/// +/// When prolog/epilog code emission is performed, the final stack frame is +/// built and the machine instructions are modified to refer to the actual +/// stack offsets of the object, eliminating all MO_FrameIndex operands from +/// the program. +/// +/// @brief Abstract Stack Frame Information class MachineFrameInfo { // StackObject - Represent a single object allocated on the stack. From evan.cheng at apple.com Tue May 23 13:18:59 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 23 May 2006 13:18:59 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetMachine.cpp Message-ID: <200605231818.NAA01551@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetMachine.cpp updated: 1.45 -> 1.46 --- Log message: -enable-unsafe-fp-math implies -enable-finite-only-fp-math --- Diffs of the changes: (+10 -2) TargetMachine.cpp | 12 ++++++++++-- 1 files changed, 10 insertions(+), 2 deletions(-) Index: llvm/lib/Target/TargetMachine.cpp diff -u llvm/lib/Target/TargetMachine.cpp:1.45 llvm/lib/Target/TargetMachine.cpp:1.46 --- llvm/lib/Target/TargetMachine.cpp:1.45 Tue May 23 01:39:12 2006 +++ llvm/lib/Target/TargetMachine.cpp Tue May 23 13:18:46 2006 @@ -26,7 +26,7 @@ bool NoFramePointerElim; bool NoExcessFPPrecision; bool UnsafeFPMath; - bool FiniteOnlyFPMath; + bool FiniteOnlyFPMathOption; Reloc::Model RelocationModel; }; namespace { @@ -52,7 +52,7 @@ cl::opt EnableFiniteOnltFPMath("enable-finite-only-fp-math", cl::desc("Enable optimizations that assumes non- NaNs / +-Infs"), - cl::location(FiniteOnlyFPMath), + cl::location(FiniteOnlyFPMathOption), cl::init(false)); cl::opt DefRelocationModel( @@ -93,3 +93,11 @@ void TargetMachine::setRelocationModel(Reloc::Model Model) { RelocationModel = Model; } + +namespace llvm { + /// FiniteOnlyFPMath - This returns true when the -enable-finite-only-fp-math + /// option is specified on the command line. If this returns false (default), + /// the code generator is not allowed to assume that FP arithmetic arguments + /// and results are never NaNs or +-Infs. + bool FiniteOnlyFPMath() { return UnsafeFPMath || FiniteOnlyFPMathOption; } +}; From evan.cheng at apple.com Tue May 23 13:19:00 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 23 May 2006 13:19:00 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetOptions.h Message-ID: <200605231819.NAA01555@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetOptions.h updated: 1.9 -> 1.10 --- Log message: -enable-unsafe-fp-math implies -enable-finite-only-fp-math --- Diffs of the changes: (+6 -5) TargetOptions.h | 11 ++++++----- 1 files changed, 6 insertions(+), 5 deletions(-) Index: llvm/include/llvm/Target/TargetOptions.h diff -u llvm/include/llvm/Target/TargetOptions.h:1.9 llvm/include/llvm/Target/TargetOptions.h:1.10 --- llvm/include/llvm/Target/TargetOptions.h:1.9 Tue May 23 01:39:12 2006 +++ llvm/include/llvm/Target/TargetOptions.h Tue May 23 13:18:46 2006 @@ -39,14 +39,15 @@ /// this flag is off (the default), the code generator is not allowed to /// produce results that are "less precise" than IEEE allows. This includes /// use of X86 instructions like FSIN and FCOS instead of libcalls. + /// UnsafeFPMath implies FiniteOnlyFPMath. extern bool UnsafeFPMath; - /// FiniteOnlyFPMath - This is enabled when the -enable-finite-only-fp-math - /// flag is specified on the command line. When this flag is off (default), + /// FiniteOnlyFPMath - This returns true when the -enable-finite-only-fp-math + /// option is specified on the command line. If this returns false (default), /// the code generator is not allowed to assume that FP arithmetic arguments - /// and results are never NaNs or +-Infs. This includes ignoring parity flag - /// (PF) when checking for FP equality. - extern bool FiniteOnlyFPMath; + /// and results are never NaNs or +-Infs. + extern bool FiniteOnlyFPMathOption; + extern bool FiniteOnlyFPMath(); } // End llvm namespace #endif From evan.cheng at apple.com Tue May 23 13:19:00 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 23 May 2006 13:19:00 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200605231819.NAA01559@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.249 -> 1.250 --- Log message: -enable-unsafe-fp-math implies -enable-finite-only-fp-math --- Diffs of the changes: (+1 -2) SelectionDAGISel.cpp | 3 +-- 1 files changed, 1 insertion(+), 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.249 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.250 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.249 Tue May 23 08:43:15 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue May 23 13:18:46 2006 @@ -1105,8 +1105,7 @@ SDOperand Op1 = getValue(I.getOperand(0)); SDOperand Op2 = getValue(I.getOperand(1)); ISD::CondCode Opcode = SignedOpcode; - if ((!UnsafeFPMath && !FiniteOnlyFPMath) && - I.getOperand(0)->getType()->isFloatingPoint()) + if (!FiniteOnlyFPMath() && I.getOperand(0)->getType()->isFloatingPoint()) Opcode = FPOpcode; else if (I.getOperand(0)->getType()->isUnsigned()) Opcode = UnsignedOpcode; From lattner at cs.uiuc.edu Tue May 23 13:50:50 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 23 May 2006 13:50:50 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h Message-ID: <200605231850.NAA01755@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.207 -> 1.208 X86ISelLowering.h updated: 1.62 -> 1.63 --- Log message: Implement an annoying part of the Darwin/X86 abi: the callee of a struct return argument pops the hidden struct pointer if present, not the caller. For example, in this testcase: struct X { int D, E, F, G; }; struct X bar() { struct X a; a.D = 0; a.E = 1; a.F = 2; a.G = 3; return a; } void foo(struct X *P) { *P = bar(); } We used to emit: _foo: subl $28, %esp movl 32(%esp), %eax movl %eax, (%esp) call _bar addl $28, %esp ret _bar: movl 4(%esp), %eax movl $0, (%eax) movl $1, 4(%eax) movl $2, 8(%eax) movl $3, 12(%eax) ret This is correct on Linux/X86 but not Darwin/X86. With this patch, we now emit: _foo: subl $28, %esp movl 32(%esp), %eax movl %eax, (%esp) call _bar *** addl $24, %esp ret _bar: movl 4(%esp), %eax movl $0, (%eax) movl $1, 4(%eax) movl $2, 8(%eax) movl $3, 12(%eax) *** ret $4 For the record, GCC emits (which is functionally equivalent to our new code): _bar: movl 4(%esp), %eax movl $3, 12(%eax) movl $2, 8(%eax) movl $1, 4(%eax) movl $0, (%eax) ret $4 _foo: pushl %esi subl $40, %esp movl 48(%esp), %esi leal 16(%esp), %eax movl %eax, (%esp) call _bar subl $4, %esp movl 16(%esp), %eax movl %eax, (%esi) movl 20(%esp), %eax movl %eax, 4(%esi) movl 24(%esp), %eax movl %eax, 8(%esi) movl 28(%esp), %eax movl %eax, 12(%esi) addl $40, %esp popl %esi ret This fixes SingleSource/Benchmarks/CoyoteBench/fftbench with LLC and the JIT, and fixes the X86-backend portion of PR729: http://llvm.cs.uiuc.edu/PR729 . The CBE still needs to be updated. --- Diffs of the changes: (+19 -3) X86ISelLowering.cpp | 20 ++++++++++++++++++-- X86ISelLowering.h | 2 +- 2 files changed, 19 insertions(+), 3 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.207 llvm/lib/Target/X86/X86ISelLowering.cpp:1.208 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.207 Fri May 19 16:34:04 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue May 23 13:50:38 2006 @@ -393,7 +393,8 @@ if (CallingConv == CallingConv::Fast && EnableFastCC) return LowerFastCCCallTo(Chain, RetTy, isTailCall, Callee, Args, DAG); - return LowerCCCCallTo(Chain, RetTy, isVarArg, isTailCall, Callee, Args, DAG); + return LowerCCCCallTo(Chain, RetTy, isVarArg, isTailCall, CallingConv, + Callee, Args, DAG); } //===----------------------------------------------------------------------===// @@ -520,6 +521,12 @@ ReturnAddrIndex = 0; // No return address slot generated yet. BytesToPopOnReturn = 0; // Callee pops nothing. BytesCallerReserves = ArgOffset; + + // If this is a struct return on Darwin/X86, the callee pops the hidden struct + // pointer. + if (F.getCallingConv() == CallingConv::CSRet && + Subtarget->isTargetDarwin()) + BytesToPopOnReturn = 4; } void X86TargetLowering::LowerCCCArguments(SDOperand Op, SelectionDAG &DAG) { @@ -551,6 +558,7 @@ std::pair X86TargetLowering::LowerCCCCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, bool isTailCall, + unsigned CallingConv, SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG) { // Count how many bytes are to be pushed on the stack. @@ -704,13 +712,21 @@ Chain = DAG.getNode(X86ISD::CALL, NodeTys, Ops); InFlag = Chain.getValue(1); + // Create the CALLSEQ_END node. + unsigned NumBytesForCalleeToPush = 0; + + // If this is is a call to a struct-return function on Darwin/X86, the callee + // pops the hidden struct pointer, so we have to push it back. + if (CallingConv == CallingConv::CSRet && Subtarget->isTargetDarwin()) + NumBytesForCalleeToPush = 4; + NodeTys.clear(); NodeTys.push_back(MVT::Other); // Returns a chain NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use. Ops.clear(); Ops.push_back(Chain); Ops.push_back(DAG.getConstant(NumBytes, getPointerTy())); - Ops.push_back(DAG.getConstant(0, getPointerTy())); + Ops.push_back(DAG.getConstant(NumBytesForCalleeToPush, getPointerTy())); Ops.push_back(InFlag); Chain = DAG.getNode(ISD::CALLSEQ_END, NodeTys, Ops); InFlag = Chain.getValue(1); Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.62 llvm/lib/Target/X86/X86ISelLowering.h:1.63 --- llvm/lib/Target/X86/X86ISelLowering.h:1.62 Wed May 17 14:07:40 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Tue May 23 13:50:38 2006 @@ -374,7 +374,7 @@ void LowerCCCArguments(SDOperand Op, SelectionDAG &DAG); std::pair LowerCCCCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, - bool isTailCall, + bool isTailCall, unsigned CallingConv, SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); // Fast Calling Convention implementation. From evan.cheng at apple.com Tue May 23 16:06:46 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 23 May 2006 16:06:46 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h Message-ID: <200605232106.QAA02552@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.208 -> 1.209 X86ISelLowering.h updated: 1.63 -> 1.64 --- Log message: Remove PreprocessCCCArguments and PreprocessFastCCArguments now that FORMAL_ARGUMENTS nodes include a token operand. --- Diffs of the changes: (+124 -253) X86ISelLowering.cpp | 341 ++++++++++++++++++---------------------------------- X86ISelLowering.h | 36 ----- 2 files changed, 124 insertions(+), 253 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.208 llvm/lib/Target/X86/X86ISelLowering.cpp:1.209 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.208 Tue May 23 13:50:38 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue May 23 16:06:34 2006 @@ -358,22 +358,6 @@ allowUnalignedMemoryAccesses = true; // x86 supports it! } -std::vector -X86TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { - std::vector Args = TargetLowering::LowerArguments(F, DAG); - - FormalArgs.clear(); - FormalArgLocs.clear(); - - // This sets BytesToPopOnReturn, BytesCallerReserves, etc. which have to be - // set before the rest of the function can be lowered. - if (F.getCallingConv() == CallingConv::Fast && EnableFastCC) - PreprocessFastCCArguments(Args, F, DAG); - else - PreprocessCCCArguments(Args, F, DAG); - return Args; -} - std::pair X86TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, unsigned CallingConv, @@ -463,11 +447,12 @@ return Objs; } -void X86TargetLowering::PreprocessCCCArguments(std::vector &Args, - Function &F, SelectionDAG &DAG) { - unsigned NumArgs = Args.size(); +SDOperand X86TargetLowering::LowerCCCArguments(SDOperand Op, SelectionDAG &DAG) { + unsigned NumArgs = Op.Val->getNumValues() - 1; MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); + SDOperand Root = Op.getOperand(0); + std::vector ArgValues; // Add DAG nodes to load the arguments... On entry to a function on the X86, // the stack frame looks like this: @@ -481,78 +466,53 @@ unsigned NumXMMRegs = 0; // XMM regs used for parameter passing. unsigned XMMArgRegs[] = { X86::XMM0, X86::XMM1, X86::XMM2 }; for (unsigned i = 0; i < NumArgs; ++i) { - SDOperand Op = Args[i]; - std::vector Objs = getFormalArgObjects(Op); - for (std::vector::iterator I = Objs.begin(), E = Objs.end(); - I != E; ++I) { - SDOperand Obj = *I; - MVT::ValueType ObjectVT = Obj.getValueType(); - unsigned ArgIncrement = 4; - unsigned ObjSize = 0; - unsigned ObjXMMRegs = 0; - HowToPassCCCArgument(ObjectVT, NumXMMRegs, ObjSize, ObjXMMRegs); - if (ObjSize >= 8) - ArgIncrement = ObjSize; - - if (ObjXMMRegs) { - // Passed in a XMM register. - unsigned Reg = AddLiveIn(MF, XMMArgRegs[NumXMMRegs], + MVT::ValueType ObjectVT = Op.getValue(i).getValueType(); + unsigned ArgIncrement = 4; + unsigned ObjSize = 0; + unsigned ObjXMMRegs = 0; + HowToPassCCCArgument(ObjectVT, NumXMMRegs, ObjSize, ObjXMMRegs); + if (ObjSize >= 8) + ArgIncrement = ObjSize; + + SDOperand ArgValue; + if (ObjXMMRegs) { + // Passed in a XMM register. + unsigned Reg = AddLiveIn(MF, XMMArgRegs[NumXMMRegs], X86::VR128RegisterClass); - std::pair Loc = - std::make_pair(FALocInfo(FALocInfo::LiveInRegLoc, Reg, ObjectVT), - FALocInfo()); - FormalArgLocs.push_back(Loc); - NumXMMRegs += ObjXMMRegs; - } else { - // Create the frame index object for this incoming parameter... - int FI = MFI->CreateFixedObject(ObjSize, ArgOffset); - std::pair Loc = - std::make_pair(FALocInfo(FALocInfo::StackFrameLoc, FI), FALocInfo()); - FormalArgLocs.push_back(Loc); - ArgOffset += ArgIncrement; // Move on to the next argument... - } + ArgValue= DAG.getCopyFromReg(Root, Reg, ObjectVT); + ArgValues.push_back(ArgValue); + NumXMMRegs += ObjXMMRegs; + } else { + // Create the frame index object for this incoming parameter... + int FI = MFI->CreateFixedObject(ObjSize, ArgOffset); + SDOperand FIN = DAG.getFrameIndex(FI, getPointerTy()); + ArgValue = DAG.getLoad(Op.Val->getValueType(i), Root, FIN, + DAG.getSrcValue(NULL)); + ArgValues.push_back(ArgValue); + ArgOffset += ArgIncrement; // Move on to the next argument... } } + ArgValues.push_back(Root); + // If the function takes variable number of arguments, make a frame index for // the start of the first vararg value... for expansion of llvm.va_start. - if (F.isVarArg()) + if (MF.getFunction()->isVarArg()) VarArgsFrameIndex = MFI->CreateFixedObject(1, ArgOffset); ReturnAddrIndex = 0; // No return address slot generated yet. BytesToPopOnReturn = 0; // Callee pops nothing. BytesCallerReserves = ArgOffset; - + // If this is a struct return on Darwin/X86, the callee pops the hidden struct // pointer. - if (F.getCallingConv() == CallingConv::CSRet && + if (MF.getFunction()->getCallingConv() == CallingConv::CSRet && Subtarget->isTargetDarwin()) BytesToPopOnReturn = 4; -} - -void X86TargetLowering::LowerCCCArguments(SDOperand Op, SelectionDAG &DAG) { - unsigned NumArgs = Op.Val->getNumValues() - 1; - MachineFunction &MF = DAG.getMachineFunction(); - for (unsigned i = 0; i < NumArgs; ++i) { - std::pair Loc = FormalArgLocs[i]; - SDOperand ArgValue; - if (Loc.first.Kind == FALocInfo::StackFrameLoc) { - // Create the SelectionDAG nodes corresponding to a load from this - // parameter. - unsigned FI = FormalArgLocs[i].first.Loc; - SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); - ArgValue = DAG.getLoad(Op.Val->getValueType(i), - DAG.getEntryNode(), FIN, DAG.getSrcValue(NULL)); - } else { - // Must be a CopyFromReg - ArgValue= DAG.getCopyFromReg(DAG.getEntryNode(), Loc.first.Loc, - Loc.first.Typ); - } - FormalArgs.push_back(ArgValue); - } - // Provide a chain. Note that this isn't the right one, but it works as well - // as before. - FormalArgs.push_back(DAG.getEntryNode()); + // Return the new list of results. + std::vector RetVTs(Op.Val->value_begin(), + Op.Val->value_end()); + return DAG.getNode(ISD::MERGE_VALUES, RetVTs, ArgValues); } std::pair @@ -911,12 +871,13 @@ } } -void -X86TargetLowering::PreprocessFastCCArguments(std::vector &Args, - Function &F, SelectionDAG &DAG) { - unsigned NumArgs = Args.size(); +SDOperand +X86TargetLowering::LowerFastCCArguments(SDOperand Op, SelectionDAG &DAG) { + unsigned NumArgs = Op.Val->getNumValues()-1; MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); + SDOperand Root = Op.getOperand(0); + std::vector ArgValues; // Add DAG nodes to load the arguments... On entry to a function the stack // frame looks like this: @@ -935,94 +896,82 @@ unsigned XMMArgRegs[] = { X86::XMM0, X86::XMM1, X86::XMM2 }; for (unsigned i = 0; i < NumArgs; ++i) { - SDOperand Op = Args[i]; - std::vector Objs = getFormalArgObjects(Op); - for (std::vector::iterator I = Objs.begin(), E = Objs.end(); - I != E; ++I) { - SDOperand Obj = *I; - MVT::ValueType ObjectVT = Obj.getValueType(); - unsigned ArgIncrement = 4; - unsigned ObjSize = 0; - unsigned ObjIntRegs = 0; - unsigned ObjXMMRegs = 0; - - HowToPassFastCCArgument(ObjectVT, NumIntRegs, NumXMMRegs, - ObjSize, ObjIntRegs, ObjXMMRegs); - if (ObjSize >= 8) - ArgIncrement = ObjSize; - - unsigned Reg; - std::pair Loc = std::make_pair(FALocInfo(), - FALocInfo()); - if (ObjIntRegs) { - switch (ObjectVT) { - default: assert(0 && "Unhandled argument type!"); - case MVT::i1: - case MVT::i8: - Reg = AddLiveIn(MF, NumIntRegs ? X86::DL : X86::AL, - X86::GR8RegisterClass); - Loc.first.Kind = FALocInfo::LiveInRegLoc; - Loc.first.Loc = Reg; - Loc.first.Typ = MVT::i8; - break; - case MVT::i16: - Reg = AddLiveIn(MF, NumIntRegs ? X86::DX : X86::AX, - X86::GR16RegisterClass); - Loc.first.Kind = FALocInfo::LiveInRegLoc; - Loc.first.Loc = Reg; - Loc.first.Typ = MVT::i16; - break; - case MVT::i32: - Reg = AddLiveIn(MF, NumIntRegs ? X86::EDX : X86::EAX, - X86::GR32RegisterClass); - Loc.first.Kind = FALocInfo::LiveInRegLoc; - Loc.first.Loc = Reg; - Loc.first.Typ = MVT::i32; - break; - case MVT::i64: - Reg = AddLiveIn(MF, NumIntRegs ? X86::EDX : X86::EAX, - X86::GR32RegisterClass); - Loc.first.Kind = FALocInfo::LiveInRegLoc; - Loc.first.Loc = Reg; - Loc.first.Typ = MVT::i32; - if (ObjIntRegs == 2) { - Reg = AddLiveIn(MF, X86::EDX, X86::GR32RegisterClass); - Loc.second.Kind = FALocInfo::LiveInRegLoc; - Loc.second.Loc = Reg; - Loc.second.Typ = MVT::i32; - } - break; - case MVT::v16i8: - case MVT::v8i16: - case MVT::v4i32: - case MVT::v2i64: - case MVT::v4f32: - case MVT::v2f64: - Reg = AddLiveIn(MF, XMMArgRegs[NumXMMRegs], X86::VR128RegisterClass); - Loc.first.Kind = FALocInfo::LiveInRegLoc; - Loc.first.Loc = Reg; - Loc.first.Typ = ObjectVT; - break; - } - NumIntRegs += ObjIntRegs; - NumXMMRegs += ObjXMMRegs; - } - if (ObjSize) { - int FI = MFI->CreateFixedObject(ObjSize, ArgOffset); - if (ObjectVT == MVT::i64 && ObjIntRegs) { - Loc.second.Kind = FALocInfo::StackFrameLoc; - Loc.second.Loc = FI; - } else { - Loc.first.Kind = FALocInfo::StackFrameLoc; - Loc.first.Loc = FI; + MVT::ValueType ObjectVT = Op.getValue(i).getValueType(); + unsigned ArgIncrement = 4; + unsigned ObjSize = 0; + unsigned ObjIntRegs = 0; + unsigned ObjXMMRegs = 0; + + HowToPassFastCCArgument(ObjectVT, NumIntRegs, NumXMMRegs, + ObjSize, ObjIntRegs, ObjXMMRegs); + if (ObjSize >= 8) + ArgIncrement = ObjSize; + + unsigned Reg; + SDOperand ArgValue; + if (ObjIntRegs || ObjXMMRegs) { + switch (ObjectVT) { + default: assert(0 && "Unhandled argument type!"); + case MVT::i1: + case MVT::i8: + Reg = AddLiveIn(MF, NumIntRegs ? X86::DL : X86::AL, + X86::GR8RegisterClass); + ArgValue = DAG.getCopyFromReg(Root, Reg, MVT::i8); + break; + case MVT::i16: + Reg = AddLiveIn(MF, NumIntRegs ? X86::DX : X86::AX, + X86::GR16RegisterClass); + ArgValue = DAG.getCopyFromReg(Root, Reg, MVT::i16); + break; + case MVT::i32: + Reg = AddLiveIn(MF, NumIntRegs ? X86::EDX : X86::EAX, + X86::GR32RegisterClass); + ArgValue = DAG.getCopyFromReg(Root, Reg, MVT::i32); + break; + case MVT::i64: + Reg = AddLiveIn(MF, NumIntRegs ? X86::EDX : X86::EAX, + X86::GR32RegisterClass); + ArgValue = DAG.getCopyFromReg(Root, Reg, MVT::i32); + if (ObjIntRegs == 2) { + Reg = AddLiveIn(MF, X86::EDX, X86::GR32RegisterClass); + SDOperand ArgValue2 = DAG.getCopyFromReg(Root, Reg, MVT::i32); + ArgValue= DAG.getNode(ISD::BUILD_PAIR, MVT::i64, ArgValue, ArgValue2); } - ArgOffset += ArgIncrement; // Move on to the next argument. + break; + case MVT::v16i8: + case MVT::v8i16: + case MVT::v4i32: + case MVT::v2i64: + case MVT::v4f32: + case MVT::v2f64: + Reg = AddLiveIn(MF, XMMArgRegs[NumXMMRegs], X86::VR128RegisterClass); + ArgValue = DAG.getCopyFromReg(Root, Reg, ObjectVT); + break; } + NumIntRegs += ObjIntRegs; + NumXMMRegs += ObjXMMRegs; + } - FormalArgLocs.push_back(Loc); + if (ObjSize) { + // Create the SelectionDAG nodes corresponding to a load from this + // parameter. + int FI = MFI->CreateFixedObject(ObjSize, ArgOffset); + SDOperand FIN = DAG.getFrameIndex(FI, getPointerTy()); + if (ObjectVT == MVT::i64 && ObjIntRegs) { + SDOperand ArgValue2 = DAG.getLoad(Op.Val->getValueType(i), Root, FIN, + DAG.getSrcValue(NULL)); + ArgValue = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, ArgValue, ArgValue2); + } else + ArgValue = DAG.getLoad(Op.Val->getValueType(i), Root, FIN, + DAG.getSrcValue(NULL)); + ArgOffset += ArgIncrement; // Move on to the next argument. } + + ArgValues.push_back(ArgValue); } + ArgValues.push_back(Root); + // Make sure the instruction takes 8n+4 bytes to make sure the start of the // arguments and the arguments after the retaddr has been pushed are aligned. if ((ArgOffset & 7) == 0) @@ -1034,7 +983,7 @@ BytesCallerReserves = 0; // Finally, inform the code generator which regs we return values in. - switch (getValueType(F.getReturnType())) { + switch (getValueType(MF.getFunction()->getReturnType())) { default: assert(0 && "Unknown type!"); case MVT::isVoid: break; case MVT::i1: @@ -1052,7 +1001,7 @@ MF.addLiveOut(X86::ST0); break; case MVT::Vector: { - const PackedType *PTy = cast(F.getReturnType()); + const PackedType *PTy = cast(MF.getFunction()->getReturnType()); MVT::ValueType EVT; MVT::ValueType LVT; unsigned NumRegs = getPackedTypeBreakdown(PTy, EVT, LVT); @@ -1061,50 +1010,11 @@ break; } } -} - -void -X86TargetLowering::LowerFastCCArguments(SDOperand Op, SelectionDAG &DAG) { - unsigned NumArgs = Op.Val->getNumValues()-1; - MachineFunction &MF = DAG.getMachineFunction(); - for (unsigned i = 0; i < NumArgs; ++i) { - MVT::ValueType VT = Op.Val->getValueType(i); - std::pair Loc = FormalArgLocs[i]; - SDOperand ArgValue; - if (Loc.first.Kind == FALocInfo::StackFrameLoc) { - // Create the SelectionDAG nodes corresponding to a load from this - // parameter. - SDOperand FIN = DAG.getFrameIndex(Loc.first.Loc, MVT::i32); - ArgValue = DAG.getLoad(Op.Val->getValueType(i), DAG.getEntryNode(), FIN, - DAG.getSrcValue(NULL)); - } else { - // Must be a CopyFromReg - ArgValue= DAG.getCopyFromReg(DAG.getEntryNode(), Loc.first.Loc, - Loc.first.Typ); - } - - if (Loc.second.Kind != FALocInfo::None) { - SDOperand ArgValue2; - if (Loc.second.Kind == FALocInfo::StackFrameLoc) { - // Create the SelectionDAG nodes corresponding to a load from this - // parameter. - SDOperand FIN = DAG.getFrameIndex(Loc.second.Loc, MVT::i32); - ArgValue2 = DAG.getLoad(Op.Val->getValueType(i), DAG.getEntryNode(), - FIN, DAG.getSrcValue(NULL)); - } else { - // Must be a CopyFromReg - ArgValue2 = DAG.getCopyFromReg(DAG.getEntryNode(), - Loc.second.Loc, Loc.second.Typ); - } - ArgValue = DAG.getNode(ISD::BUILD_PAIR, VT, ArgValue, ArgValue2); - } - FormalArgs.push_back(ArgValue); - } - - // Provide a chain. Note that this isn't the right one, but it works as well - // as before. - FormalArgs.push_back(DAG.getEntryNode()); + // Return the new list of results. + std::vector RetVTs(Op.Val->value_begin(), + Op.Val->value_end()); + return DAG.getNode(ISD::MERGE_VALUES, RetVTs, ArgValues); } std::pair @@ -3529,18 +3439,11 @@ SDOperand X86TargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG) { - if (FormalArgs.size() == 0) { - unsigned CC = cast(Op.getOperand(1))->getValue(); - if (CC == CallingConv::Fast && EnableFastCC) - LowerFastCCArguments(Op, DAG); - else - LowerCCCArguments(Op, DAG); - } - - // Return the new list of results. - std::vector RetVTs(Op.Val->value_begin(), - Op.Val->value_end()); - return DAG.getNode(ISD::MERGE_VALUES, RetVTs, FormalArgs); + unsigned CC = cast(Op.getOperand(1))->getValue(); + if (CC == CallingConv::Fast && EnableFastCC) + return LowerFastCCArguments(Op, DAG); + else + return LowerCCCArguments(Op, DAG); } SDOperand X86TargetLowering::LowerMEMSET(SDOperand Op, SelectionDAG &DAG) { Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.63 llvm/lib/Target/X86/X86ISelLowering.h:1.64 --- llvm/lib/Target/X86/X86ISelLowering.h:1.63 Tue May 23 13:50:38 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Tue May 23 16:06:34 2006 @@ -282,11 +282,6 @@ /// virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); - /// LowerArguments - This hook must be implemented to indicate how we should - /// lower the arguments for the specified function, into the specified DAG. - virtual std::vector - LowerArguments(Function &F, SelectionDAG &DAG); - /// LowerCallTo - This hook lowers an abstract call to a function into an /// actual call. virtual std::pair @@ -346,42 +341,15 @@ /// X86ScalarSSE - Select between SSE2 or x87 floating point ops. bool X86ScalarSSE; - /// Formal arguments lowered to load and CopyFromReg ops. - std::vector FormalArgs; - - /// Formal arguments locations (frame indices and registers). - struct FALocInfo { - enum FALocKind { - None, - StackFrameLoc, - LiveInRegLoc, - } Kind; - - int Loc; - MVT::ValueType Typ; - - FALocInfo() : Kind(None), Loc(0), Typ(MVT::isVoid) {}; - FALocInfo(enum FALocKind k, int fi) : Kind(k), Loc(fi), Typ(MVT::isVoid) {}; - FALocInfo(enum FALocKind k, int r, MVT::ValueType vt) - : Kind(k), Loc(r), Typ(vt) {}; - }; - - std::vector > FormalArgLocs; - // C Calling Convention implementation. - void PreprocessCCCArguments(std::vector &Args, Function &F, - SelectionDAG &DAG); - void LowerCCCArguments(SDOperand Op, SelectionDAG &DAG); + SDOperand LowerCCCArguments(SDOperand Op, SelectionDAG &DAG); std::pair LowerCCCCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, bool isTailCall, unsigned CallingConv, SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); // Fast Calling Convention implementation. - void - PreprocessFastCCArguments(std::vector &Args, Function &F, - SelectionDAG &DAG); - void + SDOperand LowerFastCCArguments(SDOperand Op, SelectionDAG &DAG); std::pair LowerFastCCCallTo(SDOperand Chain, const Type *RetTy, bool isTailCall, From evan.cheng at apple.com Tue May 23 16:08:36 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 23 May 2006 16:08:36 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200605232108.QAA02568@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.209 -> 1.210 --- Log message: Better way to check for vararg. --- Diffs of the changes: (+2 -1) X86ISelLowering.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.209 llvm/lib/Target/X86/X86ISelLowering.cpp:1.210 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.209 Tue May 23 16:06:34 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue May 23 16:08:24 2006 @@ -497,7 +497,8 @@ // If the function takes variable number of arguments, make a frame index for // the start of the first vararg value... for expansion of llvm.va_start. - if (MF.getFunction()->isVarArg()) + bool isVarArg = cast(Op.getOperand(2))->getValue() != 0; + if (isVarArg) VarArgsFrameIndex = MFI->CreateFixedObject(1, ArgOffset); ReturnAddrIndex = 0; // No return address slot generated yet. BytesToPopOnReturn = 0; // Callee pops nothing. From lattner at cs.uiuc.edu Tue May 23 18:20:54 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 23 May 2006 18:20:54 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200605232320.SAA03631@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.210 -> 1.211 --- Log message: Fix file header comment --- Diffs of the changes: (+1 -1) X86ISelLowering.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.210 llvm/lib/Target/X86/X86ISelLowering.cpp:1.211 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.210 Tue May 23 16:08:24 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue May 23 18:20:42 2006 @@ -1,4 +1,4 @@ -//===-- X86ISelLowering.h - X86 DAG Lowering Interface ----------*- C++ -*-===// +//===-- X86ISelLowering.cpp - X86 DAG Lowering Implementation -------------===// // // The LLVM Compiler Infrastructure // From lattner at cs.uiuc.edu Tue May 23 18:40:00 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 23 May 2006 18:40:00 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/CBackend/Writer.cpp Message-ID: <200605232340.SAA03723@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/CBackend: Writer.cpp updated: 1.260 -> 1.261 --- Log message: Print struct return functions and calls as actually returning the hidden argument struct pointer, enabling ABI compatibility for the CBE with platforms with strange struct-return ABIs. This fixes 252.eon and CoyoteBench/fftbench on Darwin/X86 among other things. --- Diffs of the changes: (+171 -75) Writer.cpp | 246 ++++++++++++++++++++++++++++++++++++++++++------------------- 1 files changed, 171 insertions(+), 75 deletions(-) Index: llvm/lib/Target/CBackend/Writer.cpp diff -u llvm/lib/Target/CBackend/Writer.cpp:1.260 llvm/lib/Target/CBackend/Writer.cpp:1.261 --- llvm/lib/Target/CBackend/Writer.cpp:1.260 Mon Apr 17 12:55:40 2006 +++ llvm/lib/Target/CBackend/Writer.cpp Tue May 23 18:39:48 2006 @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "CTargetMachine.h" +#include "llvm/CallingConv.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Module.h" @@ -115,6 +116,9 @@ const std::string &VariableName = "", bool IgnoreName = false); + void printStructReturnPointerFunctionType(std::ostream &Out, + const PointerType *Ty); + void writeOperand(Value *Operand); void writeOperandInternal(Value *Operand); @@ -298,6 +302,35 @@ return Changed; } +/// printStructReturnPointerFunctionType - This is like printType for a struct +/// return type, except, instead of printing the type as void (*)(Struct*, ...) +/// print it as "Struct (*)(...)", for struct return functions. +void CWriter::printStructReturnPointerFunctionType(std::ostream &Out, + const PointerType *TheTy) { + const FunctionType *FTy = cast(TheTy->getElementType()); + std::stringstream FunctionInnards; + FunctionInnards << " (*) ("; + bool PrintedType = false; + + FunctionType::param_iterator I = FTy->param_begin(), E = FTy->param_end(); + const Type *RetTy = cast(I->get())->getElementType(); + for (++I; I != E; ++I) { + if (PrintedType) + FunctionInnards << ", "; + printType(FunctionInnards, *I, ""); + PrintedType = true; + } + if (FTy->isVarArg()) { + if (PrintedType) + FunctionInnards << ", ..."; + } else if (!PrintedType) { + FunctionInnards << "void"; + } + FunctionInnards << ')'; + std::string tstr = FunctionInnards.str(); + printType(Out, RetTy, tstr); +} + // Pass the Type* and the variable name and this prints out the variable // declaration. @@ -332,24 +365,24 @@ switch (Ty->getTypeID()) { case Type::FunctionTyID: { - const FunctionType *MTy = cast(Ty); + const FunctionType *FTy = cast(Ty); std::stringstream FunctionInnards; FunctionInnards << " (" << NameSoFar << ") ("; - for (FunctionType::param_iterator I = MTy->param_begin(), - E = MTy->param_end(); I != E; ++I) { - if (I != MTy->param_begin()) + for (FunctionType::param_iterator I = FTy->param_begin(), + E = FTy->param_end(); I != E; ++I) { + if (I != FTy->param_begin()) FunctionInnards << ", "; printType(FunctionInnards, *I, ""); } - if (MTy->isVarArg()) { - if (MTy->getNumParams()) + if (FTy->isVarArg()) { + if (FTy->getNumParams()) FunctionInnards << ", ..."; - } else if (!MTy->getNumParams()) { + } else if (!FTy->getNumParams()) { FunctionInnards << "void"; } FunctionInnards << ')'; std::string tstr = FunctionInnards.str(); - printType(Out, MTy->getReturnType(), tstr); + printType(Out, FTy->getReturnType(), tstr); return Out; } case Type::StructTyID: { @@ -1223,6 +1256,9 @@ } void CWriter::printFunctionSignature(const Function *F, bool Prototype) { + /// isCStructReturn - Should this function actually return a struct by-value? + bool isCStructReturn = F->getCallingConv() == CallingConv::CSRet; + if (F->hasInternalLinkage()) Out << "static "; // Loop over the arguments, printing them... @@ -1233,55 +1269,97 @@ // Print out the name... FunctionInnards << Mang->getValueName(F) << '('; + bool PrintedArg = false; if (!F->isExternal()) { if (!F->arg_empty()) { + Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end(); + + // If this is a struct-return function, don't print the hidden + // struct-return argument. + if (isCStructReturn) { + assert(I != E && "Invalid struct return function!"); + ++I; + } + std::string ArgName; - if (F->arg_begin()->hasName() || !Prototype) - ArgName = Mang->getValueName(F->arg_begin()); - printType(FunctionInnards, F->arg_begin()->getType(), ArgName); - for (Function::const_arg_iterator I = ++F->arg_begin(), E = F->arg_end(); - I != E; ++I) { - FunctionInnards << ", "; + for (; I != E; ++I) { + if (PrintedArg) FunctionInnards << ", "; if (I->hasName() || !Prototype) ArgName = Mang->getValueName(I); else ArgName = ""; printType(FunctionInnards, I->getType(), ArgName); + PrintedArg = true; } } } else { - // Loop over the arguments, printing them... - for (FunctionType::param_iterator I = FT->param_begin(), - E = FT->param_end(); I != E; ++I) { - if (I != FT->param_begin()) FunctionInnards << ", "; + // Loop over the arguments, printing them. + FunctionType::param_iterator I = FT->param_begin(), E = FT->param_end(); + + // If this is a struct-return function, don't print the hidden + // struct-return argument. + if (isCStructReturn) { + assert(I != E && "Invalid struct return function!"); + ++I; + } + + for (; I != E; ++I) { + if (PrintedArg) FunctionInnards << ", "; printType(FunctionInnards, *I); + PrintedArg = true; } } // Finish printing arguments... if this is a vararg function, print the ..., // unless there are no known types, in which case, we just emit (). // - if (FT->isVarArg() && FT->getNumParams()) { - if (FT->getNumParams()) FunctionInnards << ", "; + if (FT->isVarArg() && PrintedArg) { + if (PrintedArg) FunctionInnards << ", "; FunctionInnards << "..."; // Output varargs portion of signature! - } else if (!FT->isVarArg() && FT->getNumParams() == 0) { + } else if (!FT->isVarArg() && !PrintedArg) { FunctionInnards << "void"; // ret() -> ret(void) in C. } FunctionInnards << ')'; - // Print out the return type and the entire signature for that matter - printType(Out, F->getReturnType(), FunctionInnards.str()); + + // Get the return tpe for the function. + const Type *RetTy; + if (!isCStructReturn) + RetTy = F->getReturnType(); + else { + // If this is a struct-return function, print the struct-return type. + RetTy = cast(FT->getParamType(0))->getElementType(); + } + + // Print out the return type and the signature built above. + printType(Out, RetTy, FunctionInnards.str()); } void CWriter::printFunction(Function &F) { printFunctionSignature(&F, false); Out << " {\n"; + + // If this is a struct return function, handle the result with magic. + if (F.getCallingConv() == CallingConv::CSRet) { + const Type *StructTy = + cast(F.arg_begin()->getType())->getElementType(); + Out << " "; + printType(Out, StructTy, "StructReturn"); + Out << "; /* Struct return temporary */\n"; + + Out << " "; + printType(Out, F.arg_begin()->getType(), Mang->getValueName(F.arg_begin())); + Out << " = &StructReturn;\n"; + } + bool PrintedVar = false; + // print local variable information for the function for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E; ++I) if (const AllocaInst *AI = isDirectAlloca(&*I)) { Out << " "; printType(Out, AI->getAllocatedType(), Mang->getValueName(AI)); Out << "; /* Address-exposed local */\n"; + PrintedVar = true; } else if (I->getType() != Type::VoidTy && !isInlinableInst(*I)) { Out << " "; printType(Out, I->getType(), Mang->getValueName(&*I)); @@ -1293,9 +1371,11 @@ Mang->getValueName(&*I)+"__PHI_TEMPORARY"); Out << ";\n"; } + PrintedVar = true; } - Out << '\n'; + if (PrintedVar) + Out << '\n'; if (F.hasExternalLinkage() && F.getName() == "main") Out << " CODE_FOR_MAIN();\n"; @@ -1366,6 +1446,12 @@ // necessary because we use the instruction classes as opaque types... // void CWriter::visitReturnInst(ReturnInst &I) { + // If this is a struct return function, return the temporary struct. + if (I.getParent()->getParent()->getCallingConv() == CallingConv::CSRet) { + Out << " return StructReturn;\n"; + return; + } + // Don't output a void return if this is the last basic block in the function if (I.getNumOperands() == 0 && &*--I.getParent()->getParent()->end() == I.getParent() && @@ -1729,70 +1815,80 @@ Value *Callee = I.getCalledValue(); - // GCC is really a PITA. It does not permit codegening casts of functions to - // function pointers if they are in a call (it generates a trap instruction - // instead!). We work around this by inserting a cast to void* in between the - // function and the function pointer cast. Unfortunately, we can't just form - // the constant expression here, because the folder will immediately nuke it. - // - // Note finally, that this is completely unsafe. ANSI C does not guarantee - // that void* and function pointers have the same size. :( To deal with this - // in the common case, we handle casts where the number of arguments passed - // match exactly. - // + // If this is a call to a struct-return function, assign to the first + // parameter instead of passing it to the call. + bool isStructRet = I.getCallingConv() == CallingConv::CSRet; + if (isStructRet) { + Out << "*("; + writeOperand(I.getOperand(1)); + Out << ") = "; + } + if (I.isTailCall()) Out << " /*tail*/ "; - if (ConstantExpr *CE = dyn_cast(Callee)) - if (CE->getOpcode() == Instruction::Cast) - if (Function *RF = dyn_cast(CE->getOperand(0))) { - const FunctionType *RFTy = RF->getFunctionType(); - if (RFTy->getNumParams() == I.getNumOperands()-1) { - // If the call site expects a value, and the actual callee doesn't - // provide one, return 0. - if (I.getType() != Type::VoidTy && - RFTy->getReturnType() == Type::VoidTy) - Out << "0 /*actual callee doesn't return value*/; "; - Callee = RF; - } else { - // Ok, just cast the pointer type. - Out << "(("; - printType(Out, CE->getType()); - Out << ")(void*)"; - printConstant(RF); - Out << ')'; - WroteCallee = true; - } - } const PointerType *PTy = cast(Callee->getType()); const FunctionType *FTy = cast(PTy->getElementType()); - const Type *RetTy = FTy->getReturnType(); + + if (!WroteCallee) { + // If this is an indirect call to a struct return function, we need to cast + // the pointer. + bool NeedsCast = isStructRet && !isa(Callee); + + // GCC is a real PITA. It does not permit codegening casts of functions to + // function pointers if they are in a call (it generates a trap instruction + // instead!). We work around this by inserting a cast to void* in between + // the function and the function pointer cast. Unfortunately, we can't just + // form the constant expression here, because the folder will immediately + // nuke it. + // + // Note finally, that this is completely unsafe. ANSI C does not guarantee + // that void* and function pointers have the same size. :( To deal with this + // in the common case, we handle casts where the number of arguments passed + // match exactly. + // + if (ConstantExpr *CE = dyn_cast(Callee)) + if (CE->getOpcode() == Instruction::Cast) + if (Function *RF = dyn_cast(CE->getOperand(0))) { + NeedsCast = true; + Callee = RF; + } + + if (NeedsCast) { + // Ok, just cast the pointer type. + Out << "(("; + if (!isStructRet) + printType(Out, I.getCalledValue()->getType()); + else + printStructReturnPointerFunctionType(Out, + cast(I.getCalledValue()->getType())); + Out << ")(void*)"; + } + writeOperand(Callee); + if (NeedsCast) Out << ')'; + } - if (!WroteCallee) writeOperand(Callee); Out << '('; unsigned NumDeclaredParams = FTy->getNumParams(); - if (I.getNumOperands() != 1) { - CallSite::arg_iterator AI = I.op_begin()+1, AE = I.op_end(); - if (NumDeclaredParams && (*AI)->getType() != FTy->getParamType(0)) { + CallSite::arg_iterator AI = I.op_begin()+1, AE = I.op_end(); + unsigned ArgNo = 0; + if (isStructRet) { // Skip struct return argument. + ++AI; + ++ArgNo; + } + + bool PrintedArg = false; + for (; AI != AE; ++AI, ++ArgNo) { + if (PrintedArg) Out << ", "; + if (ArgNo < NumDeclaredParams && + (*AI)->getType() != FTy->getParamType(ArgNo)) { Out << '('; - printType(Out, FTy->getParamType(0)); + printType(Out, FTy->getParamType(ArgNo)); Out << ')'; } - writeOperand(*AI); - - unsigned ArgNo; - for (ArgNo = 1, ++AI; AI != AE; ++AI, ++ArgNo) { - Out << ", "; - if (ArgNo < NumDeclaredParams && - (*AI)->getType() != FTy->getParamType(ArgNo)) { - Out << '('; - printType(Out, FTy->getParamType(ArgNo)); - Out << ')'; - } - writeOperand(*AI); - } + PrintedArg = true; } Out << ')'; } From lattner at cs.uiuc.edu Tue May 23 19:06:57 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 23 May 2006 19:06:57 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp Message-ID: <200605240006.TAA03979@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelLowering.cpp updated: 1.180 -> 1.181 --- Log message: Handle SETO* like we handle SET*, restoring behavior after Evan's setcc change. This fixes PowerPC/fnegsel.ll. --- Diffs of the changes: (+8 -0) PPCISelLowering.cpp | 8 ++++++++ 1 files changed, 8 insertions(+) Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.180 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.181 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.180 Wed May 17 14:00:46 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Tue May 23 19:06:44 2006 @@ -1216,17 +1216,21 @@ switch (CC) { default: break; // SETUO etc aren't handled by fsel. case ISD::SETULT: + case ISD::SETOLT: case ISD::SETLT: std::swap(TV, FV); // fsel is natively setge, swap operands for setlt case ISD::SETUGE: + case ISD::SETOGE: case ISD::SETGE: if (LHS.getValueType() == MVT::f32) // Comparison is always 64-bits LHS = DAG.getNode(ISD::FP_EXTEND, MVT::f64, LHS); return DAG.getNode(PPCISD::FSEL, ResVT, LHS, TV, FV); case ISD::SETUGT: + case ISD::SETOGT: case ISD::SETGT: std::swap(TV, FV); // fsel is natively setge, swap operands for setlt case ISD::SETULE: + case ISD::SETOLE: case ISD::SETLE: if (LHS.getValueType() == MVT::f32) // Comparison is always 64-bits LHS = DAG.getNode(ISD::FP_EXTEND, MVT::f64, LHS); @@ -1238,24 +1242,28 @@ switch (CC) { default: break; // SETUO etc aren't handled by fsel. case ISD::SETULT: + case ISD::SETOLT: case ISD::SETLT: Cmp = DAG.getNode(ISD::FSUB, CmpVT, LHS, RHS); if (Cmp.getValueType() == MVT::f32) // Comparison is always 64-bits Cmp = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Cmp); return DAG.getNode(PPCISD::FSEL, ResVT, Cmp, FV, TV); case ISD::SETUGE: + case ISD::SETOGE: case ISD::SETGE: Cmp = DAG.getNode(ISD::FSUB, CmpVT, LHS, RHS); if (Cmp.getValueType() == MVT::f32) // Comparison is always 64-bits Cmp = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Cmp); return DAG.getNode(PPCISD::FSEL, ResVT, Cmp, TV, FV); case ISD::SETUGT: + case ISD::SETOGT: case ISD::SETGT: Cmp = DAG.getNode(ISD::FSUB, CmpVT, RHS, LHS); if (Cmp.getValueType() == MVT::f32) // Comparison is always 64-bits Cmp = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Cmp); return DAG.getNode(PPCISD::FSEL, ResVT, Cmp, FV, TV); case ISD::SETULE: + case ISD::SETOLE: case ISD::SETLE: Cmp = DAG.getNode(ISD::FSUB, CmpVT, RHS, LHS); if (Cmp.getValueType() == MVT::f32) // Comparison is always 64-bits From lattner at cs.uiuc.edu Tue May 23 19:13:02 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 23 May 2006 19:13:02 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/Generic/vector.ll Message-ID: <200605240013.TAA04063@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/Generic: vector.ll updated: 1.10 -> 1.11 --- Log message: New testcase --- Diffs of the changes: (+9 -0) vector.ll | 9 +++++++++ 1 files changed, 9 insertions(+) Index: llvm/test/Regression/CodeGen/Generic/vector.ll diff -u llvm/test/Regression/CodeGen/Generic/vector.ll:1.10 llvm/test/Regression/CodeGen/Generic/vector.ll:1.11 --- llvm/test/Regression/CodeGen/Generic/vector.ll:1.10 Thu Apr 13 12:10:03 2006 +++ llvm/test/Regression/CodeGen/Generic/vector.ll Tue May 23 19:12:50 2006 @@ -56,6 +56,15 @@ store %f8 %R, %f8 *%S ret void } + +void %test_div(%f8 *%P, %f8* %Q, %f8 *%S) { + %p = load %f8* %P + %q = load %f8* %Q + %R = div %f8 %p, %q + store %f8 %R, %f8 *%S + ret void +} + ;;; TEST VECTOR CONSTRUCTS void %test_cst(%f4 *%P, %f4 *%S) { From lattner at cs.uiuc.edu Tue May 23 19:15:37 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 23 May 2006 19:15:37 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp Message-ID: <200605240015.TAA04306@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelLowering.cpp updated: 1.181 -> 1.182 --- Log message: Fix CodeGen/Generic/vector.ll:test_div with altivec. --- Diffs of the changes: (+1 -0) PPCISelLowering.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.181 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.182 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.181 Tue May 23 19:06:44 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Tue May 23 19:15:25 2006 @@ -208,6 +208,7 @@ setOperationAction(ISD::SREM, (MVT::ValueType)VT, Expand); setOperationAction(ISD::UDIV, (MVT::ValueType)VT, Expand); setOperationAction(ISD::UREM, (MVT::ValueType)VT, Expand); + setOperationAction(ISD::FDIV, (MVT::ValueType)VT, Expand); setOperationAction(ISD::EXTRACT_VECTOR_ELT, (MVT::ValueType)VT, Expand); setOperationAction(ISD::INSERT_VECTOR_ELT, (MVT::ValueType)VT, Expand); setOperationAction(ISD::BUILD_VECTOR, (MVT::ValueType)VT, Expand); From lattner at cs.uiuc.edu Tue May 23 19:49:44 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 23 May 2006 19:49:44 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/fabs.ll Message-ID: <200605240049.TAA04445@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: fabs.ll updated: 1.7 -> 1.8 --- Log message: One of these xforms is only safe with unsafe math enabled. --- Diffs of the changes: (+2 -1) fabs.ll | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/test/Regression/CodeGen/X86/fabs.ll diff -u llvm/test/Regression/CodeGen/X86/fabs.ll:1.7 llvm/test/Regression/CodeGen/X86/fabs.ll:1.8 --- llvm/test/Regression/CodeGen/X86/fabs.ll:1.7 Wed Mar 15 12:05:13 2006 +++ llvm/test/Regression/CodeGen/X86/fabs.ll Tue May 23 19:49:32 2006 @@ -1,5 +1,6 @@ ; Make sure this testcase codegens to the fabs instruction, not a call to fabsf -; RUN: llvm-as < %s | llc -march=x86 -mattr=-sse2,-sse3 | grep 'fabs$' | wc -l | grep 2 +; RUN: llvm-as < %s | llc -march=x86 -mattr=-sse2,-sse3 | grep 'fabs$' | wc -l | grep 1 && +; RUN: llvm-as < %s | llc -march=x86 -mattr=-sse2,-sse3 -enable-unsafe-fp-math | grep 'fabs$' | wc -l | grep 2 declare float %fabsf(float) From lattner at cs.uiuc.edu Wed May 24 12:04:33 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 24 May 2006 12:04:33 -0500 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200605241704.MAA22685@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.245 -> 1.246 --- Log message: Patches to make the LLVM sources more -pedantic clean. Patch provided by Anton Korobeynikov! This is a step towards closing PR786: http://llvm.cs.uiuc.edu/PR786 . --- Diffs of the changes: (+1 -1) DataStructure.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.245 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.246 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.245 Wed Apr 19 10:34:34 2006 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Wed May 24 12:04:03 2006 @@ -43,7 +43,7 @@ DSAFieldLimit("dsa-field-limit", cl::Hidden, cl::desc("Number of fields to track before collapsing a node"), cl::init(256)); -}; +} #if 0 #define TIME_REGION(VARNAME, DESC) \ From lattner at cs.uiuc.edu Wed May 24 12:04:33 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 24 May 2006 12:04:33 -0500 Subject: [llvm-commits] CVS: llvm/tools/llvm-ar/llvm-ar.cpp Message-ID: <200605241704.MAA22686@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-ar: llvm-ar.cpp updated: 1.30 -> 1.31 --- Log message: Patches to make the LLVM sources more -pedantic clean. Patch provided by Anton Korobeynikov! This is a step towards closing PR786: http://llvm.cs.uiuc.edu/PR786 . --- Diffs of the changes: (+1 -1) llvm-ar.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/tools/llvm-ar/llvm-ar.cpp diff -u llvm/tools/llvm-ar/llvm-ar.cpp:1.30 llvm/tools/llvm-ar/llvm-ar.cpp:1.31 --- llvm/tools/llvm-ar/llvm-ar.cpp:1.30 Wed Dec 28 00:56:09 2005 +++ llvm/tools/llvm-ar/llvm-ar.cpp Wed May 24 12:04:04 2006 @@ -80,7 +80,7 @@ QuickAppend, ///< Quickly append to end of archive ReplaceOrInsert, ///< Replace or Insert members DisplayTable, ///< Display the table of contents - Extract, ///< Extract files back to file system + Extract ///< Extract files back to file system }; // Modifiers to follow operation to vary behavior From lattner at cs.uiuc.edu Wed May 24 12:04:34 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 24 May 2006 12:04:34 -0500 Subject: [llvm-commits] CVS: llvm/tools/llvmc/CompilerDriver.h ConfigLexer.h ConfigLexer.l ConfigLexer.l.cvs Message-ID: <200605241704.MAA22711@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvmc: CompilerDriver.h updated: 1.18 -> 1.19 ConfigLexer.h updated: 1.13 -> 1.14 ConfigLexer.l updated: 1.13 -> 1.14 ConfigLexer.l.cvs updated: 1.1 -> 1.2 --- Log message: Patches to make the LLVM sources more -pedantic clean. Patch provided by Anton Korobeynikov! This is a step towards closing PR786: http://llvm.cs.uiuc.edu/PR786 . --- Diffs of the changes: (+5 -5) CompilerDriver.h | 4 ++-- ConfigLexer.h | 2 +- ConfigLexer.l | 2 +- ConfigLexer.l.cvs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) Index: llvm/tools/llvmc/CompilerDriver.h diff -u llvm/tools/llvmc/CompilerDriver.h:1.18 llvm/tools/llvmc/CompilerDriver.h:1.19 --- llvm/tools/llvmc/CompilerDriver.h:1.18 Wed May 18 19:52:29 2005 +++ llvm/tools/llvmc/CompilerDriver.h Wed May 24 12:04:05 2006 @@ -65,7 +65,7 @@ PREPROCESSES_FLAG = 0x0002, ///< Does this action preprocess? TRANSLATES_FLAG = 0x0004, ///< Does this action translate? OUTPUT_IS_ASM_FLAG = 0x0008, ///< Action produces .ll files? - FLAGS_MASK = 0x000F, ///< Union of all flags + FLAGS_MASK = 0x000F ///< Union of all flags }; /// This type is the input list to the CompilerDriver. It provides @@ -131,7 +131,7 @@ EMIT_RAW_FLAG = 0x0080, ///< Emit raw, unoptimized bytecode KEEP_TEMPS_FLAG = 0x0100, ///< Don't delete temporary files STRIP_OUTPUT_FLAG = 0x0200, ///< Strip symbols from linked output - DRIVER_FLAGS_MASK = 0x03FF, ///< Union of the above flags + DRIVER_FLAGS_MASK = 0x03FF ///< Union of the above flags }; /// @} Index: llvm/tools/llvmc/ConfigLexer.h diff -u llvm/tools/llvmc/ConfigLexer.h:1.13 llvm/tools/llvmc/ConfigLexer.h:1.14 --- llvm/tools/llvmc/ConfigLexer.h:1.13 Wed May 18 19:52:29 2005 +++ llvm/tools/llvmc/ConfigLexer.h Wed May 24 12:04:05 2006 @@ -102,7 +102,7 @@ TRUETOK, ///< A boolean true value (true/yes/on) VERBOSE_SUBST, ///< The substitution item %verbose% VERSION_TOK, ///< The name "version" (and variants) - WOPTS_SUBST, ///< The %WOpts% substitution + WOPTS_SUBST ///< The %WOpts% substitution }; extern ConfigLexerTokens Configlex(); Index: llvm/tools/llvmc/ConfigLexer.l diff -u llvm/tools/llvmc/ConfigLexer.l:1.13 llvm/tools/llvmc/ConfigLexer.l:1.14 --- llvm/tools/llvmc/ConfigLexer.l:1.13 Wed May 18 19:52:29 2005 +++ llvm/tools/llvmc/ConfigLexer.l Wed May 24 12:04:05 2006 @@ -64,7 +64,7 @@ } YY_FATAL_ERROR("Substitition tokens not allowed in names" ); return ERRORTOK; -}; +} inline llvm::ConfigLexerTokens handleValueContext(llvm::ConfigLexerTokens token) { ConfigLexerState.StringVal = yytext; Index: llvm/tools/llvmc/ConfigLexer.l.cvs diff -u llvm/tools/llvmc/ConfigLexer.l.cvs:1.1 llvm/tools/llvmc/ConfigLexer.l.cvs:1.2 --- llvm/tools/llvmc/ConfigLexer.l.cvs:1.1 Mon Feb 13 23:16:35 2006 +++ llvm/tools/llvmc/ConfigLexer.l.cvs Wed May 24 12:04:05 2006 @@ -64,7 +64,7 @@ } YY_FATAL_ERROR("Substitition tokens not allowed in names" ); return ERRORTOK; -}; +} inline llvm::ConfigLexerTokens handleValueContext(llvm::ConfigLexerTokens token) { ConfigLexerState.StringVal = yytext; From lattner at cs.uiuc.edu Wed May 24 12:04:33 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 24 May 2006 12:04:33 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelLowering.h AlphaRelocations.h Message-ID: <200605241704.MAA22691@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelLowering.h updated: 1.15 -> 1.16 AlphaRelocations.h updated: 1.2 -> 1.3 --- Log message: Patches to make the LLVM sources more -pedantic clean. Patch provided by Anton Korobeynikov! This is a step towards closing PR786: http://llvm.cs.uiuc.edu/PR786 . --- Diffs of the changes: (+2 -2) AlphaISelLowering.h | 2 +- AlphaRelocations.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/Alpha/AlphaISelLowering.h diff -u llvm/lib/Target/Alpha/AlphaISelLowering.h:1.15 llvm/lib/Target/Alpha/AlphaISelLowering.h:1.16 --- llvm/lib/Target/Alpha/AlphaISelLowering.h:1.15 Thu Mar 9 11:16:45 2006 +++ llvm/lib/Target/Alpha/AlphaISelLowering.h Wed May 24 12:04:04 2006 @@ -42,7 +42,7 @@ CALL, /// DIVCALL - used for special library calls for div and rem - DivCall, + DivCall }; } Index: llvm/lib/Target/Alpha/AlphaRelocations.h diff -u llvm/lib/Target/Alpha/AlphaRelocations.h:1.2 llvm/lib/Target/Alpha/AlphaRelocations.h:1.3 --- llvm/lib/Target/Alpha/AlphaRelocations.h:1.2 Thu Jul 28 13:14:47 2005 +++ llvm/lib/Target/Alpha/AlphaRelocations.h Wed May 24 12:04:04 2006 @@ -23,7 +23,7 @@ reloc_gprellow, reloc_gprelhigh, reloc_gpdist, - reloc_bsr, + reloc_bsr }; } } From lattner at cs.uiuc.edu Wed May 24 12:04:35 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 24 May 2006 12:04:35 -0500 Subject: [llvm-commits] CVS: llvm/lib/Support/Compressor.cpp IsInf.cpp IsNAN.cpp Message-ID: <200605241704.MAA22755@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: Compressor.cpp updated: 1.19 -> 1.20 IsInf.cpp updated: 1.7 -> 1.8 IsNAN.cpp updated: 1.4 -> 1.5 --- Log message: Patches to make the LLVM sources more -pedantic clean. Patch provided by Anton Korobeynikov! This is a step towards closing PR786: http://llvm.cs.uiuc.edu/PR786 . --- Diffs of the changes: (+3 -3) Compressor.cpp | 2 +- IsInf.cpp | 2 +- IsNAN.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/lib/Support/Compressor.cpp diff -u llvm/lib/Support/Compressor.cpp:1.19 llvm/lib/Support/Compressor.cpp:1.20 --- llvm/lib/Support/Compressor.cpp:1.19 Wed Jul 27 01:12:33 2005 +++ llvm/lib/Support/Compressor.cpp Wed May 24 12:04:04 2006 @@ -23,7 +23,7 @@ enum CompressionTypes { COMP_TYPE_NONE = '0', - COMP_TYPE_BZIP2 = '2', + COMP_TYPE_BZIP2 = '2' }; static int getdata(char*& buffer, size_t &size, Index: llvm/lib/Support/IsInf.cpp diff -u llvm/lib/Support/IsInf.cpp:1.7 llvm/lib/Support/IsInf.cpp:1.8 --- llvm/lib/Support/IsInf.cpp:1.7 Mon May 16 01:45:57 2005 +++ llvm/lib/Support/IsInf.cpp Wed May 24 12:04:04 2006 @@ -42,4 +42,4 @@ int IsInf (float f) { return isinf (f); } int IsInf (double d) { return isinf (d); } -}; // end namespace llvm; +} // end namespace llvm; Index: llvm/lib/Support/IsNAN.cpp diff -u llvm/lib/Support/IsNAN.cpp:1.4 llvm/lib/Support/IsNAN.cpp:1.5 --- llvm/lib/Support/IsNAN.cpp:1.4 Thu Apr 21 17:52:05 2005 +++ llvm/lib/Support/IsNAN.cpp Wed May 24 12:04:04 2006 @@ -31,4 +31,4 @@ int IsNAN (float f) { return isnan (f); } int IsNAN (double d) { return isnan (d); } -}; // end namespace llvm; +} // end namespace llvm; From lattner at cs.uiuc.edu Wed May 24 12:04:35 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 24 May 2006 12:04:35 -0500 Subject: [llvm-commits] CVS: llvm/tools/llvm-nm/llvm-nm.cpp Message-ID: <200605241704.MAA22749@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-nm: llvm-nm.cpp updated: 1.25 -> 1.26 --- Log message: Patches to make the LLVM sources more -pedantic clean. Patch provided by Anton Korobeynikov! This is a step towards closing PR786: http://llvm.cs.uiuc.edu/PR786 . --- Diffs of the changes: (+1 -1) llvm-nm.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/tools/llvm-nm/llvm-nm.cpp diff -u llvm/tools/llvm-nm/llvm-nm.cpp:1.25 llvm/tools/llvm-nm/llvm-nm.cpp:1.26 --- llvm/tools/llvm-nm/llvm-nm.cpp:1.25 Thu Jul 7 13:21:42 2005 +++ llvm/tools/llvm-nm/llvm-nm.cpp Wed May 24 12:04:04 2006 @@ -63,7 +63,7 @@ bool MultipleFiles = false; std::string ToolName; -}; +} char TypeCharForSymbol (GlobalValue &GV) { if (GV.isExternal ()) return 'U'; From lattner at cs.uiuc.edu Wed May 24 12:04:34 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 24 May 2006 12:04:34 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp X86ISelLowering.h X86InstrBuilder.h X86InstrInfo.h X86JITInfo.cpp X86Relocations.h Message-ID: <200605241704.MAA22727@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelDAGToDAG.cpp updated: 1.66 -> 1.67 X86ISelLowering.h updated: 1.64 -> 1.65 X86InstrBuilder.h updated: 1.20 -> 1.21 X86InstrInfo.h updated: 1.51 -> 1.52 X86JITInfo.cpp updated: 1.18 -> 1.19 X86Relocations.h updated: 1.2 -> 1.3 --- Log message: Patches to make the LLVM sources more -pedantic clean. Patch provided by Anton Korobeynikov! This is a step towards closing PR786: http://llvm.cs.uiuc.edu/PR786 . --- Diffs of the changes: (+6 -6) X86ISelDAGToDAG.cpp | 2 +- X86ISelLowering.h | 2 +- X86InstrBuilder.h | 2 +- X86InstrInfo.h | 2 +- X86JITInfo.cpp | 2 +- X86Relocations.h | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.66 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.67 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.66 Sun May 21 01:28:50 2006 +++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Wed May 24 12:04:04 2006 @@ -47,7 +47,7 @@ struct X86ISelAddressMode { enum { RegBase, - FrameIndexBase, + FrameIndexBase } BaseType; struct { // This is really a union, discriminated by BaseType! Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.64 llvm/lib/Target/X86/X86ISelLowering.h:1.65 --- llvm/lib/Target/X86/X86ISelLowering.h:1.64 Tue May 23 16:06:34 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Wed May 24 12:04:04 2006 @@ -156,7 +156,7 @@ /// PINSRW - Insert the lower 16-bits of a 32-bit value to a vector, /// corresponds to X86::PINSRW. - PINSRW, + PINSRW }; // X86 specific condition code. These correspond to X86_*_COND in Index: llvm/lib/Target/X86/X86InstrBuilder.h diff -u llvm/lib/Target/X86/X86InstrBuilder.h:1.20 llvm/lib/Target/X86/X86InstrBuilder.h:1.21 --- llvm/lib/Target/X86/X86InstrBuilder.h:1.20 Thu May 4 13:16:01 2006 +++ llvm/lib/Target/X86/X86InstrBuilder.h Wed May 24 12:04:04 2006 @@ -35,7 +35,7 @@ struct X86AddressMode { enum { RegBase, - FrameIndexBase, + FrameIndexBase } BaseType; union { Index: llvm/lib/Target/X86/X86InstrInfo.h diff -u llvm/lib/Target/X86/X86InstrInfo.h:1.51 llvm/lib/Target/X86/X86InstrInfo.h:1.52 --- llvm/lib/Target/X86/X86InstrInfo.h:1.51 Thu May 18 01:27:15 2006 +++ llvm/lib/Target/X86/X86InstrInfo.h Wed May 24 12:04:04 2006 @@ -162,7 +162,7 @@ SpecialFP = 7 << FPTypeShift, OpcodeShift = 16, - OpcodeMask = 0xFF << OpcodeShift, + OpcodeMask = 0xFF << OpcodeShift // Bits 25 -> 31 are unused }; } Index: llvm/lib/Target/X86/X86JITInfo.cpp diff -u llvm/lib/Target/X86/X86JITInfo.cpp:1.18 llvm/lib/Target/X86/X86JITInfo.cpp:1.19 --- llvm/lib/Target/X86/X86JITInfo.cpp:1.18 Tue May 2 14:14:47 2006 +++ llvm/lib/Target/X86/X86JITInfo.cpp Wed May 24 12:04:04 2006 @@ -167,7 +167,7 @@ } void *X86JITInfo::emitFunctionStub(void *Fn, MachineCodeEmitter &MCE) { - if (Fn != X86CompilationCallback) { + if (Fn != (void*)X86CompilationCallback) { MCE.startFunctionStub(5); MCE.emitByte(0xE9); MCE.emitWordLE((intptr_t)Fn-MCE.getCurrentPCValue()-4); Index: llvm/lib/Target/X86/X86Relocations.h diff -u llvm/lib/Target/X86/X86Relocations.h:1.2 llvm/lib/Target/X86/X86Relocations.h:1.3 --- llvm/lib/Target/X86/X86Relocations.h:1.2 Thu Apr 21 18:38:14 2005 +++ llvm/lib/Target/X86/X86Relocations.h Wed May 24 12:04:04 2006 @@ -25,7 +25,7 @@ // reloc_absolute_word - Absolute relocation, just add the relocated value // to the value already in memory. - reloc_absolute_word = 1, + reloc_absolute_word = 1 }; } } From lattner at cs.uiuc.edu Wed May 24 12:04:34 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 24 May 2006 12:04:34 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200605241704.MAA22701@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.377 -> 1.378 --- Log message: Patches to make the LLVM sources more -pedantic clean. Patch provided by Anton Korobeynikov! This is a step towards closing PR786: http://llvm.cs.uiuc.edu/PR786 . --- Diffs of the changes: (+1 -1) LegalizeDAG.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.377 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.378 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.377 Wed May 17 13:00:08 2006 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed May 24 12:04:04 2006 @@ -65,7 +65,7 @@ enum LegalizeAction { Legal, // The target natively supports this operation. Promote, // This operation should be executed in a larger type. - Expand, // Try to expand this to other ops, otherwise use a libcall. + Expand // Try to expand this to other ops, otherwise use a libcall. }; /// ValueTypeActions - This is a bitvector that contains two bits for each From lattner at cs.uiuc.edu Wed May 24 12:04:33 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 24 May 2006 12:04:33 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineInstr.h ScheduleDAG.h Message-ID: <200605241704.MAA22687@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineInstr.h updated: 1.181 -> 1.182 ScheduleDAG.h updated: 1.26 -> 1.27 --- Log message: Patches to make the LLVM sources more -pedantic clean. Patch provided by Anton Korobeynikov! This is a step towards closing PR786: http://llvm.cs.uiuc.edu/PR786 . --- Diffs of the changes: (+2 -2) MachineInstr.h | 2 +- ScheduleDAG.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/include/llvm/CodeGen/MachineInstr.h diff -u llvm/include/llvm/CodeGen/MachineInstr.h:1.181 llvm/include/llvm/CodeGen/MachineInstr.h:1.182 --- llvm/include/llvm/CodeGen/MachineInstr.h:1.181 Thu May 4 14:36:09 2006 +++ llvm/include/llvm/CodeGen/MachineInstr.h Wed May 24 12:04:03 2006 @@ -42,7 +42,7 @@ // Bit fields of the flags variable used for different operand properties enum { DEFFLAG = 0x01, // this is a def of the operand - USEFLAG = 0x02, // this is a use of the operand + USEFLAG = 0x02 // this is a use of the operand }; public: Index: llvm/include/llvm/CodeGen/ScheduleDAG.h diff -u llvm/include/llvm/CodeGen/ScheduleDAG.h:1.26 llvm/include/llvm/CodeGen/ScheduleDAG.h:1.27 --- llvm/include/llvm/CodeGen/ScheduleDAG.h:1.26 Sat May 13 00:53:16 2006 +++ llvm/include/llvm/CodeGen/ScheduleDAG.h Wed May 24 12:04:03 2006 @@ -41,7 +41,7 @@ enum HazardType { NoHazard, // This instruction can be emitted at this cycle. Hazard, // This instruction can't be emitted at this cycle. - NoopHazard, // This instruction can't be emitted, and needs noops. + NoopHazard // This instruction can't be emitted, and needs noops. }; /// getHazardType - Return the hazard type of emitting this node. There are From lattner at cs.uiuc.edu Wed May 24 12:04:34 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 24 May 2006 12:04:34 -0500 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/Andersens.cpp Message-ID: <200605241704.MAA22729@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: Andersens.cpp updated: 1.27 -> 1.28 --- Log message: Patches to make the LLVM sources more -pedantic clean. Patch provided by Anton Korobeynikov! This is a step towards closing PR786: http://llvm.cs.uiuc.edu/PR786 . --- Diffs of the changes: (+1 -1) Andersens.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Analysis/IPA/Andersens.cpp diff -u llvm/lib/Analysis/IPA/Andersens.cpp:1.27 llvm/lib/Analysis/IPA/Andersens.cpp:1.28 --- llvm/lib/Analysis/IPA/Andersens.cpp:1.27 Thu Mar 2 19:21:36 2006 +++ llvm/lib/Analysis/IPA/Andersens.cpp Wed May 24 12:04:04 2006 @@ -192,7 +192,7 @@ enum { UniversalSet = 0, NullPtr = 1, - NullObject = 2, + NullObject = 2 }; public: From lattner at cs.uiuc.edu Wed May 24 12:04:35 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 24 May 2006 12:04:35 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp PPCInstrInfo.h PPCJITInfo.cpp PPCRelocations.h Message-ID: <200605241704.MAA22785@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelLowering.cpp updated: 1.182 -> 1.183 PPCInstrInfo.h updated: 1.14 -> 1.15 PPCJITInfo.cpp updated: 1.21 -> 1.22 PPCRelocations.h updated: 1.6 -> 1.7 --- Log message: Patches to make the LLVM sources more -pedantic clean. Patch provided by Anton Korobeynikov! This is a step towards closing PR786: http://llvm.cs.uiuc.edu/PR786 . --- Diffs of the changes: (+5 -5) PPCISelLowering.cpp | 2 +- PPCInstrInfo.h | 4 ++-- PPCJITInfo.cpp | 2 +- PPCRelocations.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.182 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.183 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.182 Tue May 23 19:15:25 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Wed May 24 12:04:04 2006 @@ -1748,7 +1748,7 @@ OP_VSPLTISW3, OP_VSLDOI4, OP_VSLDOI8, - OP_VSLDOI12, + OP_VSLDOI12 }; if (OpNum == OP_COPY) { Index: llvm/lib/Target/PowerPC/PPCInstrInfo.h diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.h:1.14 llvm/lib/Target/PowerPC/PPCInstrInfo.h:1.15 --- llvm/lib/Target/PowerPC/PPCInstrInfo.h:1.14 Sun Mar 12 23:15:10 2006 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.h Wed May 24 12:04:04 2006 @@ -44,7 +44,7 @@ /// PPC970_Mask/Shift - This is a bitmask that selects the pipeline type that /// an instruction is issued to. PPC970_Shift = 3, - PPC970_Mask = 0x07 << PPC970_Shift, + PPC970_Mask = 0x07 << PPC970_Shift }; enum PPC970_Unit { /// These are the various PPC970 execution unit pipelines. Each instruction @@ -56,7 +56,7 @@ PPC970_CRU = 4 << PPC970_Shift, // Control Register Unit PPC970_VALU = 5 << PPC970_Shift, // Vector ALU PPC970_VPERM = 6 << PPC970_Shift, // Vector Permute Unit - PPC970_BRU = 7 << PPC970_Shift, // Branch Unit + PPC970_BRU = 7 << PPC970_Shift // Branch Unit }; } Index: llvm/lib/Target/PowerPC/PPCJITInfo.cpp diff -u llvm/lib/Target/PowerPC/PPCJITInfo.cpp:1.21 llvm/lib/Target/PowerPC/PPCJITInfo.cpp:1.22 --- llvm/lib/Target/PowerPC/PPCJITInfo.cpp:1.21 Tue May 2 14:14:47 2006 +++ llvm/lib/Target/PowerPC/PPCJITInfo.cpp Wed May 24 12:04:04 2006 @@ -165,7 +165,7 @@ void *PPCJITInfo::emitFunctionStub(void *Fn, MachineCodeEmitter &MCE) { // If this is just a call to an external function, emit a branch instead of a // call. The code is the same except for one bit of the last instruction. - if (Fn != PPC32CompilationCallback) { + if (Fn != (void*)PPC32CompilationCallback) { MCE.startFunctionStub(4*4); void *Addr = (void*)(intptr_t)MCE.getCurrentPCValue(); MCE.emitWordBE(0); Index: llvm/lib/Target/PowerPC/PPCRelocations.h diff -u llvm/lib/Target/PowerPC/PPCRelocations.h:1.6 llvm/lib/Target/PowerPC/PPCRelocations.h:1.7 --- llvm/lib/Target/PowerPC/PPCRelocations.h:1.6 Sun Oct 16 00:39:50 2005 +++ llvm/lib/Target/PowerPC/PPCRelocations.h Wed May 24 12:04:04 2006 @@ -50,7 +50,7 @@ // relocated to point to a POINTER to the indicated global. The low-16 // bits of the instruction are rewritten with the low 16-bits of the // address of the pointer. - reloc_absolute_ptr_low, + reloc_absolute_ptr_low }; } } From lattner at cs.uiuc.edu Wed May 24 12:04:35 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 24 May 2006 12:04:35 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp TwoAddressInstructionPass.cpp Message-ID: <200605241704.MAA22744@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveIntervalAnalysis.cpp updated: 1.160 -> 1.161 TwoAddressInstructionPass.cpp updated: 1.33 -> 1.34 --- Log message: Patches to make the LLVM sources more -pedantic clean. Patch provided by Anton Korobeynikov! This is a step towards closing PR786: http://llvm.cs.uiuc.edu/PR786 . --- Diffs of the changes: (+2 -2) LiveIntervalAnalysis.cpp | 2 +- TwoAddressInstructionPass.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.160 llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.161 --- llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.160 Fri May 12 01:06:34 2006 +++ llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Wed May 24 12:04:04 2006 @@ -59,7 +59,7 @@ EnableJoining("join-liveintervals", cl::desc("Join compatible live intervals"), cl::init(true)); -}; +} void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const { Index: llvm/lib/CodeGen/TwoAddressInstructionPass.cpp diff -u llvm/lib/CodeGen/TwoAddressInstructionPass.cpp:1.33 llvm/lib/CodeGen/TwoAddressInstructionPass.cpp:1.34 --- llvm/lib/CodeGen/TwoAddressInstructionPass.cpp:1.33 Thu May 4 12:52:23 2006 +++ llvm/lib/CodeGen/TwoAddressInstructionPass.cpp Wed May 24 12:04:04 2006 @@ -60,7 +60,7 @@ RegisterPass X("twoaddressinstruction", "Two-Address instruction pass"); -}; +} const PassInfo *llvm::TwoAddressInstructionPassID = X.getPassInfo(); From lattner at cs.uiuc.edu Wed May 24 12:04:35 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 24 May 2006 12:04:35 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/Sparc.h SparcISelDAGToDAG.cpp SparcInstrInfo.h SparcSubtarget.cpp Message-ID: <200605241704.MAA22733@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: Sparc.h updated: 1.11 -> 1.12 SparcISelDAGToDAG.cpp updated: 1.93 -> 1.94 SparcInstrInfo.h updated: 1.8 -> 1.9 SparcSubtarget.cpp updated: 1.5 -> 1.6 --- Log message: Patches to make the LLVM sources more -pedantic clean. Patch provided by Anton Korobeynikov! This is a step towards closing PR786: http://llvm.cs.uiuc.edu/PR786 . --- Diffs of the changes: (+4 -4) Sparc.h | 2 +- SparcISelDAGToDAG.cpp | 2 +- SparcInstrInfo.h | 2 +- SparcSubtarget.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) Index: llvm/lib/Target/Sparc/Sparc.h diff -u llvm/lib/Target/Sparc/Sparc.h:1.11 llvm/lib/Target/Sparc/Sparc.h:1.12 --- llvm/lib/Target/Sparc/Sparc.h:1.11 Sat Feb 4 23:50:24 2006 +++ llvm/lib/Target/Sparc/Sparc.h Wed May 24 12:04:04 2006 @@ -75,7 +75,7 @@ FCC_UGE = 12+16, // Unordered or Greater or Equal FCC_LE = 13+16, // Less or Equal FCC_ULE = 14+16, // Unordered or Less or Equal - FCC_O = 15+16, // Ordered + FCC_O = 15+16 // Ordered }; } Index: llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp diff -u llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp:1.93 llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp:1.94 --- llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp:1.93 Fri May 12 12:31:21 2006 +++ llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp Wed May 24 12:04:04 2006 @@ -48,7 +48,7 @@ ITOF, // Int to FP within a FP register. CALL, // A call instruction. - RET_FLAG, // Return with a flag operand. + RET_FLAG // Return with a flag operand. }; } Index: llvm/lib/Target/Sparc/SparcInstrInfo.h diff -u llvm/lib/Target/Sparc/SparcInstrInfo.h:1.8 llvm/lib/Target/Sparc/SparcInstrInfo.h:1.9 --- llvm/lib/Target/Sparc/SparcInstrInfo.h:1.8 Sat Feb 4 23:50:24 2006 +++ llvm/lib/Target/Sparc/SparcInstrInfo.h Wed May 24 12:04:04 2006 @@ -29,7 +29,7 @@ Store = (1<<2), DelaySlot = (1<<3) }; -}; +} class SparcInstrInfo : public TargetInstrInfo { const SparcRegisterInfo RI; Index: llvm/lib/Target/Sparc/SparcSubtarget.cpp diff -u llvm/lib/Target/Sparc/SparcSubtarget.cpp:1.5 llvm/lib/Target/Sparc/SparcSubtarget.cpp:1.6 --- llvm/lib/Target/Sparc/SparcSubtarget.cpp:1.5 Sat Feb 4 23:50:24 2006 +++ llvm/lib/Target/Sparc/SparcSubtarget.cpp Wed May 24 12:04:04 2006 @@ -40,4 +40,4 @@ // Unless explicitly enabled, disable the V9 instructions. if (!EnableV9) IsV9 = false; -}; +} From lattner at cs.uiuc.edu Wed May 24 12:04:35 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 24 May 2006 12:04:35 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp Message-ID: <200605241704.MAA22801@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/ARM: ARMISelDAGToDAG.cpp updated: 1.4 -> 1.5 --- Log message: Patches to make the LLVM sources more -pedantic clean. Patch provided by Anton Korobeynikov! This is a step towards closing PR786: http://llvm.cs.uiuc.edu/PR786 . --- Diffs of the changes: (+1 -1) ARMISelDAGToDAG.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp diff -u llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp:1.4 llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp:1.5 --- llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp:1.4 Mon May 22 21:48:20 2006 +++ llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp Wed May 24 12:04:04 2006 @@ -31,7 +31,7 @@ namespace ARMISD { enum { FIRST_NUMBER = ISD::BUILTIN_OP_END+ARM::INSTRUCTION_LIST_END, - RET_FLAG, + RET_FLAG }; } From lattner at cs.uiuc.edu Wed May 24 12:04:35 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 24 May 2006 12:04:35 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetMachine.cpp Message-ID: <200605241704.MAA22778@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetMachine.cpp updated: 1.46 -> 1.47 --- Log message: Patches to make the LLVM sources more -pedantic clean. Patch provided by Anton Korobeynikov! This is a step towards closing PR786: http://llvm.cs.uiuc.edu/PR786 . --- Diffs of the changes: (+2 -2) TargetMachine.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/TargetMachine.cpp diff -u llvm/lib/Target/TargetMachine.cpp:1.46 llvm/lib/Target/TargetMachine.cpp:1.47 --- llvm/lib/Target/TargetMachine.cpp:1.46 Tue May 23 13:18:46 2006 +++ llvm/lib/Target/TargetMachine.cpp Wed May 24 12:04:04 2006 @@ -28,7 +28,7 @@ bool UnsafeFPMath; bool FiniteOnlyFPMathOption; Reloc::Model RelocationModel; -}; +} namespace { cl::opt PrintCode("print-machineinstrs", cl::desc("Print generated machine code"), @@ -70,7 +70,7 @@ clEnumValN(Reloc::DynamicNoPIC, "dynamic-no-pic", "Relocatable external references, non-relocatable code"), clEnumValEnd)); -}; +} //--------------------------------------------------------------------------- // TargetMachine Class From lattner at cs.uiuc.edu Wed May 24 12:04:35 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 24 May 2006 12:04:35 -0500 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/ListReducer.h Message-ID: <200605241704.MAA22789@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: ListReducer.h updated: 1.15 -> 1.16 --- Log message: Patches to make the LLVM sources more -pedantic clean. Patch provided by Anton Korobeynikov! This is a step towards closing PR786: http://llvm.cs.uiuc.edu/PR786 . --- Diffs of the changes: (+1 -1) ListReducer.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/tools/bugpoint/ListReducer.h diff -u llvm/tools/bugpoint/ListReducer.h:1.15 llvm/tools/bugpoint/ListReducer.h:1.16 --- llvm/tools/bugpoint/ListReducer.h:1.15 Sun Jan 8 16:40:10 2006 +++ llvm/tools/bugpoint/ListReducer.h Wed May 24 12:04:04 2006 @@ -27,7 +27,7 @@ enum TestResult { NoFailure, // No failure of the predicate was detected KeepSuffix, // The suffix alone satisfies the predicate - KeepPrefix, // The prefix alone satisfies the predicate + KeepPrefix // The prefix alone satisfies the predicate }; virtual ~ListReducer() {} From lattner at cs.uiuc.edu Wed May 24 12:04:35 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 24 May 2006 12:04:35 -0500 Subject: [llvm-commits] CVS: llvm/utils/PerfectShuffle/PerfectShuffle.cpp Message-ID: <200605241704.MAA22737@zion.cs.uiuc.edu> Changes in directory llvm/utils/PerfectShuffle: PerfectShuffle.cpp updated: 1.7 -> 1.8 --- Log message: Patches to make the LLVM sources more -pedantic clean. Patch provided by Anton Korobeynikov! This is a step towards closing PR786: http://llvm.cs.uiuc.edu/PR786 . --- Diffs of the changes: (+1 -1) PerfectShuffle.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/utils/PerfectShuffle/PerfectShuffle.cpp diff -u llvm/utils/PerfectShuffle/PerfectShuffle.cpp:1.7 llvm/utils/PerfectShuffle/PerfectShuffle.cpp:1.8 --- llvm/utils/PerfectShuffle/PerfectShuffle.cpp:1.7 Mon Apr 17 19:21:25 2006 +++ llvm/utils/PerfectShuffle/PerfectShuffle.cpp Wed May 24 12:04:05 2006 @@ -460,7 +460,7 @@ OP_VSPLTISW3, OP_VSLDOI4, OP_VSLDOI8, - OP_VSLDOI12, + OP_VSLDOI12 }; struct vmrghw : public Operator { From lattner at cs.uiuc.edu Wed May 24 12:04:35 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 24 May 2006 12:04:35 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <200605241704.MAA22793@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: RegisterInfoEmitter.cpp updated: 1.43 -> 1.44 --- Log message: Patches to make the LLVM sources more -pedantic clean. Patch provided by Anton Korobeynikov! This is a step towards closing PR786: http://llvm.cs.uiuc.edu/PR786 . --- Diffs of the changes: (+1 -1) RegisterInfoEmitter.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/utils/TableGen/RegisterInfoEmitter.cpp diff -u llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.43 llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.44 --- llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.43 Wed May 17 19:08:46 2006 +++ llvm/utils/TableGen/RegisterInfoEmitter.cpp Wed May 24 12:04:05 2006 @@ -37,7 +37,7 @@ OS << " enum {\n NoRegister,\n"; for (unsigned i = 0, e = Registers.size(); i != e; ++i) - OS << " " << Registers[i].getName() << ", \t// " << i+1 << "\n"; + OS << " " << Registers[i].getName() << (i != (e-1) ? ", \t// " : " \t// ") << i+1 << "\n"; OS << " };\n"; if (!Namespace.empty()) From lattner at cs.uiuc.edu Wed May 24 12:04:35 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 24 May 2006 12:04:35 -0500 Subject: [llvm-commits] CVS: llvm/tools/analyze/GraphPrinters.cpp Message-ID: <200605241704.MAA22741@zion.cs.uiuc.edu> Changes in directory llvm/tools/analyze: GraphPrinters.cpp updated: 1.10 -> 1.11 --- Log message: Patches to make the LLVM sources more -pedantic clean. Patch provided by Anton Korobeynikov! This is a step towards closing PR786: http://llvm.cs.uiuc.edu/PR786 . --- Diffs of the changes: (+1 -1) GraphPrinters.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/tools/analyze/GraphPrinters.cpp diff -u llvm/tools/analyze/GraphPrinters.cpp:1.10 llvm/tools/analyze/GraphPrinters.cpp:1.11 --- llvm/tools/analyze/GraphPrinters.cpp:1.10 Thu Apr 21 18:59:21 2005 +++ llvm/tools/analyze/GraphPrinters.cpp Wed May 24 12:04:04 2006 @@ -74,4 +74,4 @@ RegisterAnalysis P2("print-callgraph", "Print Call Graph to 'dot' file"); -}; +} From lattner at cs.uiuc.edu Wed May 24 12:04:35 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 24 May 2006 12:04:35 -0500 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Constants.cpp Message-ID: <200605241704.MAA22791@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Constants.cpp updated: 1.150 -> 1.151 --- Log message: Patches to make the LLVM sources more -pedantic clean. Patch provided by Anton Korobeynikov! This is a step towards closing PR786: http://llvm.cs.uiuc.edu/PR786 . --- Diffs of the changes: (+1 -1) Constants.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/VMCore/Constants.cpp diff -u llvm/lib/VMCore/Constants.cpp:1.150 llvm/lib/VMCore/Constants.cpp:1.151 --- llvm/lib/VMCore/Constants.cpp:1.150 Sat Apr 8 00:09:48 2006 +++ llvm/lib/VMCore/Constants.cpp Wed May 24 12:04:04 2006 @@ -529,7 +529,7 @@ case Type::DoubleTyID: return true; // This is the largest type... } -}; +} //===----------------------------------------------------------------------===// // Factory Function Implementation From lattner at cs.uiuc.edu Wed May 24 12:04:35 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 24 May 2006 12:04:35 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Instrumentation/RSProfiling.cpp RSProfiling.h Message-ID: <200605241704.MAA22769@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Instrumentation: RSProfiling.cpp updated: 1.4 -> 1.5 RSProfiling.h updated: 1.2 -> 1.3 --- Log message: Patches to make the LLVM sources more -pedantic clean. Patch provided by Anton Korobeynikov! This is a step towards closing PR786: http://llvm.cs.uiuc.edu/PR786 . --- Diffs of the changes: (+2 -2) RSProfiling.cpp | 2 +- RSProfiling.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Transforms/Instrumentation/RSProfiling.cpp diff -u llvm/lib/Transforms/Instrumentation/RSProfiling.cpp:1.4 llvm/lib/Transforms/Instrumentation/RSProfiling.cpp:1.5 --- llvm/lib/Transforms/Instrumentation/RSProfiling.cpp:1.4 Mon Nov 28 12:10:59 2005 +++ llvm/lib/Transforms/Instrumentation/RSProfiling.cpp Wed May 24 12:04:04 2006 @@ -162,7 +162,7 @@ RegisterOpt X("insert-rs-profiling-framework", "Insert random sampling instrumentation framework"); -}; +} //Local utilities static void ReplacePhiPred(BasicBlock* btarget, Index: llvm/lib/Transforms/Instrumentation/RSProfiling.h diff -u llvm/lib/Transforms/Instrumentation/RSProfiling.h:1.2 llvm/lib/Transforms/Instrumentation/RSProfiling.h:1.3 --- llvm/lib/Transforms/Instrumentation/RSProfiling.h:1.2 Mon Nov 28 12:00:38 2005 +++ llvm/lib/Transforms/Instrumentation/RSProfiling.h Wed May 24 12:04:04 2006 @@ -26,4 +26,4 @@ void IncrementCounterInBlock(BasicBlock *BB, unsigned CounterNum, GlobalValue *CounterArray); }; -}; +} From lattner at cs.uiuc.edu Wed May 24 12:31:14 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 24 May 2006 12:31:14 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/SubtargetEmitter.cpp Message-ID: <200605241731.MAA22968@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: SubtargetEmitter.cpp updated: 1.18 -> 1.19 --- Log message: Don't make zero-sized static arrays --- Diffs of the changes: (+1 -1) SubtargetEmitter.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/utils/TableGen/SubtargetEmitter.cpp diff -u llvm/utils/TableGen/SubtargetEmitter.cpp:1.18 llvm/utils/TableGen/SubtargetEmitter.cpp:1.19 --- llvm/utils/TableGen/SubtargetEmitter.cpp:1.18 Thu Mar 2 20:04:07 2006 +++ llvm/utils/TableGen/SubtargetEmitter.cpp Wed May 24 12:31:02 2006 @@ -377,7 +377,7 @@ } OS << "\n"; - OS << "static llvm::InstrItinerary NoItineraries[] = {};\n"; + OS << "static llvm::InstrItinerary NoItineraries[] = { {0, 0} };\n"; } // From lattner at cs.uiuc.edu Wed May 24 12:34:14 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 24 May 2006 12:34:14 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/2006-05-10-InvalidIndexUndef.ll Message-ID: <200605241734.MAA23061@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: 2006-05-10-InvalidIndexUndef.ll added (r1.1) --- Log message: Testcase for a new instcombine xform, patch contributed by Nick Lewycky! --- Diffs of the changes: (+8 -0) 2006-05-10-InvalidIndexUndef.ll | 8 ++++++++ 1 files changed, 8 insertions(+) Index: llvm/test/Regression/Transforms/InstCombine/2006-05-10-InvalidIndexUndef.ll diff -c /dev/null llvm/test/Regression/Transforms/InstCombine/2006-05-10-InvalidIndexUndef.ll:1.1 *** /dev/null Wed May 24 12:34:12 2006 --- llvm/test/Regression/Transforms/InstCombine/2006-05-10-InvalidIndexUndef.ll Wed May 24 12:34:02 2006 *************** *** 0 **** --- 1,8 ---- + ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep undef + + %str = constant [4 x ubyte] c"str\00" + + ubyte %main() { + %A = load ubyte* getelementptr ([4 x ubyte]* %str, long 0, long 5) + ret ubyte %A + } From lattner at cs.uiuc.edu Wed May 24 12:34:43 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 24 May 2006 12:34:43 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/Local.cpp Message-ID: <200605241734.MAA23073@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: Local.cpp updated: 1.55 -> 1.56 --- Log message: Patch for a new instcombine xform, patch contributed by Nick Lewycky! This implements Transforms/InstCombine/2006-05-10-InvalidIndexUndef.ll --- Diffs of the changes: (+4 -2) Local.cpp | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) Index: llvm/lib/Transforms/Utils/Local.cpp diff -u llvm/lib/Transforms/Utils/Local.cpp:1.55 llvm/lib/Transforms/Utils/Local.cpp:1.56 --- llvm/lib/Transforms/Utils/Local.cpp:1.55 Fri Apr 7 20:19:12 2006 +++ llvm/lib/Transforms/Utils/Local.cpp Wed May 24 12:34:30 2006 @@ -273,7 +273,8 @@ } } else if (ConstantInt *CI = dyn_cast(I.getOperand())) { if (const ArrayType *ATy = dyn_cast(*I)) { - if ((uint64_t)CI->getRawValue() >= ATy->getNumElements()) return 0; + if ((uint64_t)CI->getRawValue() >= ATy->getNumElements()) + C = UndefValue::get(ATy->getElementType()); if (ConstantArray *CA = dyn_cast(C)) C = CA->getOperand((unsigned)CI->getRawValue()); else if (isa(C)) @@ -283,7 +284,8 @@ else return 0; } else if (const PackedType *PTy = dyn_cast(*I)) { - if ((uint64_t)CI->getRawValue() >= PTy->getNumElements()) return 0; + if ((uint64_t)CI->getRawValue() >= PTy->getNumElements()) + C = UndefValue::get(PTy->getElementType()); if (ConstantPacked *CP = dyn_cast(C)) C = CP->getOperand((unsigned)CI->getRawValue()); else if (isa(C)) From lattner at cs.uiuc.edu Wed May 24 13:34:20 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 24 May 2006 13:34:20 -0500 Subject: [llvm-commits] CVS: llvm/Makefile.rules Message-ID: <200605241834.NAA23435@zion.cs.uiuc.edu> Changes in directory llvm: Makefile.rules updated: 1.370 -> 1.371 --- Log message: Don't use -fomit-frame-pointer on darwin, it breaks stacktrace collection. --- Diffs of the changes: (+3 -0) Makefile.rules | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/Makefile.rules diff -u llvm/Makefile.rules:1.370 llvm/Makefile.rules:1.371 --- llvm/Makefile.rules:1.370 Wed May 17 17:55:35 2006 +++ llvm/Makefile.rules Wed May 24 13:34:08 2006 @@ -208,8 +208,11 @@ BuildMode := Release # Don't use -fomit-frame-pointer on FreeBSD ifneq ($(OS),FreeBSD) + # Don't use -fomit-frame-pointer on Darwin, it breaks backtraces. + ifneq ($(OS),Darwin) OmitFramePointer := -fomit-frame-pointer endif + endif CXX.Flags := -O3 -finline-functions -felide-constructors $(OmitFramePointer) C.Flags := -O3 $(OmitFramePointer) LD.Flags := -O3 From reid at x10sys.com Wed May 24 14:05:33 2006 From: reid at x10sys.com (Reid Spencer) Date: Wed, 24 May 2006 14:05:33 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetMachine.cpp Message-ID: <200605241905.OAA23549@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetMachine.cpp updated: 1.47 -> 1.48 --- Log message: For PR786: http://llvm.cs.uiuc.edu/PR786 : Remove a spurious ; --- Diffs of the changes: (+1 -1) TargetMachine.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/TargetMachine.cpp diff -u llvm/lib/Target/TargetMachine.cpp:1.47 llvm/lib/Target/TargetMachine.cpp:1.48 --- llvm/lib/Target/TargetMachine.cpp:1.47 Wed May 24 12:04:04 2006 +++ llvm/lib/Target/TargetMachine.cpp Wed May 24 14:05:21 2006 @@ -100,4 +100,4 @@ /// the code generator is not allowed to assume that FP arithmetic arguments /// and results are never NaNs or +-Infs. bool FiniteOnlyFPMath() { return UnsafeFPMath || FiniteOnlyFPMathOption; } -}; +} From reid at x10sys.com Wed May 24 14:21:28 2006 From: reid at x10sys.com (Reid Spencer) Date: Wed, 24 May 2006 14:21:28 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/CBackend/Writer.cpp Message-ID: <200605241921.OAA23700@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/CBackend: Writer.cpp updated: 1.261 -> 1.262 --- Log message: For PR786: http://llvm.cs.uiuc.edu/PR786 : Minor tweaks in public headers and a few .cpp files so that LLVM can build successfully with -pedantic and projects using LLVM with -pedantic don't get warnings from LLVM. There's still more -pedantic warnings to fix. --- Diffs of the changes: (+1 -1) Writer.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/CBackend/Writer.cpp diff -u llvm/lib/Target/CBackend/Writer.cpp:1.261 llvm/lib/Target/CBackend/Writer.cpp:1.262 --- llvm/lib/Target/CBackend/Writer.cpp:1.261 Tue May 23 18:39:48 2006 +++ llvm/lib/Target/CBackend/Writer.cpp Wed May 24 14:21:12 2006 @@ -685,7 +685,7 @@ char Buffer[100]; uint64_t ll = DoubleToBits(FPC->getValue()); - sprintf(Buffer, "0x%llx", (unsigned long long)ll); + sprintf(Buffer, "0x%llx", uint64_t(ll)); std::string Num(&Buffer[0], &Buffer[6]); unsigned long Val = strtoul(Num.c_str(), 0, 16); From reid at x10sys.com Wed May 24 14:21:29 2006 From: reid at x10sys.com (Reid Spencer) Date: Wed, 24 May 2006 14:21:29 -0500 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp Message-ID: <200605241921.OAA23704@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/Interpreter: ExternalFunctions.cpp updated: 1.85 -> 1.86 --- Log message: For PR786: http://llvm.cs.uiuc.edu/PR786 : Minor tweaks in public headers and a few .cpp files so that LLVM can build successfully with -pedantic and projects using LLVM with -pedantic don't get warnings from LLVM. There's still more -pedantic warnings to fix. --- Diffs of the changes: (+1 -1) ExternalFunctions.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp diff -u llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp:1.85 llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp:1.86 --- llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp:1.85 Thu Apr 21 23:06:38 2005 +++ llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp Wed May 24 14:21:12 2006 @@ -313,7 +313,7 @@ if (HowLong >= 1) { if (HowLong == 1 && TheInterpreter->getModule().getPointerSize()==Module::Pointer64 && - sizeof(long) < sizeof(long long)) { + sizeof(long) < sizeof(int64_t)) { // Make sure we use %lld with a 64 bit argument because we might be // compiling LLI on a 32 bit compiler. unsigned Size = strlen(FmtBuf); From reid at x10sys.com Wed May 24 14:21:31 2006 From: reid at x10sys.com (Reid Spencer) Date: Wed, 24 May 2006 14:21:31 -0500 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/crtend/Exception.h Message-ID: <200605241921.OAA23708@zion.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/crtend: Exception.h updated: 1.9 -> 1.10 --- Log message: For PR786: http://llvm.cs.uiuc.edu/PR786 : Minor tweaks in public headers and a few .cpp files so that LLVM can build successfully with -pedantic and projects using LLVM with -pedantic don't get warnings from LLVM. There's still more -pedantic warnings to fix. --- Diffs of the changes: (+1 -1) Exception.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/runtime/GCCLibraries/crtend/Exception.h diff -u llvm/runtime/GCCLibraries/crtend/Exception.h:1.9 llvm/runtime/GCCLibraries/crtend/Exception.h:1.10 --- llvm/runtime/GCCLibraries/crtend/Exception.h:1.9 Thu Apr 21 18:48:05 2005 +++ llvm/runtime/GCCLibraries/crtend/Exception.h Wed May 24 14:21:12 2006 @@ -54,7 +54,7 @@ enum { ErrorException = 0, SJLJException = 1, - CXXException = 2, + CXXException = 2 }; // Language independent exception handling API... From reid at x10sys.com Wed May 24 14:21:31 2006 From: reid at x10sys.com (Reid Spencer) Date: Wed, 24 May 2006 14:21:31 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetLowering.h Message-ID: <200605241921.OAA23710@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetLowering.h updated: 1.75 -> 1.76 --- Log message: For PR786: http://llvm.cs.uiuc.edu/PR786 : Minor tweaks in public headers and a few .cpp files so that LLVM can build successfully with -pedantic and projects using LLVM with -pedantic don't get warnings from LLVM. There's still more -pedantic warnings to fix. --- Diffs of the changes: (+1 -1) TargetLowering.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/include/llvm/Target/TargetLowering.h diff -u llvm/include/llvm/Target/TargetLowering.h:1.75 llvm/include/llvm/Target/TargetLowering.h:1.76 --- llvm/include/llvm/Target/TargetLowering.h:1.75 Wed May 17 13:22:14 2006 +++ llvm/include/llvm/Target/TargetLowering.h Wed May 24 14:21:13 2006 @@ -512,7 +512,7 @@ LegalizeAction Action) { assert(VT < 32 && Op < sizeof(OpActions)/sizeof(OpActions[0]) && "Table isn't big enough!"); - OpActions[Op] &= ~(3ULL << VT*2); + OpActions[Op] &= ~(uint64_t(3UL) << VT*2); OpActions[Op] |= (uint64_t)Action << VT*2; } From reid at x10sys.com Wed May 24 14:21:32 2006 From: reid at x10sys.com (Reid Spencer) Date: Wed, 24 May 2006 14:21:32 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Constants.h Type.h Message-ID: <200605241921.OAA23724@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Constants.h updated: 1.79 -> 1.80 Type.h updated: 1.84 -> 1.85 --- Log message: For PR786: http://llvm.cs.uiuc.edu/PR786 : Minor tweaks in public headers and a few .cpp files so that LLVM can build successfully with -pedantic and projects using LLVM with -pedantic don't get warnings from LLVM. There's still more -pedantic warnings to fix. --- Diffs of the changes: (+2 -2) Constants.h | 2 +- Type.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/include/llvm/Constants.h diff -u llvm/include/llvm/Constants.h:1.79 llvm/include/llvm/Constants.h:1.80 --- llvm/include/llvm/Constants.h:1.79 Fri Apr 7 20:15:18 2006 +++ llvm/include/llvm/Constants.h Wed May 24 14:21:13 2006 @@ -58,7 +58,7 @@ /// type. inline uint64_t getZExtValue() const { unsigned Size = getType()->getPrimitiveSizeInBits(); - return Val.Unsigned & (~0ULL >> (64-Size)); + return Val.Unsigned & (~uint64_t(0UL) >> (64-Size)); } /// getSExtValue - Return the constant sign extended as appropriate for this Index: llvm/include/llvm/Type.h diff -u llvm/include/llvm/Type.h:1.84 llvm/include/llvm/Type.h:1.85 --- llvm/include/llvm/Type.h:1.84 Tue Apr 4 14:05:42 2006 +++ llvm/include/llvm/Type.h Wed May 24 14:21:13 2006 @@ -239,7 +239,7 @@ /// sbyte/ubyte, 0xFFFF for shorts, etc. uint64_t getIntegralTypeMask() const { assert(isIntegral() && "This only works for integral types!"); - return ~0ULL >> (64-getPrimitiveSizeInBits()); + return ~uint64_t(0UL) >> (64-getPrimitiveSizeInBits()); } /// getForwaredType - Return the type that this type has been resolved to if From reid at x10sys.com Wed May 24 14:21:32 2006 From: reid at x10sys.com (Reid Spencer) Date: Wed, 24 May 2006 14:21:32 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/ADT/StringExtras.h Message-ID: <200605241921.OAA23736@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/ADT: StringExtras.h updated: 1.27 -> 1.28 --- Log message: For PR786: http://llvm.cs.uiuc.edu/PR786 : Minor tweaks in public headers and a few .cpp files so that LLVM can build successfully with -pedantic and projects using LLVM with -pedantic don't get warnings from LLVM. There's still more -pedantic warnings to fix. --- Diffs of the changes: (+3 -3) StringExtras.h | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/include/llvm/ADT/StringExtras.h diff -u llvm/include/llvm/ADT/StringExtras.h:1.27 llvm/include/llvm/ADT/StringExtras.h:1.28 --- llvm/include/llvm/ADT/StringExtras.h:1.27 Thu Jan 26 14:36:29 2006 +++ llvm/include/llvm/ADT/StringExtras.h Wed May 24 14:21:13 2006 @@ -39,7 +39,7 @@ return std::string(BufPtr); } -static inline std::string utostr(unsigned long long X, bool isNeg = false) { +static inline std::string utostr(uint64_t X, bool isNeg = false) { char Buffer[40]; char *BufPtr = Buffer+39; @@ -56,7 +56,7 @@ } static inline std::string utostr(unsigned long X, bool isNeg = false) { - return utostr(static_cast(X), isNeg); + return utostr(static_cast(X), isNeg); } static inline std::string utostr(unsigned X, bool isNeg = false) { @@ -76,7 +76,7 @@ return std::string(BufPtr); } -static inline std::string itostr(long long X) { +static inline std::string itostr(int64_t X) { if (X < 0) return utostr(static_cast(-X), true); else From reid at x10sys.com Wed May 24 14:21:31 2006 From: reid at x10sys.com (Reid Spencer) Date: Wed, 24 May 2006 14:21:31 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/ValueTypes.h Message-ID: <200605241921.OAA23716@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: ValueTypes.h updated: 1.27 -> 1.28 --- Log message: For PR786: http://llvm.cs.uiuc.edu/PR786 : Minor tweaks in public headers and a few .cpp files so that LLVM can build successfully with -pedantic and projects using LLVM with -pedantic don't get warnings from LLVM. There's still more -pedantic warnings to fix. --- Diffs of the changes: (+2 -2) ValueTypes.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/include/llvm/CodeGen/ValueTypes.h diff -u llvm/include/llvm/CodeGen/ValueTypes.h:1.27 llvm/include/llvm/CodeGen/ValueTypes.h:1.28 --- llvm/include/llvm/CodeGen/ValueTypes.h:1.27 Mon Mar 27 19:59:17 2006 +++ llvm/include/llvm/CodeGen/ValueTypes.h Wed May 24 14:21:13 2006 @@ -203,13 +203,13 @@ /// bits in the specified integer value type. static inline uint64_t getIntVTBitMask(ValueType VT) { assert(isInteger(VT) && !isVector(VT) && "Only applies to int scalars!"); - return ~0ULL >> (64-getSizeInBits(VT)); + return ~uint64_t(0UL) >> (64-getSizeInBits(VT)); } /// MVT::getIntVTSignBit - Return an integer with a 1 in the position of the /// sign bit for the specified integer value type. static inline uint64_t getIntVTSignBit(ValueType VT) { assert(isInteger(VT) && !isVector(VT) && "Only applies to int scalars!"); - return 1ULL << (getSizeInBits(VT)-1); + return uint64_t(1UL) << (getSizeInBits(VT)-1); } /// MVT::getValueTypeString - This function returns value type as a string, From reid at x10sys.com Wed May 24 14:21:32 2006 From: reid at x10sys.com (Reid Spencer) Date: Wed, 24 May 2006 14:21:32 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/MathExtras.h SlowOperationInformer.h Message-ID: <200605241921.OAA23732@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: MathExtras.h updated: 1.29 -> 1.30 SlowOperationInformer.h updated: 1.5 -> 1.6 --- Log message: For PR786: http://llvm.cs.uiuc.edu/PR786 : Minor tweaks in public headers and a few .cpp files so that LLVM can build successfully with -pedantic and projects using LLVM with -pedantic don't get warnings from LLVM. There's still more -pedantic warnings to fix. --- Diffs of the changes: (+2 -2) MathExtras.h | 2 +- SlowOperationInformer.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/include/llvm/Support/MathExtras.h diff -u llvm/include/llvm/Support/MathExtras.h:1.29 llvm/include/llvm/Support/MathExtras.h:1.30 --- llvm/include/llvm/Support/MathExtras.h:1.29 Fri Jan 13 20:17:20 2006 +++ llvm/include/llvm/Support/MathExtras.h Wed May 24 14:21:13 2006 @@ -76,7 +76,7 @@ // isPowerOf2_64 - This function returns true if the argument is a power of two // > 0 (64 bit edition.) inline bool isPowerOf2_64(uint64_t Value) { - return Value && !(Value & (Value - 1LL)); + return Value && !(Value & (Value - int64_t(1L))); } // ByteSwap_16 - This function returns a byte-swapped representation of the Index: llvm/include/llvm/Support/SlowOperationInformer.h diff -u llvm/include/llvm/Support/SlowOperationInformer.h:1.5 llvm/include/llvm/Support/SlowOperationInformer.h:1.6 --- llvm/include/llvm/Support/SlowOperationInformer.h:1.5 Thu Apr 21 15:44:59 2005 +++ llvm/include/llvm/Support/SlowOperationInformer.h Wed May 24 14:21:13 2006 @@ -57,7 +57,7 @@ void progress(unsigned Current, unsigned Maximum) { assert(Maximum != 0 && "Shouldn't be doing work if there is nothing to do!"); - progress(Current*1000ULL/Maximum); + progress(Current*uint64_t(1000UL)/Maximum); } }; } // end namespace llvm From reid at x10sys.com Wed May 24 14:21:32 2006 From: reid at x10sys.com (Reid Spencer) Date: Wed, 24 May 2006 14:21:32 -0500 Subject: [llvm-commits] CVS: llvm/tools/llvm-prof/llvm-prof.cpp Message-ID: <200605241921.OAA23720@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-prof: llvm-prof.cpp updated: 1.27 -> 1.28 --- Log message: For PR786: http://llvm.cs.uiuc.edu/PR786 : Minor tweaks in public headers and a few .cpp files so that LLVM can build successfully with -pedantic and projects using LLVM with -pedantic don't get warnings from LLVM. There's still more -pedantic warnings to fix. --- Diffs of the changes: (+1 -1) llvm-prof.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/tools/llvm-prof/llvm-prof.cpp diff -u llvm/tools/llvm-prof/llvm-prof.cpp:1.27 llvm/tools/llvm-prof/llvm-prof.cpp:1.28 --- llvm/tools/llvm-prof/llvm-prof.cpp:1.27 Fri Dec 30 03:07:29 2005 +++ llvm/tools/llvm-prof/llvm-prof.cpp Wed May 24 14:21:12 2006 @@ -139,7 +139,7 @@ sort(FunctionCounts.begin(), FunctionCounts.end(), PairSecondSortReverse()); - unsigned long long TotalExecutions = 0; + uint64_t TotalExecutions = 0; for (unsigned i = 0, e = FunctionCounts.size(); i != e; ++i) TotalExecutions += FunctionCounts[i].second; From evan.cheng at apple.com Wed May 24 15:46:41 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 24 May 2006 15:46:41 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Message-ID: <200605242046.PAA24146@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelDAGToDAG.cpp updated: 1.187 -> 1.188 --- Log message: Clear HandleMap and ReplaceMap after instruction selection. Or it may cause non-deterministic behavior. --- Diffs of the changes: (+2 -0) PPCISelDAGToDAG.cpp | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.187 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.188 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.187 Wed May 17 14:00:46 2006 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Wed May 24 15:46:25 2006 @@ -206,6 +206,8 @@ // Select target instructions for the DAG. DAG.setRoot(SelectRoot(DAG.getRoot())); CodeGenMap.clear(); + HandleMap.clear(); + ReplaceMap.clear(); DAG.RemoveDeadNodes(); // Emit machine code to BB. From evan.cheng at apple.com Wed May 24 15:46:40 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 24 May 2006 15:46:40 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Message-ID: <200605242046.PAA24142@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelDAGToDAG.cpp updated: 1.67 -> 1.68 --- Log message: Clear HandleMap and ReplaceMap after instruction selection. Or it may cause non-deterministic behavior. --- Diffs of the changes: (+2 -0) X86ISelDAGToDAG.cpp | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.67 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.68 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.67 Wed May 24 12:04:04 2006 +++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Wed May 24 15:46:25 2006 @@ -186,6 +186,8 @@ DEBUG(std::cerr << "===== Instruction selection ends:\n"); #endif CodeGenMap.clear(); + HandleMap.clear(); + ReplaceMap.clear(); DAG.RemoveDeadNodes(); // Emit machine code to BB. From evan.cheng at apple.com Wed May 24 15:46:41 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 24 May 2006 15:46:41 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp Message-ID: <200605242046.PAA24162@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelDAGToDAG.cpp updated: 1.40 -> 1.41 --- Log message: Clear HandleMap and ReplaceMap after instruction selection. Or it may cause non-deterministic behavior. --- Diffs of the changes: (+2 -0) AlphaISelDAGToDAG.cpp | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp diff -u llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.40 llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.41 --- llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.40 Thu May 18 12:29:34 2006 +++ llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp Wed May 24 15:46:25 2006 @@ -155,6 +155,8 @@ // Select target instructions for the DAG. DAG.setRoot(SelectRoot(DAG.getRoot())); CodeGenMap.clear(); + HandleMap.clear(); + ReplaceMap.clear(); DAG.RemoveDeadNodes(); // Emit machine code to BB. From evan.cheng at apple.com Wed May 24 15:46:41 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 24 May 2006 15:46:41 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp Message-ID: <200605242046.PAA24156@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcISelDAGToDAG.cpp updated: 1.94 -> 1.95 --- Log message: Clear HandleMap and ReplaceMap after instruction selection. Or it may cause non-deterministic behavior. --- Diffs of the changes: (+2 -0) SparcISelDAGToDAG.cpp | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp diff -u llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp:1.94 llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp:1.95 --- llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp:1.94 Wed May 24 12:04:04 2006 +++ llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp Wed May 24 15:46:25 2006 @@ -996,6 +996,8 @@ // Select target instructions for the DAG. DAG.setRoot(SelectRoot(DAG.getRoot())); CodeGenMap.clear(); + HandleMap.clear(); + ReplaceMap.clear(); DAG.RemoveDeadNodes(); // Emit machine code to BB. From evan.cheng at apple.com Wed May 24 15:46:41 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 24 May 2006 15:46:41 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp Message-ID: <200605242046.PAA24150@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64ISelDAGToDAG.cpp updated: 1.40 -> 1.41 --- Log message: Clear HandleMap and ReplaceMap after instruction selection. Or it may cause non-deterministic behavior. --- Diffs of the changes: (+2 -0) IA64ISelDAGToDAG.cpp | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp diff -u llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp:1.40 llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp:1.41 --- llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp:1.40 Tue May 16 12:42:15 2006 +++ llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp Wed May 24 15:46:25 2006 @@ -148,6 +148,8 @@ // Select target instructions for the DAG. DAG.setRoot(SelectRoot(DAG.getRoot())); CodeGenMap.clear(); + HandleMap.clear(); + ReplaceMap.clear(); DAG.RemoveDeadNodes(); // Emit machine code to BB. From evan.cheng at apple.com Wed May 24 15:46:41 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 24 May 2006 15:46:41 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp Message-ID: <200605242046.PAA24154@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/ARM: ARMISelDAGToDAG.cpp updated: 1.5 -> 1.6 --- Log message: Clear HandleMap and ReplaceMap after instruction selection. Or it may cause non-deterministic behavior. --- Diffs of the changes: (+2 -0) ARMISelDAGToDAG.cpp | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp diff -u llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp:1.5 llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp:1.6 --- llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp:1.5 Wed May 24 12:04:04 2006 +++ llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp Wed May 24 15:46:25 2006 @@ -161,6 +161,8 @@ DAG.setRoot(SelectRoot(DAG.getRoot())); CodeGenMap.clear(); + HandleMap.clear(); + ReplaceMap.clear(); DAG.RemoveDeadNodes(); ScheduleAndEmitDAG(DAG); From lattner at cs.uiuc.edu Wed May 24 15:52:20 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 24 May 2006 15:52:20 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/CBackend/2004-11-13-FunctionPointerCast.llx Message-ID: <200605242052.PAA24246@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/CBackend: 2004-11-13-FunctionPointerCast.llx updated: 1.1 -> 1.2 --- Log message: Update testcase with recent cbe change --- Diffs of the changes: (+1 -1) 2004-11-13-FunctionPointerCast.llx | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/test/Regression/CodeGen/CBackend/2004-11-13-FunctionPointerCast.llx diff -u llvm/test/Regression/CodeGen/CBackend/2004-11-13-FunctionPointerCast.llx:1.1 llvm/test/Regression/CodeGen/CBackend/2004-11-13-FunctionPointerCast.llx:1.2 --- llvm/test/Regression/CodeGen/CBackend/2004-11-13-FunctionPointerCast.llx:1.1 Sat Nov 13 16:21:15 2004 +++ llvm/test/Regression/CodeGen/CBackend/2004-11-13-FunctionPointerCast.llx Wed May 24 15:52:08 2006 @@ -1,7 +1,7 @@ ; The CBE should not emit code that casts the function pointer. This causes ; GCC to get testy and insert trap instructions instead of doing the right ; thing. :( -; RUN: llvm-as < %s | llc -march=c | not grep 'external)' +; RUN: llvm-as < %s | llc -march=c implementation From lattner at cs.uiuc.edu Wed May 24 17:59:20 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 24 May 2006 17:59:20 -0500 Subject: [llvm-commits] CVS: llvm/Makefile.rules Message-ID: <200605242259.RAA25039@zion.cs.uiuc.edu> Changes in directory llvm: Makefile.rules updated: 1.371 -> 1.372 --- Log message: Remove flags implied by -O3 --- Diffs of the changes: (+2 -2) Makefile.rules | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/Makefile.rules diff -u llvm/Makefile.rules:1.371 llvm/Makefile.rules:1.372 --- llvm/Makefile.rules:1.371 Wed May 24 13:34:08 2006 +++ llvm/Makefile.rules Wed May 24 17:59:07 2006 @@ -200,7 +200,7 @@ ifdef ENABLE_PROFILING BuildMode := Profile - CXX.Flags := -O3 -felide-constructors -finline-functions -pg + CXX.Flags := -O3 -pg C.Flags := -O3 -pg LD.Flags := -O3 -pg else @@ -213,7 +213,7 @@ OmitFramePointer := -fomit-frame-pointer endif endif - CXX.Flags := -O3 -finline-functions -felide-constructors $(OmitFramePointer) + CXX.Flags := -O3 $(OmitFramePointer) C.Flags := -O3 $(OmitFramePointer) LD.Flags := -O3 else From lattner at cs.uiuc.edu Wed May 24 18:02:52 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 24 May 2006 18:02:52 -0500 Subject: [llvm-commits] CVS: llvm/Makefile.rules Message-ID: <200605242302.SAA25175@zion.cs.uiuc.edu> Changes in directory llvm: Makefile.rules updated: 1.372 -> 1.373 --- Log message: Abstract out the current optimization level into a flag that can be overridden on the make line, to avoid bugs in native compilers. --- Diffs of the changes: (+10 -6) Makefile.rules | 16 ++++++++++------ 1 files changed, 10 insertions(+), 6 deletions(-) Index: llvm/Makefile.rules diff -u llvm/Makefile.rules:1.372 llvm/Makefile.rules:1.373 --- llvm/Makefile.rules:1.372 Wed May 24 17:59:07 2006 +++ llvm/Makefile.rules Wed May 24 18:02:40 2006 @@ -198,11 +198,15 @@ # Variables derived from configuration we are building #-------------------------------------------------------------------- +# OPTIMIZE_OPTION - The optimization level option we want to build LLVM with +# this can be overridden on the make command line. +OPTIMIZE_OPTION := -O3 + ifdef ENABLE_PROFILING BuildMode := Profile - CXX.Flags := -O3 -pg - C.Flags := -O3 -pg - LD.Flags := -O3 -pg + CXX.Flags := $(OPTIMIZE_OPTION) -pg + C.Flags := $(OPTIMIZE_OPTION) -pg + LD.Flags := $(OPTIMIZE_OPTION) -pg else ifdef ENABLE_OPTIMIZED BuildMode := Release @@ -213,9 +217,9 @@ OmitFramePointer := -fomit-frame-pointer endif endif - CXX.Flags := -O3 $(OmitFramePointer) - C.Flags := -O3 $(OmitFramePointer) - LD.Flags := -O3 + CXX.Flags := $(OPTIMIZE_OPTION) $(OmitFramePointer) + C.Flags := $(OPTIMIZE_OPTION) $(OmitFramePointer) + LD.Flags := $(OPTIMIZE_OPTION) else BuildMode := Debug CXX.Flags := -g From reid at x10sys.com Wed May 24 18:33:55 2006 From: reid at x10sys.com (Reid Spencer) Date: Wed, 24 May 2006 16:33:55 -0700 Subject: [llvm-commits] CVS: llvm/Makefile.rules In-Reply-To: <200605242302.SAA25175@zion.cs.uiuc.edu> References: <200605242302.SAA25175@zion.cs.uiuc.edu> Message-ID: <1148513635.5380.8.camel@bashful.x10sys.com> On Wed, 2006-05-24 at 18:02 -0500, Chris Lattner wrote: > > +# OPTIMIZE_OPTION - The optimization level option we want to build LLVM with > +# this can be overridden on the make command line. > +OPTIMIZE_OPTION := -O3 Yuck! :) That means anyone not using a compiler that understands -O3 will have to put that on every make command line. I assume this is a temporary situation. What we ought to do is put the value into Makefile.config.in and have configure deduce it when it determines the kind of compiler we'll be using. If that makes sense, can you file a bug and I'll get to it eventually? Reid. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: This is a digitally signed message part Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20060524/7dcfec34/attachment.bin From sabre at nondot.org Wed May 24 18:37:10 2006 From: sabre at nondot.org (Chris Lattner) Date: Wed, 24 May 2006 18:37:10 -0500 (CDT) Subject: [llvm-commits] CVS: llvm/Makefile.rules In-Reply-To: <1148513635.5380.8.camel@bashful.x10sys.com> References: <200605242302.SAA25175@zion.cs.uiuc.edu> <1148513635.5380.8.camel@bashful.x10sys.com> Message-ID: On Wed, 24 May 2006, Reid Spencer wrote: >> +# this can be overridden on the make command line. >> +OPTIMIZE_OPTION := -O3 > > Yuck! :) > > That means anyone not using a compiler that understands -O3 will have to > put that on every make command line. I assume this is a temporary > situation. What we ought to do is put the value into Makefile.config.in > and have configure deduce it when it determines the kind of compiler > we'll be using. If that makes sense, can you file a bug and I'll get to > it eventually? That's not the intention of this option. The specific situation I have is that some versions of GCC crash when compiling some of the LLVM sources as -O3. As a temporary work around, I'm forcing -O2 to be used: ugly but effective. The only way to check for this in an autoconf check would be to compile all of llvm with -O3 :) I don't think the LLVM build systems are well suited for compilers that don't grok -O3, but this patch doesn't change that... -Chris -- http://nondot.org/sabre/ http://llvm.org/ From reid at x10sys.com Wed May 24 18:49:30 2006 From: reid at x10sys.com (Reid Spencer) Date: Wed, 24 May 2006 16:49:30 -0700 Subject: [llvm-commits] CVS: llvm/Makefile.rules In-Reply-To: References: <200605242302.SAA25175@zion.cs.uiuc.edu> <1148513635.5380.8.camel@bashful.x10sys.com> Message-ID: <1148514570.5380.10.camel@bashful.x10sys.com> Okay, that makes sense now :) Reid. On Wed, 2006-05-24 at 18:37 -0500, Chris Lattner wrote: > On Wed, 24 May 2006, Reid Spencer wrote: > >> +# this can be overridden on the make command line. > >> +OPTIMIZE_OPTION := -O3 > > > > Yuck! :) > > > > That means anyone not using a compiler that understands -O3 will have to > > put that on every make command line. I assume this is a temporary > > situation. What we ought to do is put the value into Makefile.config.in > > and have configure deduce it when it determines the kind of compiler > > we'll be using. If that makes sense, can you file a bug and I'll get to > > it eventually? > > That's not the intention of this option. The specific situation I have is > that some versions of GCC crash when compiling some of the LLVM sources as > -O3. As a temporary work around, I'm forcing -O2 to be used: ugly but > effective. The only way to check for this in an autoconf check would be > to compile all of llvm with -O3 :) > > I don't think the LLVM build systems are well suited for compilers that > don't grok -O3, but this patch doesn't change that... > > -Chris > -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: This is a digitally signed message part Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20060524/6d01f0cc/attachment.bin From evan.cheng at apple.com Wed May 24 19:21:56 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 24 May 2006 19:21:56 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200605250021.TAA25488@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.205 -> 1.206 --- Log message: Fixed a really ugly bug. The TableGen'd isel is not freeing the "inflight set" correctly. That is causing non-deterministic behavior (and possibly preventing some load folding from happening). --- Diffs of the changes: (+21 -9) DAGISelEmitter.cpp | 30 +++++++++++++++++++++--------- 1 files changed, 21 insertions(+), 9 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.205 llvm/utils/TableGen/DAGISelEmitter.cpp:1.206 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.205 Fri May 19 02:24:32 2006 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Wed May 24 19:21:44 2006 @@ -2407,20 +2407,32 @@ std::string Fn = CP->getSelectFunc(); NumRes = CP->getNumOperands(); for (unsigned i = 0; i < NumRes; ++i) - emitDecl("Tmp" + utostr(i+ResNo)); + emitDecl("CPTmp" + utostr(i+ResNo)); - std::string Code = Fn + "(" + Val; + std::string Code = "bool Match = " + Fn + "(" + Val; for (unsigned i = 0; i < NumRes; i++) - Code += ", Tmp" + utostr(i + ResNo); - emitCheck(Code + ")"); + Code += ", CPTmp" + utostr(i + ResNo); + emitCode(Code + ");"); + if (InflightNodes.size()) { + // Remove the in-flight nodes if the ComplexPattern does not match! + emitCode("if (!Match) {"); + for (std::vector::iterator AI = InflightNodes.begin(), + AE = InflightNodes.end(); AI != AE; ++AI) + emitCode(" InFlightSet.erase(" + *AI + ".Val);"); + emitCode("}"); + } + + emitCheck("Match"); for (unsigned i = 0; i < NumRes; ++i) { - emitCode("InFlightSet.insert(Tmp" + utostr(i+ResNo) + ".Val);"); - InflightNodes.push_back("Tmp" + utostr(i+ResNo)); + emitCode("InFlightSet.insert(CPTmp" + utostr(i+ResNo) + ".Val);"); + InflightNodes.push_back("CPTmp" + utostr(i+ResNo)); } - for (unsigned i = 0; i < NumRes; ++i) - emitCode("Select(Tmp" + utostr(i+ResNo) + ", Tmp" + + for (unsigned i = 0; i < NumRes; ++i) { + emitDecl("Tmp" + utostr(i+ResNo)); + emitCode("Select(Tmp" + utostr(i+ResNo) + ", CPTmp" + utostr(i+ResNo) + ");"); + } TmpNo = ResNo + NumRes; } else { @@ -2524,7 +2536,6 @@ // Make sure these operands which would be selected won't be folded while // the isel traverses the DAG upward. - std::vector > NumTemps(EmitOrder.size()); for (unsigned i = 0, e = EmitOrder.size(); i != e; ++i) { TreePatternNode *Child = EmitOrder[i].second; if (!Child->getName().empty()) { @@ -2539,6 +2550,7 @@ } // Emit all of the operands. + std::vector > NumTemps(EmitOrder.size()); for (unsigned i = 0, e = EmitOrder.size(); i != e; ++i) { unsigned OpOrder = EmitOrder[i].first; TreePatternNode *Child = EmitOrder[i].second; From evan.cheng at apple.com Wed May 24 19:24:42 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 24 May 2006 19:24:42 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Message-ID: <200605250024.TAA25534@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelDAGToDAG.cpp updated: 1.188 -> 1.189 --- Log message: Assert if InflightSet is not cleared after instruction selecting a BB. --- Diffs of the changes: (+1 -0) PPCISelDAGToDAG.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.188 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.189 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.188 Wed May 24 15:46:25 2006 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Wed May 24 19:24:27 2006 @@ -205,6 +205,7 @@ // Select target instructions for the DAG. DAG.setRoot(SelectRoot(DAG.getRoot())); + assert(InFlightSet.empty() && "ISel InFlightSet has not been emptied!"); CodeGenMap.clear(); HandleMap.clear(); ReplaceMap.clear(); From evan.cheng at apple.com Wed May 24 19:24:43 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 24 May 2006 19:24:43 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp Message-ID: <200605250024.TAA25538@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelDAGToDAG.cpp updated: 1.41 -> 1.42 --- Log message: Assert if InflightSet is not cleared after instruction selecting a BB. --- Diffs of the changes: (+1 -0) AlphaISelDAGToDAG.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp diff -u llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.41 llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.42 --- llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.41 Wed May 24 15:46:25 2006 +++ llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp Wed May 24 19:24:28 2006 @@ -154,6 +154,7 @@ // Select target instructions for the DAG. DAG.setRoot(SelectRoot(DAG.getRoot())); + assert(InFlightSet.empty() && "ISel InFlightSet has not been emptied!"); CodeGenMap.clear(); HandleMap.clear(); ReplaceMap.clear(); From evan.cheng at apple.com Wed May 24 19:24:44 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 24 May 2006 19:24:44 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Message-ID: <200605250024.TAA25554@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelDAGToDAG.cpp updated: 1.68 -> 1.69 --- Log message: Assert if InflightSet is not cleared after instruction selecting a BB. --- Diffs of the changes: (+1 -0) X86ISelDAGToDAG.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.68 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.69 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.68 Wed May 24 15:46:25 2006 +++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Wed May 24 19:24:27 2006 @@ -182,6 +182,7 @@ Indent = 0; #endif DAG.setRoot(SelectRoot(DAG.getRoot())); + assert(InFlightSet.empty() && "ISel InFlightSet has not been emptied!"); #ifndef NDEBUG DEBUG(std::cerr << "===== Instruction selection ends:\n"); #endif From evan.cheng at apple.com Wed May 24 19:24:44 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 24 May 2006 19:24:44 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp Message-ID: <200605250024.TAA25550@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64ISelDAGToDAG.cpp updated: 1.41 -> 1.42 --- Log message: Assert if InflightSet is not cleared after instruction selecting a BB. --- Diffs of the changes: (+1 -0) IA64ISelDAGToDAG.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp diff -u llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp:1.41 llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp:1.42 --- llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp:1.41 Wed May 24 15:46:25 2006 +++ llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp Wed May 24 19:24:28 2006 @@ -147,6 +147,7 @@ // Select target instructions for the DAG. DAG.setRoot(SelectRoot(DAG.getRoot())); + assert(InFlightSet.empty() && "ISel InFlightSet has not been emptied!"); CodeGenMap.clear(); HandleMap.clear(); ReplaceMap.clear(); From evan.cheng at apple.com Wed May 24 19:24:44 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 24 May 2006 19:24:44 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp Message-ID: <200605250024.TAA25542@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcISelDAGToDAG.cpp updated: 1.95 -> 1.96 --- Log message: Assert if InflightSet is not cleared after instruction selecting a BB. --- Diffs of the changes: (+1 -0) SparcISelDAGToDAG.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp diff -u llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp:1.95 llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp:1.96 --- llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp:1.95 Wed May 24 15:46:25 2006 +++ llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp Wed May 24 19:24:27 2006 @@ -995,6 +995,7 @@ // Select target instructions for the DAG. DAG.setRoot(SelectRoot(DAG.getRoot())); + assert(InFlightSet.empty() && "ISel InFlightSet has not been emptied!"); CodeGenMap.clear(); HandleMap.clear(); ReplaceMap.clear(); From evan.cheng at apple.com Wed May 24 19:24:44 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 24 May 2006 19:24:44 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp Message-ID: <200605250024.TAA25546@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/ARM: ARMISelDAGToDAG.cpp updated: 1.6 -> 1.7 --- Log message: Assert if InflightSet is not cleared after instruction selecting a BB. --- Diffs of the changes: (+1 -0) ARMISelDAGToDAG.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp diff -u llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp:1.6 llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp:1.7 --- llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp:1.6 Wed May 24 15:46:25 2006 +++ llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp Wed May 24 19:24:28 2006 @@ -160,6 +160,7 @@ DEBUG(BB->dump()); DAG.setRoot(SelectRoot(DAG.getRoot())); + assert(InFlightSet.empty() && "ISel InFlightSet has not been emptied!"); CodeGenMap.clear(); HandleMap.clear(); ReplaceMap.clear(); From evan.cheng at apple.com Wed May 24 19:54:45 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 24 May 2006 19:54:45 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200605250054.TAA25698@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAGNodes.h updated: 1.132 -> 1.133 --- Log message: CALL node change: now containing signness of each argument. --- Diffs of the changes: (+3 -3) SelectionDAGNodes.h | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.132 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.133 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.132 Tue May 16 17:52:27 2006 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Wed May 24 19:54:33 2006 @@ -125,10 +125,10 @@ FORMAL_ARGUMENTS, /// RV1, RV2...RVn, CHAIN = CALL(CHAIN, CC#, ISVARARG, ISTAILCALL, CALLEE, - /// ARG0, ARG1, ... ARGn) + /// ARG0, SIGN0, ARG1, SIGN1, ... ARGn, SIGNn) /// This node represents a fully general function call, before the legalizer - /// runs. This has one result value for each argument, plus a chain result. - /// It must be custom legalized. + /// runs. This has one result value for each argument / signness pair, plus + /// a chain result. It must be custom legalized. CALL, // EXTRACT_ELEMENT - This is used to get the first or second (determined by From evan.cheng at apple.com Wed May 24 19:55:45 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 24 May 2006 19:55:45 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200605250055.TAA25713@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.250 -> 1.251 --- Log message: CALL node change: now including signness of every argument. --- Diffs of the changes: (+7 -2) SelectionDAGISel.cpp | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.250 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.251 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.250 Tue May 23 13:18:46 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed May 24 19:55:32 2006 @@ -2506,21 +2506,23 @@ for (unsigned i = 0, e = Args.size(); i != e; ++i) { MVT::ValueType VT = getValueType(Args[i].second); SDOperand Op = Args[i].first; + bool isSigned = Args[i].second->isSigned(); switch (getTypeAction(VT)) { default: assert(0 && "Unknown type action!"); case Legal: Ops.push_back(Op); + Ops.push_back(DAG.getConstant(isSigned, MVT::i1)); break; case Promote: if (MVT::isInteger(VT)) { - unsigned ExtOp = Args[i].second->isSigned() ? - ISD::SIGN_EXTEND : ISD::ZERO_EXTEND; + unsigned ExtOp = isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND; Op = DAG.getNode(ExtOp, getTypeToTransformTo(VT), Op); } else { assert(MVT::isFloatingPoint(VT) && "Not int or FP?"); Op = DAG.getNode(ISD::FP_EXTEND, getTypeToTransformTo(VT), Op); } Ops.push_back(Op); + Ops.push_back(DAG.getConstant(isSigned, MVT::i1)); break; case Expand: if (VT != MVT::Vector) { @@ -2538,7 +2540,9 @@ std::swap(Lo, Hi); Ops.push_back(Lo); + Ops.push_back(DAG.getConstant(isSigned, MVT::i1)); Ops.push_back(Hi); + Ops.push_back(DAG.getConstant(isSigned, MVT::i1)); } else { // Value scalarized into many values. Unimp for now. assert(0 && "Cannot expand i64 -> i16 yet!"); @@ -2557,6 +2561,7 @@ // Insert a VBIT_CONVERT of the MVT::Vector type to the packed type. Op = DAG.getNode(ISD::VBIT_CONVERT, TVT, Op); Ops.push_back(Op); + Ops.push_back(DAG.getConstant(isSigned, MVT::i1)); } else { assert(0 && "Don't support illegal by-val vector call args yet!"); abort(); From evan.cheng at apple.com Wed May 24 19:57:45 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 24 May 2006 19:57:45 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp Message-ID: <200605250057.TAA25733@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelLowering.cpp updated: 1.183 -> 1.184 --- Log message: CALL node change (arg / sign pairs instead of just arguments). --- Diffs of the changes: (+6 -5) PPCISelLowering.cpp | 11 ++++++----- 1 files changed, 6 insertions(+), 5 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.183 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.184 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.183 Wed May 24 12:04:04 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Wed May 24 19:57:32 2006 @@ -901,7 +901,8 @@ bool isVarArg = cast(Op.getOperand(2))->getValue() != 0; bool isTailCall = cast(Op.getOperand(3))->getValue() != 0; SDOperand Callee = Op.getOperand(4); - + unsigned NumOps = (Op.getNumOperands() - 5) / 2; + // args_to_use will accumulate outgoing args for the PPCISD::CALL case in // SelectExpr to use to put the arguments in the appropriate registers. std::vector args_to_use; @@ -912,8 +913,8 @@ unsigned NumBytes = 24; // Add up all the space actually used. - for (unsigned i = 5, e = Op.getNumOperands(); i != e; ++i) - NumBytes += MVT::getSizeInBits(Op.getOperand(i).getValueType())/8; + for (unsigned i = 0; i != NumOps; ++i) + NumBytes += MVT::getSizeInBits(Op.getOperand(5+2*i).getValueType())/8; // If we are calling what looks like a varargs function on the caller side, // there are two cases: @@ -962,8 +963,8 @@ std::vector > RegsToPass; std::vector MemOpChains; - for (unsigned i = 5, e = Op.getNumOperands(); i != e; ++i) { - SDOperand Arg = Op.getOperand(i); + for (unsigned i = 0; i != NumOps; ++i) { + SDOperand Arg = Op.getOperand(5+2*i); // PtrOff will be used to store the current argument to the stack if a // register cannot be found for it. From evan.cheng at apple.com Wed May 24 19:59:42 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 24 May 2006 19:59:42 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h Message-ID: <200605250059.TAA25784@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.211 -> 1.212 X86ISelLowering.h updated: 1.65 -> 1.66 --- Log message: Switch X86 over to a call-selection model where the lowering code creates the copyto/fromregs instead of making the X86ISD::CALL selection code create them. --- Diffs of the changes: (+391 -421) X86ISelLowering.cpp | 792 +++++++++++++++++++++++++--------------------------- X86ISelLowering.h | 20 - 2 files changed, 391 insertions(+), 421 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.211 llvm/lib/Target/X86/X86ISelLowering.cpp:1.212 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.211 Tue May 23 18:20:42 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Wed May 24 19:59:30 2006 @@ -358,29 +358,6 @@ allowUnalignedMemoryAccesses = true; // x86 supports it! } -std::pair -X86TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, - bool isVarArg, unsigned CallingConv, - bool isTailCall, - SDOperand Callee, ArgListTy &Args, - SelectionDAG &DAG) { - assert((!isVarArg || CallingConv == CallingConv::C || - CallingConv == CallingConv::CSRet) && - "Only CCC/CSRet takes varargs!"); - - // If the callee is a GlobalAddress node (quite common, every direct call is) - // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. - if (GlobalAddressSDNode *G = dyn_cast(Callee)) - Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy()); - else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) - Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy()); - - if (CallingConv == CallingConv::Fast && EnableFastCC) - return LowerFastCCCallTo(Chain, RetTy, isTailCall, Callee, Args, DAG); - return LowerCCCCallTo(Chain, RetTy, isVarArg, isTailCall, CallingConv, - Callee, Args, DAG); -} - //===----------------------------------------------------------------------===// // C Calling Convention implementation //===----------------------------------------------------------------------===// @@ -516,150 +493,134 @@ return DAG.getNode(ISD::MERGE_VALUES, RetVTs, ArgValues); } -std::pair -X86TargetLowering::LowerCCCCallTo(SDOperand Chain, const Type *RetTy, - bool isVarArg, bool isTailCall, - unsigned CallingConv, - SDOperand Callee, ArgListTy &Args, - SelectionDAG &DAG) { - // Count how many bytes are to be pushed on the stack. - unsigned NumBytes = 0; + +SDOperand X86TargetLowering::LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG) { + SDOperand Chain = Op.getOperand(0); + unsigned CallingConv= cast(Op.getOperand(1))->getValue(); + bool isVarArg = cast(Op.getOperand(2))->getValue() != 0; + bool isTailCall = cast(Op.getOperand(3))->getValue() != 0; + SDOperand Callee = Op.getOperand(4); + MVT::ValueType RetVT= Op.Val->getValueType(0); + unsigned NumOps = (Op.getNumOperands() - 5) / 2; // Keep track of the number of XMM regs passed so far. unsigned NumXMMRegs = 0; - unsigned XMMArgRegs[] = { X86::XMM0, X86::XMM1, X86::XMM2 }; + static const unsigned XMMArgRegs[] = { + X86::XMM0, X86::XMM1, X86::XMM2 + }; - std::vector RegValuesToPass; - if (Args.empty()) { - // Save zero bytes. - Chain = DAG.getCALLSEQ_START(Chain, DAG.getConstant(0, getPointerTy())); - } else { - for (unsigned i = 0, e = Args.size(); i != e; ++i) - switch (getValueType(Args[i].second)) { - default: assert(0 && "Unknown value type!"); - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - case MVT::f32: - NumBytes += 4; - break; - case MVT::i64: - case MVT::f64: - NumBytes += 8; - break; - case MVT::Vector: - if (NumXMMRegs < 3) - ++NumXMMRegs; - else - NumBytes += 16; - break; - } + // Count how many bytes are to be pushed on the stack. + unsigned NumBytes = 0; + for (unsigned i = 0; i != NumOps; ++i) { + SDOperand Arg = Op.getOperand(5+2*i); - Chain = DAG.getCALLSEQ_START(Chain, - DAG.getConstant(NumBytes, getPointerTy())); + switch (Arg.getValueType()) { + default: assert(0 && "Unexpected ValueType for argument!"); + case MVT::i8: + case MVT::i16: + case MVT::i32: + case MVT::f32: + NumBytes += 4; + break; + case MVT::i64: + case MVT::f64: + NumBytes += 8; + break; + case MVT::v16i8: + case MVT::v8i16: + case MVT::v4i32: + case MVT::v2i64: + case MVT::v4f32: + case MVT::v2f64: { + if (NumXMMRegs < 3) + ++NumXMMRegs; + else + NumBytes += 16; + break; + } + } + } - // Arguments go on the stack in reverse order, as specified by the ABI. - unsigned ArgOffset = 0; - NumXMMRegs = 0; - SDOperand StackPtr = DAG.getRegister(X86::ESP, MVT::i32); - std::vector Stores; - for (unsigned i = 0, e = Args.size(); i != e; ++i) { - switch (getValueType(Args[i].second)) { - default: assert(0 && "Unexpected ValueType for argument!"); - case MVT::i1: - case MVT::i8: - case MVT::i16: - // Promote the integer to 32 bits. If the input type is signed use a - // sign extend, otherwise use a zero extend. - if (Args[i].second->isSigned()) - Args[i].first =DAG.getNode(ISD::SIGN_EXTEND, MVT::i32, Args[i].first); - else - Args[i].first =DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first); + Chain = DAG.getCALLSEQ_START(Chain,DAG.getConstant(NumBytes, getPointerTy())); - // FALL THROUGH - case MVT::i32: - case MVT::f32: { - SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); - PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); - Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Args[i].first, PtrOff, - DAG.getSrcValue(NULL))); - ArgOffset += 4; - break; - } - case MVT::i64: - case MVT::f64: { + // Arguments go on the stack in reverse order, as specified by the ABI. + unsigned ArgOffset = 0; + NumXMMRegs = 0; + std::vector > RegsToPass; + std::vector MemOpChains; + SDOperand StackPtr = DAG.getRegister(X86::ESP, getPointerTy()); + for (unsigned i = 0; i != NumOps; ++i) { + SDOperand Arg = Op.getOperand(5+2*i); + + switch (Arg.getValueType()) { + default: assert(0 && "Unexpected ValueType for argument!"); + case MVT::i8: + case MVT::i16: + // Promote the integer to 32 bits. If the input type is signed use a + // sign extend, otherwise use a zero extend. + unsigned ExtOp = + dyn_cast(Op.getOperand(5+2*i+1))->getValue() ? + ISD::SIGN_EXTEND : ISD::ZERO_EXTEND; + Arg = DAG.getNode(ExtOp, MVT::i32, Arg); + // Fallthrough + + case MVT::i32: + case MVT::f32: { + SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); + PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff); + MemOpChains.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Arg, PtrOff, DAG.getSrcValue(NULL))); + ArgOffset += 4; + break; + } + case MVT::i64: + case MVT::f64: { + SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); + PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff); + MemOpChains.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Arg, PtrOff, DAG.getSrcValue(NULL))); + ArgOffset += 8; + break; + } + case MVT::v16i8: + case MVT::v8i16: + case MVT::v4i32: + case MVT::v2i64: + case MVT::v4f32: + case MVT::v2f64: { + if (NumXMMRegs < 3) { + RegsToPass.push_back(std::make_pair(XMMArgRegs[NumXMMRegs], Arg)); + NumXMMRegs++; + } else { SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); - PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); - Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Args[i].first, PtrOff, - DAG.getSrcValue(NULL))); - ArgOffset += 8; - break; - } - case MVT::Vector: - if (NumXMMRegs < 3) { - RegValuesToPass.push_back(Args[i].first); - NumXMMRegs++; - } else { - SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); - PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); - Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Args[i].first, PtrOff, - DAG.getSrcValue(NULL))); - ArgOffset += 16; - } + PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff); + MemOpChains.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Arg, PtrOff, DAG.getSrcValue(NULL))); + ArgOffset += 16; } } - if (!Stores.empty()) - Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores); + } } - std::vector RetVals; - MVT::ValueType RetTyVT = getValueType(RetTy); - RetVals.push_back(MVT::Other); - - // The result values produced have to be legal. Promote the result. - switch (RetTyVT) { - case MVT::isVoid: break; - default: - RetVals.push_back(RetTyVT); - break; - case MVT::i1: - case MVT::i8: - case MVT::i16: - RetVals.push_back(MVT::i32); - break; - case MVT::f32: - if (X86ScalarSSE) - RetVals.push_back(MVT::f32); - else - RetVals.push_back(MVT::f64); - break; - case MVT::i64: - RetVals.push_back(MVT::i32); - RetVals.push_back(MVT::i32); - break; - } + if (!MemOpChains.empty()) + Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, MemOpChains); // Build a sequence of copy-to-reg nodes chained together with token chain // and flag operands which copy the outgoing args into registers. SDOperand InFlag; - for (unsigned i = 0, e = RegValuesToPass.size(); i != e; ++i) { - unsigned CCReg = XMMArgRegs[i]; - SDOperand RegToPass = RegValuesToPass[i]; - assert(RegToPass.getValueType() == MVT::Vector); - unsigned NumElems = - cast(*(RegToPass.Val->op_end()-2))->getValue(); - MVT::ValueType EVT = cast(*(RegToPass.Val->op_end()-1))->getVT(); - MVT::ValueType PVT = getVectorType(EVT, NumElems); - SDOperand CCRegNode = DAG.getRegister(CCReg, PVT); - RegToPass = DAG.getNode(ISD::VBIT_CONVERT, PVT, RegToPass); - Chain = DAG.getCopyToReg(Chain, CCRegNode, RegToPass, InFlag); + for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { + Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second, + InFlag); InFlag = Chain.getValue(1); } + // If the callee is a GlobalAddress node (quite common, every direct call is) + // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. + if (GlobalAddressSDNode *G = dyn_cast(Callee)) + Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy()); + else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) + Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy()); + std::vector NodeTys; NodeTys.push_back(MVT::Other); // Returns a chain NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use. @@ -669,8 +630,8 @@ if (InFlag.Val) Ops.push_back(InFlag); - // FIXME: Do not generate X86ISD::TAILCALL for now. - Chain = DAG.getNode(X86ISD::CALL, NodeTys, Ops); + Chain = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL, + NodeTys, Ops); InFlag = Chain.getValue(1); // Create the CALLSEQ_END node. @@ -683,95 +644,109 @@ NodeTys.clear(); NodeTys.push_back(MVT::Other); // Returns a chain - NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use. + if (RetVT != MVT::Other) + NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use. Ops.clear(); Ops.push_back(Chain); Ops.push_back(DAG.getConstant(NumBytes, getPointerTy())); Ops.push_back(DAG.getConstant(NumBytesForCalleeToPush, getPointerTy())); Ops.push_back(InFlag); Chain = DAG.getNode(ISD::CALLSEQ_END, NodeTys, Ops); - InFlag = Chain.getValue(1); + if (RetVT != MVT::Other) + InFlag = Chain.getValue(1); - SDOperand RetVal; - if (RetTyVT != MVT::isVoid) { - switch (RetTyVT) { - default: assert(0 && "Unknown value type to return!"); - case MVT::i1: - case MVT::i8: - RetVal = DAG.getCopyFromReg(Chain, X86::AL, MVT::i8, InFlag); - Chain = RetVal.getValue(1); - if (RetTyVT == MVT::i1) - RetVal = DAG.getNode(ISD::TRUNCATE, MVT::i1, RetVal); - break; - case MVT::i16: - RetVal = DAG.getCopyFromReg(Chain, X86::AX, MVT::i16, InFlag); - Chain = RetVal.getValue(1); - break; - case MVT::i32: - RetVal = DAG.getCopyFromReg(Chain, X86::EAX, MVT::i32, InFlag); - Chain = RetVal.getValue(1); - break; - case MVT::i64: { - SDOperand Lo = DAG.getCopyFromReg(Chain, X86::EAX, MVT::i32, InFlag); - SDOperand Hi = DAG.getCopyFromReg(Lo.getValue(1), X86::EDX, MVT::i32, - Lo.getValue(2)); - RetVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi); - Chain = Hi.getValue(1); - break; + std::vector ResultVals; + NodeTys.clear(); + switch (RetVT) { + default: assert(0 && "Unknown value type to return!"); + case MVT::Other: break; + case MVT::i8: + Chain = DAG.getCopyFromReg(Chain, X86::AL, MVT::i8, InFlag).getValue(1); + ResultVals.push_back(Chain.getValue(0)); + NodeTys.push_back(MVT::i8); + break; + case MVT::i16: + Chain = DAG.getCopyFromReg(Chain, X86::AX, MVT::i16, InFlag).getValue(1); + ResultVals.push_back(Chain.getValue(0)); + NodeTys.push_back(MVT::i16); + break; + case MVT::i32: + if (Op.Val->getValueType(1) == MVT::i32) { + Chain = DAG.getCopyFromReg(Chain, X86::EAX, MVT::i32, InFlag).getValue(1); + ResultVals.push_back(Chain.getValue(0)); + Chain = DAG.getCopyFromReg(Chain, X86::EDX, MVT::i32, + Chain.getValue(2)).getValue(1); + ResultVals.push_back(Chain.getValue(0)); + NodeTys.push_back(MVT::i32); + } else { + Chain = DAG.getCopyFromReg(Chain, X86::EAX, MVT::i32, InFlag).getValue(1); + ResultVals.push_back(Chain.getValue(0)); } - case MVT::f32: - case MVT::f64: { - std::vector Tys; - Tys.push_back(MVT::f64); + NodeTys.push_back(MVT::i32); + break; + case MVT::v16i8: + case MVT::v8i16: + case MVT::v4i32: + case MVT::v2i64: + case MVT::v4f32: + case MVT::v2f64: + case MVT::Vector: + Chain = DAG.getCopyFromReg(Chain, X86::XMM0, RetVT, InFlag).getValue(1); + ResultVals.push_back(Chain.getValue(0)); + NodeTys.push_back(RetVT); + break; + case MVT::f32: + case MVT::f64: { + std::vector Tys; + Tys.push_back(MVT::f64); + Tys.push_back(MVT::Other); + Tys.push_back(MVT::Flag); + std::vector Ops; + Ops.push_back(Chain); + Ops.push_back(InFlag); + SDOperand RetVal = DAG.getNode(X86ISD::FP_GET_RESULT, Tys, Ops); + Chain = RetVal.getValue(1); + InFlag = RetVal.getValue(2); + if (X86ScalarSSE) { + // FIXME: Currently the FST is flagged to the FP_GET_RESULT. This + // shouldn't be necessary except that RFP cannot be live across + // multiple blocks. When stackifier is fixed, they can be uncoupled. + MachineFunction &MF = DAG.getMachineFunction(); + int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8); + SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); + Tys.clear(); Tys.push_back(MVT::Other); - Tys.push_back(MVT::Flag); - std::vector Ops; + Ops.clear(); Ops.push_back(Chain); + Ops.push_back(RetVal); + Ops.push_back(StackSlot); + Ops.push_back(DAG.getValueType(RetVT)); Ops.push_back(InFlag); - RetVal = DAG.getNode(X86ISD::FP_GET_RESULT, Tys, Ops); - Chain = RetVal.getValue(1); - InFlag = RetVal.getValue(2); - if (X86ScalarSSE) { - // FIXME: Currently the FST is flagged to the FP_GET_RESULT. This - // shouldn't be necessary except that RFP cannot be live across - // multiple blocks. When stackifier is fixed, they can be uncoupled. - MachineFunction &MF = DAG.getMachineFunction(); - int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8); - SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); - Tys.clear(); - Tys.push_back(MVT::Other); - Ops.clear(); - Ops.push_back(Chain); - Ops.push_back(RetVal); - Ops.push_back(StackSlot); - Ops.push_back(DAG.getValueType(RetTyVT)); - Ops.push_back(InFlag); - Chain = DAG.getNode(X86ISD::FST, Tys, Ops); - RetVal = DAG.getLoad(RetTyVT, Chain, StackSlot, - DAG.getSrcValue(NULL)); - Chain = RetVal.getValue(1); - } - - if (RetTyVT == MVT::f32 && !X86ScalarSSE) - // FIXME: we would really like to remember that this FP_ROUND - // operation is okay to eliminate if we allow excess FP precision. - RetVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, RetVal); - break; - } - case MVT::Vector: { - const PackedType *PTy = cast(RetTy); - MVT::ValueType EVT; - MVT::ValueType LVT; - unsigned NumRegs = getPackedTypeBreakdown(PTy, EVT, LVT); - assert(NumRegs == 1 && "Unsupported type!"); - RetVal = DAG.getCopyFromReg(Chain, X86::XMM0, EVT, InFlag); + Chain = DAG.getNode(X86ISD::FST, Tys, Ops); + RetVal = DAG.getLoad(RetVT, Chain, StackSlot, + DAG.getSrcValue(NULL)); Chain = RetVal.getValue(1); - break; - } } + + if (RetVT == MVT::f32 && !X86ScalarSSE) + // FIXME: we would really like to remember that this FP_ROUND + // operation is okay to eliminate if we allow excess FP precision. + RetVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, RetVal); + ResultVals.push_back(RetVal); + NodeTys.push_back(RetVT); + break; + } } - return std::make_pair(RetVal, Chain); + // If the function returns void, just return the chain. + if (ResultVals.empty()) + return Chain; + + // Otherwise, merge everything together with a MERGE_VALUES node. + NodeTys.push_back(MVT::Other); + ResultVals.push_back(Chain); + SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, NodeTys, ResultVals); + return Res.getValue(Op.ResNo); } //===----------------------------------------------------------------------===// @@ -894,7 +869,10 @@ // used). unsigned NumIntRegs = 0; unsigned NumXMMRegs = 0; // XMM regs used for parameter passing. - unsigned XMMArgRegs[] = { X86::XMM0, X86::XMM1, X86::XMM2 }; + + static const unsigned XMMArgRegs[] = { + X86::XMM0, X86::XMM1, X86::XMM2 + }; for (unsigned i = 0; i < NumArgs; ++i) { MVT::ValueType ObjectVT = Op.getValue(i).getValueType(); @@ -1018,10 +996,15 @@ return DAG.getNode(ISD::MERGE_VALUES, RetVTs, ArgValues); } -std::pair -X86TargetLowering::LowerFastCCCallTo(SDOperand Chain, const Type *RetTy, - bool isTailCall, SDOperand Callee, - ArgListTy &Args, SelectionDAG &DAG) { + SDOperand X86TargetLowering::LowerFastCCCallTo(SDOperand Op, SelectionDAG &DAG) { + SDOperand Chain = Op.getOperand(0); + unsigned CallingConv= cast(Op.getOperand(1))->getValue(); + bool isVarArg = cast(Op.getOperand(2))->getValue() != 0; + bool isTailCall = cast(Op.getOperand(3))->getValue() != 0; + SDOperand Callee = Op.getOperand(4); + MVT::ValueType RetVT= Op.Val->getValueType(0); + unsigned NumOps = (Op.getNumOperands() - 5) / 2; + // Count how many bytes are to be pushed on the stack. unsigned NumBytes = 0; @@ -1029,11 +1012,22 @@ // 0 (neither EAX or EDX used), 1 (EAX is used) or 2 (EAX and EDX are both // used). unsigned NumIntRegs = 0; + unsigned NumXMMRegs = 0; // XMM regs used for parameter passing. - for (unsigned i = 0, e = Args.size(); i != e; ++i) - switch (getValueType(Args[i].second)) { + static const unsigned GPRArgRegs[][2] = { + { X86::AL, X86::DL }, + { X86::AX, X86::DX }, + { X86::EAX, X86::EDX } + }; + static const unsigned XMMArgRegs[] = { + X86::XMM0, X86::XMM1, X86::XMM2 + }; + + for (unsigned i = 0; i != NumOps; ++i) { + SDOperand Arg = Op.getOperand(5+2*i); + + switch (Arg.getValueType()) { default: assert(0 && "Unknown value type!"); - case MVT::i1: case MVT::i8: case MVT::i16: case MVT::i32: @@ -1041,25 +1035,26 @@ ++NumIntRegs; break; } - // fall through case MVT::f32: NumBytes += 4; break; - case MVT::i64: - if (NumIntRegs+2 <= FASTCC_NUM_INT_ARGS_INREGS) { - NumIntRegs += 2; - break; - } else if (NumIntRegs+1 <= FASTCC_NUM_INT_ARGS_INREGS) { - NumIntRegs = FASTCC_NUM_INT_ARGS_INREGS; - NumBytes += 4; - break; - } - - // fall through case MVT::f64: NumBytes += 8; break; + case MVT::v16i8: + case MVT::v8i16: + case MVT::v4i32: + case MVT::v2i64: + case MVT::v4f32: + case MVT::v2f64: { + if (NumXMMRegs < 3) + NumXMMRegs++; + else + NumBytes += 16; + break; } + } + } // Make sure the instruction takes 8n+4 bytes to make sure the start of the // arguments and the arguments after the retaddr has been pushed are aligned. @@ -1070,128 +1065,81 @@ // Arguments go on the stack in reverse order, as specified by the ABI. unsigned ArgOffset = 0; - SDOperand StackPtr = DAG.getRegister(X86::ESP, MVT::i32); NumIntRegs = 0; - std::vector Stores; - std::vector RegValuesToPass; - for (unsigned i = 0, e = Args.size(); i != e; ++i) { - switch (getValueType(Args[i].second)) { + std::vector > RegsToPass; + std::vector MemOpChains; + SDOperand StackPtr = DAG.getRegister(X86::ESP, getPointerTy()); + for (unsigned i = 0; i != NumOps; ++i) { + SDOperand Arg = Op.getOperand(5+2*i); + + switch (Arg.getValueType()) { default: assert(0 && "Unexpected ValueType for argument!"); - case MVT::i1: - Args[i].first = DAG.getNode(ISD::ANY_EXTEND, MVT::i8, Args[i].first); - // Fall through. case MVT::i8: case MVT::i16: case MVT::i32: if (NumIntRegs < FASTCC_NUM_INT_ARGS_INREGS) { - RegValuesToPass.push_back(Args[i].first); + RegsToPass.push_back( + std::make_pair(GPRArgRegs[Arg.getValueType()-MVT::i8][NumIntRegs], + Arg)); ++NumIntRegs; break; } // Fall through case MVT::f32: { SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); - PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); - Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Args[i].first, PtrOff, - DAG.getSrcValue(NULL))); + PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff); + MemOpChains.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Arg, PtrOff, DAG.getSrcValue(NULL))); ArgOffset += 4; break; } - case MVT::i64: - // Can pass (at least) part of it in regs? - if (NumIntRegs < FASTCC_NUM_INT_ARGS_INREGS) { - SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, - Args[i].first, DAG.getConstant(1, MVT::i32)); - SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, - Args[i].first, DAG.getConstant(0, MVT::i32)); - RegValuesToPass.push_back(Lo); - ++NumIntRegs; - - // Pass both parts in regs? - if (NumIntRegs < FASTCC_NUM_INT_ARGS_INREGS) { - RegValuesToPass.push_back(Hi); - ++NumIntRegs; - } else { - // Pass the high part in memory. - SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); - PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); - Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Hi, PtrOff, DAG.getSrcValue(NULL))); - ArgOffset += 4; - } - break; - } - // Fall through - case MVT::f64: + case MVT::f64: { SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); - PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); - Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Args[i].first, PtrOff, - DAG.getSrcValue(NULL))); + PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff); + MemOpChains.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Arg, PtrOff, DAG.getSrcValue(NULL))); ArgOffset += 8; break; } + case MVT::v16i8: + case MVT::v8i16: + case MVT::v4i32: + case MVT::v2i64: + case MVT::v4f32: + case MVT::v2f64: { + if (NumXMMRegs < 3) { + RegsToPass.push_back(std::make_pair(XMMArgRegs[NumXMMRegs], Arg)); + NumXMMRegs++; + } else { + SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); + PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff); + MemOpChains.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Arg, PtrOff, DAG.getSrcValue(NULL))); + ArgOffset += 16; + } + } + } } - if (!Stores.empty()) - Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores); - // Make sure the instruction takes 8n+4 bytes to make sure the start of the - // arguments and the arguments after the retaddr has been pushed are aligned. - if ((ArgOffset & 7) == 0) - ArgOffset += 4; - - std::vector RetVals; - MVT::ValueType RetTyVT = getValueType(RetTy); - - RetVals.push_back(MVT::Other); - - // The result values produced have to be legal. Promote the result. - switch (RetTyVT) { - case MVT::isVoid: break; - default: - RetVals.push_back(RetTyVT); - break; - case MVT::i1: - case MVT::i8: - case MVT::i16: - RetVals.push_back(MVT::i32); - break; - case MVT::f32: - if (X86ScalarSSE) - RetVals.push_back(MVT::f32); - else - RetVals.push_back(MVT::f64); - break; - case MVT::i64: - RetVals.push_back(MVT::i32); - RetVals.push_back(MVT::i32); - break; - } + if (!MemOpChains.empty()) + Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, MemOpChains); // Build a sequence of copy-to-reg nodes chained together with token chain // and flag operands which copy the outgoing args into registers. SDOperand InFlag; - for (unsigned i = 0, e = RegValuesToPass.size(); i != e; ++i) { - unsigned CCReg; - SDOperand RegToPass = RegValuesToPass[i]; - switch (RegToPass.getValueType()) { - default: assert(0 && "Bad thing to pass in regs"); - case MVT::i8: - CCReg = (i == 0) ? X86::AL : X86::DL; - break; - case MVT::i16: - CCReg = (i == 0) ? X86::AX : X86::DX; - break; - case MVT::i32: - CCReg = (i == 0) ? X86::EAX : X86::EDX; - break; - } - - Chain = DAG.getCopyToReg(Chain, CCReg, RegToPass, InFlag); + for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { + Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second, + InFlag); InFlag = Chain.getValue(1); } + // If the callee is a GlobalAddress node (quite common, every direct call is) + // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. + if (GlobalAddressSDNode *G = dyn_cast(Callee)) + Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy()); + else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) + Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy()); + std::vector NodeTys; NodeTys.push_back(MVT::Other); // Returns a chain NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use. @@ -1208,85 +1156,110 @@ NodeTys.clear(); NodeTys.push_back(MVT::Other); // Returns a chain - NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use. + if (RetVT != MVT::Other) + NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use. Ops.clear(); Ops.push_back(Chain); - Ops.push_back(DAG.getConstant(ArgOffset, getPointerTy())); - Ops.push_back(DAG.getConstant(ArgOffset, getPointerTy())); + Ops.push_back(DAG.getConstant(NumBytes, getPointerTy())); + Ops.push_back(DAG.getConstant(NumBytes, getPointerTy())); Ops.push_back(InFlag); Chain = DAG.getNode(ISD::CALLSEQ_END, NodeTys, Ops); - InFlag = Chain.getValue(1); + if (RetVT != MVT::Other) + InFlag = Chain.getValue(1); - SDOperand RetVal; - if (RetTyVT != MVT::isVoid) { - switch (RetTyVT) { - default: assert(0 && "Unknown value type to return!"); - case MVT::i1: - case MVT::i8: - RetVal = DAG.getCopyFromReg(Chain, X86::AL, MVT::i8, InFlag); - Chain = RetVal.getValue(1); - if (RetTyVT == MVT::i1) - RetVal = DAG.getNode(ISD::TRUNCATE, MVT::i1, RetVal); - break; - case MVT::i16: - RetVal = DAG.getCopyFromReg(Chain, X86::AX, MVT::i16, InFlag); - Chain = RetVal.getValue(1); - break; - case MVT::i32: - RetVal = DAG.getCopyFromReg(Chain, X86::EAX, MVT::i32, InFlag); - Chain = RetVal.getValue(1); - break; - case MVT::i64: { - SDOperand Lo = DAG.getCopyFromReg(Chain, X86::EAX, MVT::i32, InFlag); - SDOperand Hi = DAG.getCopyFromReg(Lo.getValue(1), X86::EDX, MVT::i32, - Lo.getValue(2)); - RetVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi); - Chain = Hi.getValue(1); - break; + std::vector ResultVals; + NodeTys.clear(); + switch (RetVT) { + default: assert(0 && "Unknown value type to return!"); + case MVT::Other: break; + case MVT::i8: + Chain = DAG.getCopyFromReg(Chain, X86::AL, MVT::i8, InFlag).getValue(1); + ResultVals.push_back(Chain.getValue(0)); + NodeTys.push_back(MVT::i8); + break; + case MVT::i16: + Chain = DAG.getCopyFromReg(Chain, X86::AX, MVT::i16, InFlag).getValue(1); + ResultVals.push_back(Chain.getValue(0)); + NodeTys.push_back(MVT::i16); + break; + case MVT::i32: + if (Op.Val->getValueType(1) == MVT::i32) { + Chain = DAG.getCopyFromReg(Chain, X86::EAX, MVT::i32, InFlag).getValue(1); + ResultVals.push_back(Chain.getValue(0)); + Chain = DAG.getCopyFromReg(Chain, X86::EDX, MVT::i32, + Chain.getValue(2)).getValue(1); + ResultVals.push_back(Chain.getValue(0)); + NodeTys.push_back(MVT::i32); + } else { + Chain = DAG.getCopyFromReg(Chain, X86::EAX, MVT::i32, InFlag).getValue(1); + ResultVals.push_back(Chain.getValue(0)); } - case MVT::f32: - case MVT::f64: { - std::vector Tys; - Tys.push_back(MVT::f64); + NodeTys.push_back(MVT::i32); + break; + case MVT::v16i8: + case MVT::v8i16: + case MVT::v4i32: + case MVT::v2i64: + case MVT::v4f32: + case MVT::v2f64: + case MVT::Vector: + Chain = DAG.getCopyFromReg(Chain, X86::XMM0, RetVT, InFlag).getValue(1); + ResultVals.push_back(Chain.getValue(0)); + NodeTys.push_back(RetVT); + break; + case MVT::f32: + case MVT::f64: { + std::vector Tys; + Tys.push_back(MVT::f64); + Tys.push_back(MVT::Other); + Tys.push_back(MVT::Flag); + std::vector Ops; + Ops.push_back(Chain); + Ops.push_back(InFlag); + SDOperand RetVal = DAG.getNode(X86ISD::FP_GET_RESULT, Tys, Ops); + Chain = RetVal.getValue(1); + InFlag = RetVal.getValue(2); + if (X86ScalarSSE) { + // FIXME: Currently the FST is flagged to the FP_GET_RESULT. This + // shouldn't be necessary except that RFP cannot be live across + // multiple blocks. When stackifier is fixed, they can be uncoupled. + MachineFunction &MF = DAG.getMachineFunction(); + int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8); + SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); + Tys.clear(); Tys.push_back(MVT::Other); - Tys.push_back(MVT::Flag); - std::vector Ops; + Ops.clear(); Ops.push_back(Chain); + Ops.push_back(RetVal); + Ops.push_back(StackSlot); + Ops.push_back(DAG.getValueType(RetVT)); Ops.push_back(InFlag); - RetVal = DAG.getNode(X86ISD::FP_GET_RESULT, Tys, Ops); - Chain = RetVal.getValue(1); - InFlag = RetVal.getValue(2); - if (X86ScalarSSE) { - // FIXME: Currently the FST is flagged to the FP_GET_RESULT. This - // shouldn't be necessary except that RFP cannot be live across - // multiple blocks. When stackifier is fixed, they can be uncoupled. - MachineFunction &MF = DAG.getMachineFunction(); - int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8); - SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); - Tys.clear(); - Tys.push_back(MVT::Other); - Ops.clear(); - Ops.push_back(Chain); - Ops.push_back(RetVal); - Ops.push_back(StackSlot); - Ops.push_back(DAG.getValueType(RetTyVT)); - Ops.push_back(InFlag); - Chain = DAG.getNode(X86ISD::FST, Tys, Ops); - RetVal = DAG.getLoad(RetTyVT, Chain, StackSlot, - DAG.getSrcValue(NULL)); - Chain = RetVal.getValue(1); - } - - if (RetTyVT == MVT::f32 && !X86ScalarSSE) - // FIXME: we would really like to remember that this FP_ROUND - // operation is okay to eliminate if we allow excess FP precision. - RetVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, RetVal); - break; - } + Chain = DAG.getNode(X86ISD::FST, Tys, Ops); + RetVal = DAG.getLoad(RetVT, Chain, StackSlot, + DAG.getSrcValue(NULL)); + Chain = RetVal.getValue(1); } + + if (RetVT == MVT::f32 && !X86ScalarSSE) + // FIXME: we would really like to remember that this FP_ROUND + // operation is okay to eliminate if we allow excess FP precision. + RetVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, RetVal); + ResultVals.push_back(RetVal); + NodeTys.push_back(RetVT); + break; + } } - return std::make_pair(RetVal, Chain); + + // If the function returns void, just return the chain. + if (ResultVals.empty()) + return Chain; + + // Otherwise, merge everything together with a MERGE_VALUES node. + NodeTys.push_back(MVT::Other); + ResultVals.push_back(Chain); + SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, NodeTys, ResultVals); + return Res.getValue(Op.ResNo); } SDOperand X86TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) { @@ -3344,6 +3317,14 @@ return Result; } +SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) { + unsigned CallingConv= cast(Op.getOperand(1))->getValue(); + if (CallingConv == CallingConv::Fast && EnableFastCC) + return LowerFastCCCallTo(Op, DAG); + else + return LowerCCCCallTo(Op, DAG); +} + SDOperand X86TargetLowering::LowerRET(SDOperand Op, SelectionDAG &DAG) { SDOperand Copy; @@ -3860,6 +3841,7 @@ case ISD::SELECT: return LowerSELECT(Op, DAG); case ISD::BRCOND: return LowerBRCOND(Op, DAG); case ISD::JumpTable: return LowerJumpTable(Op, DAG); + case ISD::CALL: return LowerCALL(Op, DAG); case ISD::RET: return LowerRET(Op, DAG); case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG); case ISD::MEMSET: return LowerMEMSET(Op, DAG); Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.65 llvm/lib/Target/X86/X86ISelLowering.h:1.66 --- llvm/lib/Target/X86/X86ISelLowering.h:1.65 Wed May 24 12:04:04 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Wed May 24 19:59:30 2006 @@ -282,13 +282,6 @@ /// virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); - /// LowerCallTo - This hook lowers an abstract call to a function into an - /// actual call. - virtual std::pair - LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, unsigned CC, - bool isTailCall, SDOperand Callee, ArgListTy &Args, - SelectionDAG &DAG); - virtual std::pair LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, SelectionDAG &DAG); @@ -343,17 +336,11 @@ // C Calling Convention implementation. SDOperand LowerCCCArguments(SDOperand Op, SelectionDAG &DAG); - std::pair - LowerCCCCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, - bool isTailCall, unsigned CallingConv, - SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); + SDOperand LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG); // Fast Calling Convention implementation. - SDOperand - LowerFastCCArguments(SDOperand Op, SelectionDAG &DAG); - std::pair - LowerFastCCCallTo(SDOperand Chain, const Type *RetTy, bool isTailCall, - SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); + SDOperand LowerFastCCArguments(SDOperand Op, SelectionDAG &DAG); + SDOperand LowerFastCCCallTo(SDOperand Op, SelectionDAG &DAG); SDOperand LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG); SDOperand LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG); @@ -374,6 +361,7 @@ SDOperand LowerMEMSET(SDOperand Op, SelectionDAG &DAG); SDOperand LowerMEMCPY(SDOperand Op, SelectionDAG &DAG); SDOperand LowerJumpTable(SDOperand Op, SelectionDAG &DAG); + SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG); SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG); SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG); SDOperand LowerREADCYCLCECOUNTER(SDOperand Op, SelectionDAG &DAG); From lattner at cs.uiuc.edu Thu May 25 01:00:02 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 25 May 2006 01:00:02 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/SlowOperationInformer.h Message-ID: <200605250600.BAA27044@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: SlowOperationInformer.h updated: 1.6 -> 1.7 --- Log message: Fix breakage on platforms where string/cassert don't pull in int64_t. --- Diffs of the changes: (+1 -0) SlowOperationInformer.h | 1 + 1 files changed, 1 insertion(+) Index: llvm/include/llvm/Support/SlowOperationInformer.h diff -u llvm/include/llvm/Support/SlowOperationInformer.h:1.6 llvm/include/llvm/Support/SlowOperationInformer.h:1.7 --- llvm/include/llvm/Support/SlowOperationInformer.h:1.6 Wed May 24 14:21:13 2006 +++ llvm/include/llvm/Support/SlowOperationInformer.h Thu May 25 00:59:50 2006 @@ -33,6 +33,7 @@ #include #include +#include "llvm/Support/DataTypes.h" namespace llvm { class SlowOperationInformer { From evan.cheng at apple.com Thu May 25 03:37:43 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 25 May 2006 03:37:43 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Message-ID: <200605250837.DAA24873@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGRRList.cpp updated: 1.4 -> 1.5 --- Log message: Turn on -sched-commute-nodes by default. --- Diffs of the changes: (+2 -7) ScheduleDAGRRList.cpp | 9 ++------- 1 files changed, 2 insertions(+), 7 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp:1.4 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp:1.5 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp:1.4 Sat May 13 03:22:24 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Thu May 25 03:37:31 2006 @@ -31,10 +31,6 @@ using namespace llvm; namespace { - cl::opt SchedCommuteNodes("sched-commute-nodes", cl::Hidden); -} - -namespace { //===----------------------------------------------------------------------===// /// ScheduleDAGRRList - The actual register reduction list scheduler /// implementation. This supports both top-down and bottom-up scheduling. @@ -100,8 +96,7 @@ AvailableQueue->releaseState(); - if (SchedCommuteNodes) - CommuteNodesToReducePressure(); + CommuteNodesToReducePressure(); DEBUG(std::cerr << "*** Final schedule ***\n"); DEBUG(dumpSchedule()); @@ -685,7 +680,7 @@ SUnit *SuccSU = I->first; if (SuccSU != SU && (!canClobber(SuccSU, DUSU) || - (SchedCommuteNodes && !SU->isCommutable && SuccSU->isCommutable))){ + (!SU->isCommutable && SuccSU->isCommutable))){ if (SuccSU->Depth == SU->Depth && !isReachable(SuccSU, SU)) { DEBUG(std::cerr << "Adding an edge from SU # " << SU->NodeNum << " to SU #" << SuccSU->NodeNum << "\n"); From evan.cheng at apple.com Thu May 25 03:38:33 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 25 May 2006 03:38:33 -0500 Subject: [llvm-commits] CVS: llvm-test/Makefile.programs Message-ID: <200605250838.DAA24885@zion.cs.uiuc.edu> Changes in directory llvm-test: Makefile.programs updated: 1.212 -> 1.213 --- Log message: Set x86 llcbeta to -sched=list-tdrr --- Diffs of the changes: (+1 -1) Makefile.programs | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-test/Makefile.programs diff -u llvm-test/Makefile.programs:1.212 llvm-test/Makefile.programs:1.213 --- llvm-test/Makefile.programs:1.212 Thu May 11 20:58:52 2006 +++ llvm-test/Makefile.programs Thu May 25 03:38:21 2006 @@ -197,7 +197,7 @@ LLCBETAOPTION := -sched=simple endif ifeq ($(ARCH),x86) -LLCBETAOPTION := -sched-commute-nodes +LLCBETAOPTION := -sched=list-tdrr endif ifeq ($(ARCH),Sparc) LLCBETAOPTION := -enable-sparc-v9-insts From evan.cheng at apple.com Thu May 25 03:39:37 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 25 May 2006 03:39:37 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/2006-05-11-InstrSched.ll Message-ID: <200605250839.DAA24906@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: 2006-05-11-InstrSched.ll updated: 1.1 -> 1.2 --- Log message: -sched-commute-nodes is now on by default. --- Diffs of the changes: (+1 -2) 2006-05-11-InstrSched.ll | 3 +-- 1 files changed, 1 insertion(+), 2 deletions(-) Index: llvm/test/Regression/CodeGen/X86/2006-05-11-InstrSched.ll diff -u llvm/test/Regression/CodeGen/X86/2006-05-11-InstrSched.ll:1.1 llvm/test/Regression/CodeGen/X86/2006-05-11-InstrSched.ll:1.2 --- llvm/test/Regression/CodeGen/X86/2006-05-11-InstrSched.ll:1.1 Thu May 11 20:59:17 2006 +++ llvm/test/Regression/CodeGen/X86/2006-05-11-InstrSched.ll Thu May 25 03:39:25 2006 @@ -1,5 +1,4 @@ -; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 -sched-commute-nodes && -; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 -sched-commute-nodes -stats 2>&1 | grep 'asm-printer' | grep 39 +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 -stats 2>&1 | grep 'asm-printer' | grep 39 void %foo(int* %mc, int* %bp, int* %ms, int* %xmb, int* %mpp, int* %tpmm, int* %ip, int* %tpim, int* %dpp, int* %tpdm, int* %bpi, int %M) { entry: From llvm at cs.uiuc.edu Thu May 25 05:47:41 2006 From: llvm at cs.uiuc.edu (LLVM) Date: Thu, 25 May 2006 05:47:41 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/ARM/ Message-ID: <200605251047.FAA25553@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/ARM: --- Log message: Directory /var/cvs/llvm/llvm/test/Regression/CodeGen/ARM added to the repository --- Diffs of the changes: (+0 -0) 0 files changed From rafael.espindola at gmail.com Thu May 25 05:49:32 2006 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Thu, 25 May 2006 05:49:32 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/ARM/dg.exp ret0.ll Message-ID: <200605251049.FAA25596@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/ARM: dg.exp added (r1.1) ret0.ll added (r1.1) --- Log message: create test/Regression/CodeGen/ARM/ and add a minimal test to it --- Diffs of the changes: (+7 -0) dg.exp | 3 +++ ret0.ll | 4 ++++ 2 files changed, 7 insertions(+) Index: llvm/test/Regression/CodeGen/ARM/dg.exp diff -c /dev/null llvm/test/Regression/CodeGen/ARM/dg.exp:1.1 *** /dev/null Thu May 25 05:49:29 2006 --- llvm/test/Regression/CodeGen/ARM/dg.exp Thu May 25 05:49:19 2006 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $srcdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext $llvmgcc_version Index: llvm/test/Regression/CodeGen/ARM/ret0.ll diff -c /dev/null llvm/test/Regression/CodeGen/ARM/ret0.ll:1.1 *** /dev/null Thu May 25 05:49:32 2006 --- llvm/test/Regression/CodeGen/ARM/ret0.ll Thu May 25 05:49:19 2006 *************** *** 0 **** --- 1,4 ---- + ; RUN: llvm-as < %s | llc -march=arm + int %test() { + ret int 0 + } From rafael.espindola at gmail.com Thu May 25 06:00:30 2006 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Thu, 25 May 2006 06:00:30 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp Message-ID: <200605251100.GAA25668@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/ARM: ARMISelDAGToDAG.cpp updated: 1.7 -> 1.8 --- Log message: port the ARM backend to use ISD::CALL instead of LowerCallTo --- Diffs of the changes: (+3 -12) ARMISelDAGToDAG.cpp | 15 +++------------ 1 files changed, 3 insertions(+), 12 deletions(-) Index: llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp diff -u llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp:1.7 llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp:1.8 --- llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp:1.7 Wed May 24 19:24:28 2006 +++ llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp Thu May 25 06:00:18 2006 @@ -40,13 +40,6 @@ public: ARMTargetLowering(TargetMachine &TM); virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); - - virtual std::pair - LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, - unsigned CC, - bool isTailCall, SDOperand Callee, ArgListTy &Args, - SelectionDAG &DAG); - }; } @@ -56,11 +49,7 @@ setOperationAction(ISD::RET, MVT::Other, Custom); } -std::pair -ARMTargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, - bool isVarArg, unsigned CC, - bool isTailCall, SDOperand Callee, - ArgListTy &Args, SelectionDAG &DAG) { +static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) { assert(0 && "Not implemented"); abort(); } @@ -127,6 +116,8 @@ abort(); case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG); + case ISD::CALL: + return LowerCALL(Op, DAG); case ISD::RET: return LowerRET(Op, DAG); } From rafael.espindola at gmail.com Thu May 25 07:57:19 2006 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Thu, 25 May 2006 07:57:19 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/ARM/ARMAsmPrinter.cpp Message-ID: <200605251257.HAA26042@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/ARM: ARMAsmPrinter.cpp updated: 1.2 -> 1.3 --- Log message: implement initial version of ARMAsmPrinter::printOperand --- Diffs of the changes: (+31 -1) ARMAsmPrinter.cpp | 32 +++++++++++++++++++++++++++++++- 1 files changed, 31 insertions(+), 1 deletion(-) Index: llvm/lib/Target/ARM/ARMAsmPrinter.cpp diff -u llvm/lib/Target/ARM/ARMAsmPrinter.cpp:1.2 llvm/lib/Target/ARM/ARMAsmPrinter.cpp:1.3 --- llvm/lib/Target/ARM/ARMAsmPrinter.cpp:1.2 Mon May 22 21:48:20 2006 +++ llvm/lib/Target/ARM/ARMAsmPrinter.cpp Thu May 25 07:57:06 2006 @@ -133,7 +133,37 @@ } void ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum) { - assert(0 && "not implemented"); + const MachineOperand &MO = MI->getOperand (opNum); + const MRegisterInfo &RI = *TM.getRegisterInfo(); + switch (MO.getType()) { + case MachineOperand::MO_Register: + if (MRegisterInfo::isPhysicalRegister(MO.getReg())) + O << LowercaseString (RI.get(MO.getReg()).Name); + else + assert(0 && "not implemented"); + break; + case MachineOperand::MO_Immediate: + O << "#" << (int)MO.getImmedValue(); + break; + case MachineOperand::MO_MachineBasicBlock: + assert(0 && "not implemented"); + abort(); + return; + case MachineOperand::MO_GlobalAddress: + assert(0 && "not implemented"); + abort(); + break; + case MachineOperand::MO_ExternalSymbol: + assert(0 && "not implemented"); + abort(); + break; + case MachineOperand::MO_ConstantPoolIndex: + assert(0 && "not implemented"); + abort(); + break; + default: + O << ""; abort (); break; + } } void ARMAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum, From lattner at cs.uiuc.edu Thu May 25 11:54:28 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 25 May 2006 11:54:28 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Message-ID: <200605251654.LAA27577@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelDAGToDAG.cpp updated: 1.189 -> 1.190 --- Log message: Fix Benchmarks/MallocBench/cfrac --- Diffs of the changes: (+2 -0) PPCISelDAGToDAG.cpp | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.189 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.190 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.189 Wed May 24 19:24:27 2006 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Thu May 25 11:54:16 2006 @@ -714,8 +714,10 @@ switch (CC) { default: assert(0 && "Unknown condition!"); abort(); case ISD::SETOEQ: // FIXME: This is incorrect see PR642. + case ISD::SETUEQ: case ISD::SETEQ: return PPC::BEQ; case ISD::SETONE: // FIXME: This is incorrect see PR642. + case ISD::SETUNE: case ISD::SETNE: return PPC::BNE; case ISD::SETOLT: // FIXME: This is incorrect see PR642. case ISD::SETULT: From lattner at cs.uiuc.edu Thu May 25 12:25:45 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 25 May 2006 12:25:45 -0500 Subject: [llvm-commits] CVS: llvm-test/SingleSource/Benchmarks/Shootout/fib2.c Message-ID: <200605251725.MAA27721@zion.cs.uiuc.edu> Changes in directory llvm-test/SingleSource/Benchmarks/Shootout: fib2.c updated: 1.2 -> 1.3 --- Log message: Fix fib2 in the PPC JIT --- Diffs of the changes: (+3 -3) fib2.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm-test/SingleSource/Benchmarks/Shootout/fib2.c diff -u llvm-test/SingleSource/Benchmarks/Shootout/fib2.c:1.2 llvm-test/SingleSource/Benchmarks/Shootout/fib2.c:1.3 --- llvm-test/SingleSource/Benchmarks/Shootout/fib2.c:1.2 Tue Jun 8 12:21:42 2004 +++ llvm-test/SingleSource/Benchmarks/Shootout/fib2.c Thu May 25 12:25:32 2006 @@ -1,10 +1,10 @@ /* -*- mode: c -*- - * $Id: fib2.c,v 1.2 2004/06/08 17:21:42 lattner Exp $ + * $Id: fib2.c,v 1.3 2006/05/25 17:25:32 lattner Exp $ * http://www.bagley.org/~doug/shootout/ */ int atoi(char *); -void printf(char *, unsigned long); +#include unsigned long fib(unsigned long n) { @@ -16,7 +16,7 @@ int main(int argc, char *argv[]) { - int N = ((argc == 2) ? atoi(argv[1]) : 43); + int N = ((argc == 2) ? atoi(argv[1]) : 4); printf("%ld\n", fib(N)); return(0); } From lattner at cs.uiuc.edu Thu May 25 13:06:29 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 25 May 2006 13:06:29 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Message-ID: <200605251806.NAA28069@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelDAGToDAG.cpp updated: 1.190 -> 1.191 --- Log message: Fix build failure of povray --- Diffs of the changes: (+2 -0) PPCISelDAGToDAG.cpp | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.190 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.191 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.190 Thu May 25 11:54:16 2006 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Thu May 25 13:06:16 2006 @@ -757,8 +757,10 @@ case ISD::SETULE: case ISD::SETLE: Inv = true; return 1; case ISD::SETOEQ: // FIXME: This is incorrect see PR642. + case ISD::SETUEQ: case ISD::SETEQ: Inv = false; return 2; case ISD::SETONE: // FIXME: This is incorrect see PR642. + case ISD::SETUNE: case ISD::SETNE: Inv = true; return 2; case ISD::SETO: Inv = true; return 3; case ISD::SETUO: Inv = false; return 3; From lattner at cs.uiuc.edu Thu May 25 13:31:26 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 25 May 2006 13:31:26 -0500 Subject: [llvm-commits] CVS: llvm-test/SingleSource/Benchmarks/Shootout/fib2.c Message-ID: <200605251831.NAA28397@zion.cs.uiuc.edu> Changes in directory llvm-test/SingleSource/Benchmarks/Shootout: fib2.c updated: 1.3 -> 1.4 --- Log message: Restore the problem size --- Diffs of the changes: (+2 -2) fib2.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm-test/SingleSource/Benchmarks/Shootout/fib2.c diff -u llvm-test/SingleSource/Benchmarks/Shootout/fib2.c:1.3 llvm-test/SingleSource/Benchmarks/Shootout/fib2.c:1.4 --- llvm-test/SingleSource/Benchmarks/Shootout/fib2.c:1.3 Thu May 25 12:25:32 2006 +++ llvm-test/SingleSource/Benchmarks/Shootout/fib2.c Thu May 25 13:31:14 2006 @@ -1,5 +1,5 @@ /* -*- mode: c -*- - * $Id: fib2.c,v 1.3 2006/05/25 17:25:32 lattner Exp $ + * $Id: fib2.c,v 1.4 2006/05/25 18:31:14 lattner Exp $ * http://www.bagley.org/~doug/shootout/ */ @@ -16,7 +16,7 @@ int main(int argc, char *argv[]) { - int N = ((argc == 2) ? atoi(argv[1]) : 4); + int N = ((argc == 2) ? atoi(argv[1]) : 43); printf("%ld\n", fib(N)); return(0); } From evan.cheng at apple.com Thu May 25 13:56:46 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 25 May 2006 13:56:46 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200605251856.NAA28541@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.212 -> 1.213 --- Log message: Build breakage. --- Diffs of the changes: (+11 -15) X86ISelLowering.cpp | 26 +++++++++++--------------- 1 files changed, 11 insertions(+), 15 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.212 llvm/lib/Target/X86/X86ISelLowering.cpp:1.213 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.212 Wed May 24 19:59:30 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Thu May 25 13:56:34 2006 @@ -555,14 +555,15 @@ switch (Arg.getValueType()) { default: assert(0 && "Unexpected ValueType for argument!"); case MVT::i8: - case MVT::i16: + case MVT::i16: { // Promote the integer to 32 bits. If the input type is signed use a // sign extend, otherwise use a zero extend. unsigned ExtOp = dyn_cast(Op.getOperand(5+2*i+1))->getValue() ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND; Arg = DAG.getNode(ExtOp, MVT::i32, Arg); - // Fallthrough + } + // Fallthrough case MVT::i32: case MVT::f32: { @@ -690,7 +691,6 @@ case MVT::v2i64: case MVT::v4f32: case MVT::v2f64: - case MVT::Vector: Chain = DAG.getCopyFromReg(Chain, X86::XMM0, RetVT, InFlag).getValue(1); ResultVals.push_back(Chain.getValue(0)); NodeTys.push_back(RetVT); @@ -979,16 +979,15 @@ case MVT::f64: MF.addLiveOut(X86::ST0); break; - case MVT::Vector: { - const PackedType *PTy = cast(MF.getFunction()->getReturnType()); - MVT::ValueType EVT; - MVT::ValueType LVT; - unsigned NumRegs = getPackedTypeBreakdown(PTy, EVT, LVT); - assert(NumRegs == 1 && "Unsupported type!"); + case MVT::v16i8: + case MVT::v8i16: + case MVT::v4i32: + case MVT::v2i64: + case MVT::v4f32: + case MVT::v2f64: MF.addLiveOut(X86::XMM0); break; } - } // Return the new list of results. std::vector RetVTs(Op.Val->value_begin(), @@ -1046,14 +1045,13 @@ case MVT::v4i32: case MVT::v2i64: case MVT::v4f32: - case MVT::v2f64: { + case MVT::v2f64: if (NumXMMRegs < 3) NumXMMRegs++; else NumBytes += 16; break; } - } } // Make sure the instruction takes 8n+4 bytes to make sure the start of the @@ -1106,7 +1104,7 @@ case MVT::v4i32: case MVT::v2i64: case MVT::v4f32: - case MVT::v2f64: { + case MVT::v2f64: if (NumXMMRegs < 3) { RegsToPass.push_back(std::make_pair(XMMArgRegs[NumXMMRegs], Arg)); NumXMMRegs++; @@ -1118,7 +1116,6 @@ ArgOffset += 16; } } - } } if (!MemOpChains.empty()) @@ -1202,7 +1199,6 @@ case MVT::v2i64: case MVT::v4f32: case MVT::v2f64: - case MVT::Vector: Chain = DAG.getCopyFromReg(Chain, X86::XMM0, RetVT, InFlag).getValue(1); ResultVals.push_back(Chain.getValue(0)); NodeTys.push_back(RetVT); From evan.cheng at apple.com Thu May 25 15:17:08 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 25 May 2006 15:17:08 -0500 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200605252017.PAA28922@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.206 -> 1.207 --- Log message: Can't trust NodeDepth when checking for possibility of load folding creating a cycle. This increase the search space and will increase compile time (in practice it appears to be small, e.g. 176.gcc goes from 62 sec to 65 sec) that will be addressed later. --- Diffs of the changes: (+5 -7) DAGISelEmitter.cpp | 12 +++++------- 1 files changed, 5 insertions(+), 7 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.206 llvm/utils/TableGen/DAGISelEmitter.cpp:1.207 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.206 Wed May 24 19:21:44 2006 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Thu May 25 15:16:55 2006 @@ -3481,13 +3481,11 @@ OS << " if (found || !Visited.insert(Use).second) return;\n"; OS << " for (unsigned i = 0, e = Use->getNumOperands(); i != e; ++i) {\n"; OS << " SDNode *N = Use->getOperand(i).Val;\n"; - OS << " if (N->getNodeDepth() >= Def->getNodeDepth()) {\n"; - OS << " if (N != Def) {\n"; - OS << " findNonImmUse(N, Def, found, Visited);\n"; - OS << " } else {\n"; - OS << " found = true;\n"; - OS << " break;\n"; - OS << " }\n"; + OS << " if (N != Def) {\n"; + OS << " findNonImmUse(N, Def, found, Visited);\n"; + OS << " } else {\n"; + OS << " found = true;\n"; + OS << " break;\n"; OS << " }\n"; OS << " }\n"; OS << "}\n"; From evan.cheng at apple.com Thu May 25 15:21:31 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 25 May 2006 15:21:31 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/2006-05-25-CycleInDAG.ll Message-ID: <200605252021.PAA28948@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: 2006-05-25-CycleInDAG.ll added (r1.1) --- Log message: New test case. x86 isel was creating a cycle in the DAG. --- Diffs of the changes: (+21 -0) 2006-05-25-CycleInDAG.ll | 21 +++++++++++++++++++++ 1 files changed, 21 insertions(+) Index: llvm/test/Regression/CodeGen/X86/2006-05-25-CycleInDAG.ll diff -c /dev/null llvm/test/Regression/CodeGen/X86/2006-05-25-CycleInDAG.ll:1.1 *** /dev/null Thu May 25 15:21:29 2006 --- llvm/test/Regression/CodeGen/X86/2006-05-25-CycleInDAG.ll Thu May 25 15:21:19 2006 *************** *** 0 **** --- 1,21 ---- + ; RUN: llvm-as < %s | llc -march=x86 + + int %test() { + br bool false, label %cond_next33, label %cond_true12 + + cond_true12: + ret int 0 + + cond_next33: + %tmp44.i = call double %foo( double 0.000000e+00, int 32 ) + %tmp61.i = load ubyte* null + %tmp61.i = cast ubyte %tmp61.i to int + %tmp58.i = or int 0, %tmp61.i + %tmp62.i = or int %tmp58.i, 0 + %tmp62.i = cast int %tmp62.i to double + %tmp64.i = add double %tmp62.i, %tmp44.i + %tmp68.i = call double %foo( double %tmp64.i, int 0 ) + ret int 0 + } + + declare double %foo(double, int) From lattner at cs.uiuc.edu Thu May 25 16:26:07 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 25 May 2006 16:26:07 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/2006-05-10-InvalidIndexUndef.ll Message-ID: <200605252126.QAA29368@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: 2006-05-10-InvalidIndexUndef.ll updated: 1.1 -> 1.2 --- Log message: The patch corresponding to this test had to be reverted as unsafe. --- Diffs of the changes: (+1 -0) 2006-05-10-InvalidIndexUndef.ll | 1 + 1 files changed, 1 insertion(+) Index: llvm/test/Regression/Transforms/InstCombine/2006-05-10-InvalidIndexUndef.ll diff -u llvm/test/Regression/Transforms/InstCombine/2006-05-10-InvalidIndexUndef.ll:1.1 llvm/test/Regression/Transforms/InstCombine/2006-05-10-InvalidIndexUndef.ll:1.2 --- llvm/test/Regression/Transforms/InstCombine/2006-05-10-InvalidIndexUndef.ll:1.1 Wed May 24 12:34:02 2006 +++ llvm/test/Regression/Transforms/InstCombine/2006-05-10-InvalidIndexUndef.ll Thu May 25 16:25:54 2006 @@ -1,4 +1,5 @@ ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep undef +; XFAIL: * %str = constant [4 x ubyte] c"str\00" From lattner at cs.uiuc.edu Thu May 25 16:25:25 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 25 May 2006 16:25:25 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/Local.cpp Message-ID: <200605252125.QAA29309@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: Local.cpp updated: 1.56 -> 1.57 --- Log message: Revert a patch that is unsafe, due to out of range array accesses in inner array scopes possibly accessing valid memory in outer subscripts. --- Diffs of the changes: (+2 -2) Local.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Transforms/Utils/Local.cpp diff -u llvm/lib/Transforms/Utils/Local.cpp:1.56 llvm/lib/Transforms/Utils/Local.cpp:1.57 --- llvm/lib/Transforms/Utils/Local.cpp:1.56 Wed May 24 12:34:30 2006 +++ llvm/lib/Transforms/Utils/Local.cpp Thu May 25 16:25:12 2006 @@ -274,7 +274,7 @@ } else if (ConstantInt *CI = dyn_cast(I.getOperand())) { if (const ArrayType *ATy = dyn_cast(*I)) { if ((uint64_t)CI->getRawValue() >= ATy->getNumElements()) - C = UndefValue::get(ATy->getElementType()); + return 0; if (ConstantArray *CA = dyn_cast(C)) C = CA->getOperand((unsigned)CI->getRawValue()); else if (isa(C)) @@ -285,7 +285,7 @@ return 0; } else if (const PackedType *PTy = dyn_cast(*I)) { if ((uint64_t)CI->getRawValue() >= PTy->getNumElements()) - C = UndefValue::get(PTy->getElementType()); + return 0; if (ConstantPacked *CP = dyn_cast(C)) C = CP->getOperand((unsigned)CI->getRawValue()); else if (isa(C)) From evan.cheng at apple.com Thu May 25 16:59:20 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 25 May 2006 16:59:20 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp X86AsmPrinter.cpp X86AsmPrinter.h X86Subtarget.cpp Message-ID: <200605252159.QAA29714@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ATTAsmPrinter.cpp updated: 1.47 -> 1.48 X86AsmPrinter.cpp updated: 1.181 -> 1.182 X86AsmPrinter.h updated: 1.18 -> 1.19 X86Subtarget.cpp updated: 1.26 -> 1.27 --- Log message: X86 / Cygwin asm / alignment fixes. Patch contributed by Anton Korobeynikov! --- Diffs of the changes: (+42 -30) X86ATTAsmPrinter.cpp | 32 ++++++++++++++++++++------------ X86AsmPrinter.cpp | 30 +++++++++++++++++------------- X86AsmPrinter.h | 8 ++++---- X86Subtarget.cpp | 2 +- 4 files changed, 42 insertions(+), 30 deletions(-) Index: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp diff -u llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.47 llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.48 --- llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.47 Tue May 16 02:21:53 2006 +++ llvm/lib/Target/X86/X86ATTAsmPrinter.cpp Thu May 25 16:59:08 2006 @@ -26,11 +26,9 @@ /// method to print assembly for each instruction. /// bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) { - // if (forDarwin) { - // Let PassManager know we need debug information and relay - // the MachineDebugInfo address on to DwarfWriter. - DW.SetDebugInfo(&getAnalysis()); - // } + // Let PassManager know we need debug information and relay + // the MachineDebugInfo address on to DwarfWriter. + DW.SetDebugInfo(&getAnalysis()); SetupMachineFunction(MF); O << "\n\n"; @@ -56,11 +54,17 @@ break; case Function::WeakLinkage: case Function::LinkOnceLinkage: - if (forDarwin) { + if (Subtarget->TargetType == X86Subtarget::isDarwin) { SwitchToTextSection( ".section __TEXT,__textcoal_nt,coalesced,pure_instructions", F); O << "\t.globl\t" << CurrentFnName << "\n"; O << "\t.weak_definition\t" << CurrentFnName << "\n"; + } else if (Subtarget->TargetType == X86Subtarget::isCygwin) { + EmitAlignment(4, F); // FIXME: This should be parameterized somewhere. + O << "\t.section\t.llvm.linkonce.t." << CurrentFnName + << ",\"ax\"\n"; + SwitchToTextSection("", F); + O << "\t.weak " << CurrentFnName << "\n"; } else { EmitAlignment(4, F); // FIXME: This should be parameterized somewhere. O << "\t.section\t.llvm.linkonce.t." << CurrentFnName @@ -72,7 +76,7 @@ } O << CurrentFnName << ":\n"; - if (forDarwin) { + if (Subtarget->TargetType == X86Subtarget::isDarwin) { // Emit pre-function debug information. DW.BeginFunction(&MF); } @@ -95,7 +99,7 @@ if (HasDotTypeDotSizeDirective) O << "\t.size " << CurrentFnName << ", .-" << CurrentFnName << "\n"; - if (forDarwin) { + if (Subtarget->TargetType == X86Subtarget::isDarwin) { // Emit post-function debug information. DW.EndFunction(); } @@ -145,7 +149,8 @@ if (!isMemOp) O << '$'; O << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_" << MO.getConstantPoolIndex(); - if (forDarwin && TM.getRelocationModel() == Reloc::PIC) + if (Subtarget->TargetType == X86Subtarget::isDarwin && + TM.getRelocationModel() == Reloc::PIC) O << "-\"L" << getFunctionNumber() << "$pb\""; int Offset = MO.getOffset(); if (Offset > 0) @@ -159,7 +164,8 @@ bool isMemOp = Modifier && !strcmp(Modifier, "mem"); if (!isMemOp && !isCallOp) O << '$'; // Darwin block shameless ripped from PPCAsmPrinter.cpp - if (forDarwin && TM.getRelocationModel() != Reloc::Static) { + if (Subtarget->TargetType == X86Subtarget::isDarwin && + TM.getRelocationModel() != Reloc::Static) { GlobalValue *GV = MO.getGlobal(); std::string Name = Mang->getValueName(GV); // Link-once, External, or Weakly-linked global variables need @@ -190,7 +196,9 @@ } case MachineOperand::MO_ExternalSymbol: { bool isCallOp = Modifier && !strcmp(Modifier, "call"); - if (isCallOp && forDarwin && TM.getRelocationModel() != Reloc::Static) { + if (isCallOp && + Subtarget->TargetType == X86Subtarget::isDarwin && + TM.getRelocationModel() != Reloc::Static) { std::string Name(GlobalPrefix); Name += MO.getSymbolName(); FnStubs.insert(Name); @@ -332,7 +340,7 @@ void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) { ++EmittedInsts; // This works around some Darwin assembler bugs. - if (forDarwin) { + if (Subtarget->TargetType == X86Subtarget::isDarwin) { switch (MI->getOpcode()) { case X86::REP_MOVSB: O << "rep/movsb (%esi),(%edi)\n"; Index: llvm/lib/Target/X86/X86AsmPrinter.cpp diff -u llvm/lib/Target/X86/X86AsmPrinter.cpp:1.181 llvm/lib/Target/X86/X86AsmPrinter.cpp:1.182 --- llvm/lib/Target/X86/X86AsmPrinter.cpp:1.181 Tue May 9 00:12:53 2006 +++ llvm/lib/Target/X86/X86AsmPrinter.cpp Thu May 25 16:59:08 2006 @@ -46,9 +46,6 @@ /// doInitialization bool X86SharedAsmPrinter::doInitialization(Module &M) { - const X86Subtarget *Subtarget = &TM.getSubtarget(); - - forDarwin = false; PrivateGlobalPrefix = ".L"; DefaultTextSection = ".text"; DefaultDataSection = ".data"; @@ -65,7 +62,6 @@ LCOMMDirective = "\t.lcomm\t"; COMMDirectiveTakesAlignment = false; HasDotTypeDotSizeDirective = false; - forDarwin = true; StaticCtorsSection = ".mod_init_func"; StaticDtorsSection = ".mod_term_func"; InlineAsmStart = "# InlineAsm Start"; @@ -75,6 +71,8 @@ GlobalPrefix = "_"; COMMDirectiveTakesAlignment = false; HasDotTypeDotSizeDirective = false; + StaticCtorsSection = "\t.section .ctors,\"aw\""; + StaticDtorsSection = "\t.section .dtors,\"aw\""; break; case X86Subtarget::isWindows: GlobalPrefix = "_"; @@ -83,7 +81,7 @@ default: break; } - if (forDarwin) { + if (Subtarget->TargetType == X86Subtarget::isDarwin) { // Emit initial debug information. DW.BeginModule(&M); } @@ -114,7 +112,8 @@ if (C->isNullValue() && /* FIXME: Verify correct */ (I->hasInternalLinkage() || I->hasWeakLinkage() || I->hasLinkOnceLinkage() || - (forDarwin && I->hasExternalLinkage() && !I->hasSection()))) { + (Subtarget->TargetType == X86Subtarget::isDarwin && + I->hasExternalLinkage() && !I->hasSection()))) { if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. if (I->hasExternalLinkage()) { O << "\t.globl\t" << name << "\n"; @@ -125,13 +124,15 @@ if (LCOMMDirective != NULL) { if (I->hasInternalLinkage()) { O << LCOMMDirective << name << "," << Size; - if (forDarwin) + if (Subtarget->TargetType == X86Subtarget::isDarwin) O << "," << (AlignmentIsInBytes ? (1 << Align) : Align); } else O << COMMDirective << name << "," << Size; } else { - if (I->hasInternalLinkage()) - O << "\t.local\t" << name << "\n"; + if (Subtarget->TargetType == X86Subtarget::isCygwin) { + if (I->hasInternalLinkage()) + O << "\t.local\t" << name << "\n"; + } O << COMMDirective << name << "," << Size; if (COMMDirectiveTakesAlignment) O << "," << (AlignmentIsInBytes ? (1 << Align) : Align); @@ -142,13 +143,16 @@ switch (I->getLinkage()) { case GlobalValue::LinkOnceLinkage: case GlobalValue::WeakLinkage: - if (forDarwin) { + if (Subtarget->TargetType == X86Subtarget::isDarwin) { O << "\t.globl " << name << "\n" << "\t.weak_definition " << name << "\n"; SwitchToDataSection(".section __DATA,__datacoal_nt,coalesced", I); + } else if (Subtarget->TargetType == X86Subtarget::isCygwin) { + O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\"\n" + << "\t.weak " << name << "\n"; } else { - O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\", at progbits\n"; - O << "\t.weak " << name << "\n"; + O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\", at progbits\n" + << "\t.weak " << name << "\n"; } break; case GlobalValue::AppendingLinkage: @@ -176,7 +180,7 @@ } } - if (forDarwin) { + if (Subtarget->TargetType == X86Subtarget::isDarwin) { SwitchToDataSection("", 0); // Output stubs for dynamically-linked functions Index: llvm/lib/Target/X86/X86AsmPrinter.h diff -u llvm/lib/Target/X86/X86AsmPrinter.h:1.18 llvm/lib/Target/X86/X86AsmPrinter.h:1.19 --- llvm/lib/Target/X86/X86AsmPrinter.h:1.18 Tue May 9 00:12:53 2006 +++ llvm/lib/Target/X86/X86AsmPrinter.h Thu May 25 16:59:08 2006 @@ -57,7 +57,9 @@ X86DwarfWriter DW; X86SharedAsmPrinter(std::ostream &O, X86TargetMachine &TM) - : AsmPrinter(O, TM), DW(O, this), forDarwin(false) { } + : AsmPrinter(O, TM), DW(O, this) { + Subtarget = &TM.getSubtarget(); + } bool doInitialization(Module &M); bool doFinalization(Module &M); @@ -68,11 +70,9 @@ MachineFunctionPass::getAnalysisUsage(AU); } - bool forDarwin; // FIXME: eliminate. - const char *DefaultTextSection; // "_text" for MASM, ".text" for others. const char *DefaultDataSection; // "_data" for MASM, ".data" for others. - + const X86Subtarget *Subtarget; // Necessary for Darwin to print out the apprioriate types of linker stubs std::set FnStubs, GVStubs, LinkOnceStubs; Index: llvm/lib/Target/X86/X86Subtarget.cpp diff -u llvm/lib/Target/X86/X86Subtarget.cpp:1.26 llvm/lib/Target/X86/X86Subtarget.cpp:1.27 --- llvm/lib/Target/X86/X86Subtarget.cpp:1.26 Fri Feb 17 18:15:05 2006 +++ llvm/lib/Target/X86/X86Subtarget.cpp Thu May 25 16:59:08 2006 @@ -182,6 +182,6 @@ #endif } - if (TargetType == isDarwin) + if (TargetType == isDarwin || TargetType == isCygwin) stackAlignment = 16; } From evan.cheng at apple.com Thu May 25 17:26:04 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 25 May 2006 17:26:04 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200605252226.RAA29875@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.213 -> 1.214 --- Log message: Remove some dead code. --- Diffs of the changes: (+0 -21) X86ISelLowering.cpp | 21 --------------------- 1 files changed, 21 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.213 llvm/lib/Target/X86/X86ISelLowering.cpp:1.214 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.213 Thu May 25 13:56:34 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Thu May 25 17:25:52 2006 @@ -403,27 +403,6 @@ } } -/// getFormalArgObjects - Returns itself if Op is a FORMAL_ARGUMENTS, otherwise -/// returns the FORMAL_ARGUMENTS node(s) that made up parts of the node. -static std::vector getFormalArgObjects(SDOperand Op) { - unsigned Opc = Op.getOpcode(); - std::vector Objs; - if (Opc == ISD::TRUNCATE) { - Op = Op.getOperand(0); - assert(Op.getOpcode() == ISD::AssertSext || - Op.getOpcode() == ISD::AssertZext); - Objs.push_back(Op.getOperand(0)); - } else if (Opc == ISD::FP_ROUND || Opc == ISD::VBIT_CONVERT) { - Objs.push_back(Op.getOperand(0)); - } else if (Opc == ISD::BUILD_PAIR) { - Objs.push_back(Op.getOperand(0)); - Objs.push_back(Op.getOperand(1)); - } else { - Objs.push_back(Op); - } - return Objs; -} - SDOperand X86TargetLowering::LowerCCCArguments(SDOperand Op, SelectionDAG &DAG) { unsigned NumArgs = Op.Val->getNumValues() - 1; MachineFunction &MF = DAG.getMachineFunction(); From lattner at cs.uiuc.edu Thu May 25 17:26:14 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 25 May 2006 17:26:14 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp Message-ID: <200605252226.RAA29885@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcISelDAGToDAG.cpp updated: 1.96 -> 1.97 --- Log message: Add support for the missing FP condition codes --- Diffs of the changes: (+12 -6) SparcISelDAGToDAG.cpp | 18 ++++++++++++------ 1 files changed, 12 insertions(+), 6 deletions(-) Index: llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp diff -u llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp:1.96 llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp:1.97 --- llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp:1.96 Wed May 24 19:24:27 2006 +++ llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp Thu May 25 17:26:02 2006 @@ -75,12 +75,18 @@ static SPCC::CondCodes FPCondCCodeToFCC(ISD::CondCode CC) { switch (CC) { default: assert(0 && "Unknown fp condition code!"); - case ISD::SETEQ: return SPCC::FCC_E; - case ISD::SETNE: return SPCC::FCC_NE; - case ISD::SETLT: return SPCC::FCC_L; - case ISD::SETGT: return SPCC::FCC_G; - case ISD::SETLE: return SPCC::FCC_LE; - case ISD::SETGE: return SPCC::FCC_GE; + case ISD::SETEQ: + case ISD::SETOEQ: return SPCC::FCC_E; + case ISD::SETNE: + case ISD::SETUNE: return SPCC::FCC_NE; + case ISD::SETLT: + case ISD::SETOLT: return SPCC::FCC_L; + case ISD::SETGT: + case ISD::SETOGT: return SPCC::FCC_G; + case ISD::SETLE: + case ISD::SETOLE: return SPCC::FCC_LE; + case ISD::SETGE: + case ISD::SETOGE: return SPCC::FCC_GE; case ISD::SETULT: return SPCC::FCC_UL; case ISD::SETULE: return SPCC::FCC_ULE; case ISD::SETUGT: return SPCC::FCC_UG; From evan.cheng at apple.com Thu May 25 17:38:44 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 25 May 2006 17:38:44 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200605252238.RAA29952@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.214 -> 1.215 --- Log message: Some clean up. --- Diffs of the changes: (+3 -4) X86ISelLowering.cpp | 7 +++---- 1 files changed, 3 insertions(+), 4 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.214 llvm/lib/Target/X86/X86ISelLowering.cpp:1.215 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.214 Thu May 25 17:25:52 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Thu May 25 17:38:31 2006 @@ -510,14 +510,13 @@ case MVT::v4i32: case MVT::v2i64: case MVT::v4f32: - case MVT::v2f64: { + case MVT::v2f64: if (NumXMMRegs < 3) ++NumXMMRegs; else NumBytes += 16; break; } - } } Chain = DAG.getCALLSEQ_START(Chain,DAG.getConstant(NumBytes, getPointerTy())); @@ -567,7 +566,7 @@ case MVT::v4i32: case MVT::v2i64: case MVT::v4f32: - case MVT::v2f64: { + case MVT::v2f64: if (NumXMMRegs < 3) { RegsToPass.push_back(std::make_pair(XMMArgRegs[NumXMMRegs], Arg)); NumXMMRegs++; @@ -579,7 +578,6 @@ ArgOffset += 16; } } - } } if (!MemOpChains.empty()) @@ -1013,6 +1011,7 @@ ++NumIntRegs; break; } + // Fall through case MVT::f32: NumBytes += 4; break; From lattner at cs.uiuc.edu Thu May 25 17:53:01 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 25 May 2006 17:53:01 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/vec_shuffle.ll Message-ID: <200605252253.RAA30050@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: vec_shuffle.ll updated: 1.2 -> 1.3 --- Log message: new testcases --- Diffs of the changes: (+12 -0) vec_shuffle.ll | 12 ++++++++++++ 1 files changed, 12 insertions(+) Index: llvm/test/Regression/Transforms/InstCombine/vec_shuffle.ll diff -u llvm/test/Regression/Transforms/InstCombine/vec_shuffle.ll:1.2 llvm/test/Regression/Transforms/InstCombine/vec_shuffle.ll:1.3 --- llvm/test/Regression/Transforms/InstCombine/vec_shuffle.ll:1.2 Mon Apr 10 18:06:18 2006 +++ llvm/test/Regression/Transforms/InstCombine/vec_shuffle.ll Thu May 25 17:52:49 2006 @@ -22,3 +22,15 @@ ret float %E } +int %test4(<4 x int> %X) { + %tmp152.i53899.i = shufflevector <4 x int> %X, <4 x int> undef, <4 x uint> zeroinitializer + %tmp34 = extractelement <4 x int> %tmp152.i53899.i, uint 0 + ret int %tmp34 +} + +int %test5(<4 x int> %X) { + %tmp152.i53899.i = shufflevector <4 x int> %X, <4 x int> undef, <4 x uint> + %tmp34 = extractelement <4 x int> %tmp152.i53899.i, uint 0 + ret int %tmp34 +} + From lattner at cs.uiuc.edu Thu May 25 17:53:51 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 25 May 2006 17:53:51 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200605252253.RAA30085@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.483 -> 1.484 --- Log message: extract element from a shuffle vector can be trivially turned into an extractelement from the SV's source. This implement vec_shuffle.ll:test[45] --- Diffs of the changes: (+41 -12) InstructionCombining.cpp | 53 ++++++++++++++++++++++++++++++++++++----------- 1 files changed, 41 insertions(+), 12 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.483 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.484 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.483 Sat May 20 18:14:03 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Thu May 25 17:53:38 2006 @@ -7072,7 +7072,7 @@ return ReplaceInstUsesWith(EI, Elt); } - if (Instruction *I = dyn_cast(EI.getOperand(0))) + if (Instruction *I = dyn_cast(EI.getOperand(0))) { if (I->hasOneUse()) { // Push extractelement into predecessor operation if legal and // profitable to do so @@ -7097,20 +7097,49 @@ I->getName() + ".gep"); InsertNewInstBefore(GEP, EI); return new LoadInst(GEP); - } else if (InsertElementInst *IE = dyn_cast(I)) { - // Extracting the inserted element? - if (IE->getOperand(2) == EI.getOperand(1)) - return ReplaceInstUsesWith(EI, IE->getOperand(1)); - // If the inserted and extracted elements are constants, they must not - // be the same value, extract from the pre-inserted value instead. - if (isa(IE->getOperand(2)) && - isa(EI.getOperand(1))) { - AddUsesToWorkList(EI); - EI.setOperand(0, IE->getOperand(0)); - return &EI; + } + } + if (InsertElementInst *IE = dyn_cast(I)) { + // Extracting the inserted element? + if (IE->getOperand(2) == EI.getOperand(1)) + return ReplaceInstUsesWith(EI, IE->getOperand(1)); + // If the inserted and extracted elements are constants, they must not + // be the same value, extract from the pre-inserted value instead. + if (isa(IE->getOperand(2)) && + isa(EI.getOperand(1))) { + AddUsesToWorkList(EI); + EI.setOperand(0, IE->getOperand(0)); + return &EI; + } + } else if (ShuffleVectorInst *SVI = dyn_cast(I)) { + // If this is extracting an element from a shufflevector, figure out where + // it came from and extract from the appropriate input element instead. + if (ConstantUInt *Elt = dyn_cast(EI.getOperand(1))) { + unsigned ExtractedIdx = Elt->getValue(); + if (ConstantPacked *CP = dyn_cast(SVI->getOperand(2))) { + unsigned Idx = 0; + if (ConstantUInt *CI = + dyn_cast(CP->getOperand(ExtractedIdx))) + Idx = CI->getValue(); + Value *Src; + if (Idx < CP->getNumOperands()) + Src = SVI->getOperand(0); + else { + Idx -= CP->getNumOperands(); + Src = SVI->getOperand(0); + } + return new ExtractElementInst(Src, + ConstantUInt::get(Type::UIntTy, Idx)); + + } else if (isa(SVI->getOperand(2))) { + // If extracting from a splat of the 0th element, return an extract + // of the zero'th element of the input to the splat. + return new ExtractElementInst(SVI->getOperand(0), + ConstantUInt::get(Type::UIntTy, 0)); } } } + } return 0; } From lattner at cs.uiuc.edu Thu May 25 18:23:34 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 25 May 2006 18:23:34 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/vec_shuffle.ll Message-ID: <200605252323.SAA30238@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: vec_shuffle.ll updated: 1.3 -> 1.4 --- Log message: new testcase --- Diffs of the changes: (+8 -0) vec_shuffle.ll | 8 ++++++++ 1 files changed, 8 insertions(+) Index: llvm/test/Regression/Transforms/InstCombine/vec_shuffle.ll diff -u llvm/test/Regression/Transforms/InstCombine/vec_shuffle.ll:1.3 llvm/test/Regression/Transforms/InstCombine/vec_shuffle.ll:1.4 --- llvm/test/Regression/Transforms/InstCombine/vec_shuffle.ll:1.3 Thu May 25 17:52:49 2006 +++ llvm/test/Regression/Transforms/InstCombine/vec_shuffle.ll Thu May 25 18:23:22 2006 @@ -34,3 +34,11 @@ ret int %tmp34 } +float %test6(<4 x float> %X) { + %X = cast <4 x float> %X to <4 x int> + %tmp152.i53899.i = shufflevector <4 x int> %X, <4 x int> undef, <4 x uint> zeroinitializer + %tmp152.i53900.i = cast <4 x int> %tmp152.i53899.i to <4 x float> + %tmp34 = extractelement <4 x float> %tmp152.i53900.i, uint 0 + ret float %tmp34 +} + From lattner at cs.uiuc.edu Thu May 25 18:24:49 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 25 May 2006 18:24:49 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200605252324.SAA30283@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.484 -> 1.485 --- Log message: Turn (cast (shuffle (cast)) -> shuffle (cast) if it reduces the # casts in the program. This exposes more opportunities for the instcombiner, and implements vec_shuffle.ll:test6 --- Diffs of the changes: (+31 -2) InstructionCombining.cpp | 33 +++++++++++++++++++++++++++++++-- 1 files changed, 31 insertions(+), 2 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.484 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.485 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.484 Thu May 25 17:53:38 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Thu May 25 18:24:33 2006 @@ -413,7 +413,7 @@ if (V->getType()->isLosslesslyConvertibleTo(Ty)) return false; - // If this is another cast that can be elimianted, it isn't codegen either. + // If this is another cast that can be eliminated, it isn't codegen either. if (const CastInst *CI = dyn_cast(V)) if (isEliminableCastOfCast(CI->getOperand(0)->getType(), CI->getType(), Ty, TD)) @@ -4970,7 +4970,7 @@ // If the source value is an instruction with only this use, we can attempt to // propagate the cast into the instruction. Also, only handle integral types // for now. - if (Instruction *SrcI = dyn_cast(Src)) + if (Instruction *SrcI = dyn_cast(Src)) { if (SrcI->hasOneUse() && Src->getType()->isIntegral() && CI.getType()->isInteger()) { // Don't mess with casts to bool here @@ -5152,6 +5152,35 @@ break; } } + + if (SrcI->hasOneUse()) { + if (ShuffleVectorInst *SVI = dyn_cast(SrcI)) { + // Okay, we have (cast (shuffle ..)). We know this cast is a bitconvert + // because the inputs are known to be a vector. Check to see if this is + // a cast to a vector with the same # elts. + if (isa(CI.getType()) && + cast(CI.getType())->getNumElements() == + SVI->getType()->getNumElements()) { + CastInst *Tmp; + // If either of the operands is a cast from CI.getType(), then + // evaluating the shuffle in the casted destination's type will allow + // us to eliminate at least one cast. + if (((Tmp = dyn_cast(SVI->getOperand(0))) && + Tmp->getOperand(0)->getType() == CI.getType()) || + ((Tmp = dyn_cast(SVI->getOperand(1))) && + Tmp->getOperand(1)->getType() == CI.getType())) { + Value *LHS = InsertOperandCastBefore(SVI->getOperand(0), + CI.getType(), &CI); + Value *RHS = InsertOperandCastBefore(SVI->getOperand(1), + CI.getType(), &CI); + // Return a new shuffle vector. Use the same element ID's, as we + // know the vector types match #elts. + return new ShuffleVectorInst(LHS, RHS, SVI->getOperand(2)); + } + } + } + } + } return 0; } From evan.cheng at apple.com Thu May 25 18:31:35 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 25 May 2006 18:31:35 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200605252331.SAA30313@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.215 -> 1.216 --- Log message: Consistency --- Diffs of the changes: (+3 -0) X86ISelLowering.cpp | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.215 llvm/lib/Target/X86/X86ISelLowering.cpp:1.216 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.215 Thu May 25 17:38:31 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Thu May 25 18:31:23 2006 @@ -380,6 +380,8 @@ static void HowToPassCCCArgument(MVT::ValueType ObjectVT, unsigned NumXMMRegs, unsigned &ObjSize, unsigned &ObjXMMRegs) { + NumXMMRegs = 0; + switch (ObjectVT) { default: assert(0 && "Unhandled argument type!"); case MVT::i1: @@ -774,6 +776,7 @@ unsigned &ObjXMMRegs) { ObjSize = 0; NumIntRegs = 0; + NumXMMRegs = 0; switch (ObjectVT) { default: assert(0 && "Unhandled argument type!"); From lattner at cs.uiuc.edu Thu May 25 18:48:50 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 25 May 2006 18:48:50 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200605252348.SAA30437@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.485 -> 1.486 --- Log message: Introduce a helper function that simplifies interpretation of shuffle masks. No functionality change. --- Diffs of the changes: (+64 -91) InstructionCombining.cpp | 155 +++++++++++++++++++---------------------------- 1 files changed, 64 insertions(+), 91 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.485 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.486 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.485 Thu May 25 18:24:33 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Thu May 25 18:48:38 2006 @@ -7024,6 +7024,25 @@ return false; } +/// getShuffleMask - Read and decode a shufflevector mask. It turns undef +/// elements into values that are larger than the #elts in the input. +static std::vector getShuffleMask(const ShuffleVectorInst *SVI) { + unsigned NElts = SVI->getType()->getNumElements(); + if (isa(SVI->getOperand(2))) + return std::vector(NElts, 0); + if (isa(SVI->getOperand(2))) + return std::vector(NElts, 2*NElts); + + std::vector Result; + const ConstantPacked *CP = cast(SVI->getOperand(2)); + for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i) + if (isa(CP->getOperand(i))) + Result.push_back(NElts*2); // undef -> 8 + else + Result.push_back(cast(CP->getOperand(i))->getValue()); + return Result; +} + /// FindScalarElement - Given a vector and an element number, see if the scalar /// value is already around as a register, for example if it were inserted then /// extracted from the vector. @@ -7053,18 +7072,13 @@ // vector input. return FindScalarElement(III->getOperand(0), EltNo); } else if (ShuffleVectorInst *SVI = dyn_cast(V)) { - if (isa(SVI->getOperand(2))) { - return FindScalarElement(SVI->getOperand(0), 0); - } else if (ConstantPacked *CP = - dyn_cast(SVI->getOperand(2))) { - if (isa(CP->getOperand(EltNo))) - return UndefValue::get(PTy->getElementType()); - unsigned InEl = cast(CP->getOperand(EltNo))->getValue(); - if (InEl < Width) - return FindScalarElement(SVI->getOperand(0), InEl); - else - return FindScalarElement(SVI->getOperand(1), InEl - Width); - } + unsigned InEl = getShuffleMask(SVI)[EltNo]; + if (InEl < Width) + return FindScalarElement(SVI->getOperand(0), InEl); + else if (InEl < Width*2) + return FindScalarElement(SVI->getOperand(1), InEl - Width); + else + return UndefValue::get(PTy->getElementType()); } // Otherwise, we don't know. @@ -7144,28 +7158,18 @@ // If this is extracting an element from a shufflevector, figure out where // it came from and extract from the appropriate input element instead. if (ConstantUInt *Elt = dyn_cast(EI.getOperand(1))) { - unsigned ExtractedIdx = Elt->getValue(); - if (ConstantPacked *CP = dyn_cast(SVI->getOperand(2))) { - unsigned Idx = 0; - if (ConstantUInt *CI = - dyn_cast(CP->getOperand(ExtractedIdx))) - Idx = CI->getValue(); - Value *Src; - if (Idx < CP->getNumOperands()) - Src = SVI->getOperand(0); - else { - Idx -= CP->getNumOperands(); - Src = SVI->getOperand(0); - } - return new ExtractElementInst(Src, - ConstantUInt::get(Type::UIntTy, Idx)); - - } else if (isa(SVI->getOperand(2))) { - // If extracting from a splat of the 0th element, return an extract - // of the zero'th element of the input to the splat. - return new ExtractElementInst(SVI->getOperand(0), - ConstantUInt::get(Type::UIntTy, 0)); + unsigned SrcIdx = getShuffleMask(SVI)[Elt->getValue()]; + Value *Src; + if (SrcIdx < SVI->getType()->getNumElements()) + Src = SVI->getOperand(0); + else if (SrcIdx < SVI->getType()->getNumElements()*2) { + SrcIdx -= SVI->getType()->getNumElements(); + Src = SVI->getOperand(1); + } else { + return ReplaceInstUsesWith(EI, UndefValue::get(EI.getType())); } + return new ExtractElementInst(Src, + ConstantUInt::get(Type::UIntTy, SrcIdx)); } } } @@ -7373,84 +7377,53 @@ Instruction *InstCombiner::visitShuffleVectorInst(ShuffleVectorInst &SVI) { Value *LHS = SVI.getOperand(0); Value *RHS = SVI.getOperand(1); - Constant *Mask = cast(SVI.getOperand(2)); + std::vector Mask = getShuffleMask(&SVI); bool MadeChange = false; - if (isa(Mask)) + if (isa(SVI.getOperand(2))) return ReplaceInstUsesWith(SVI, UndefValue::get(SVI.getType())); // TODO: If we have shuffle(x, undef, mask) and any elements of mask refer to // the undef, change them to undefs. - // Canonicalize shuffle(x,x) -> shuffle(x,undef) - if (LHS == RHS) { - if (isa(LHS)) { + // Canonicalize shuffle(x ,x,mask) -> shuffle(x, undef,mask') + // Canonicalize shuffle(undef,x,mask) -> shuffle(x, undef,mask'). + if (LHS == RHS || isa(LHS)) { + if (isa(LHS) && LHS == RHS) { // shuffle(undef,undef,mask) -> undef. return ReplaceInstUsesWith(SVI, LHS); } - if (!isa(Mask)) { - // Remap any references to RHS to use LHS. - ConstantPacked *CP = cast(Mask); - std::vector Elts; - for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i) { - Elts.push_back(CP->getOperand(i)); - if (isa(CP->getOperand(i))) - continue; - unsigned MV = cast(CP->getOperand(i))->getRawValue(); - if (MV >= e) - Elts.back() = ConstantUInt::get(Type::UIntTy, MV & (e-1)); - } - Mask = ConstantPacked::get(Elts); + // Remap any references to RHS to use LHS. + std::vector Elts; + for (unsigned i = 0, e = Mask.size(); i != e; ++i) { + if (Mask[i] > 2*e) + Elts.push_back(UndefValue::get(Type::UIntTy)); + else + Elts.push_back(ConstantUInt::get(Type::UIntTy, Mask[i] & (e-1))); } + SVI.setOperand(0, SVI.getOperand(1)); SVI.setOperand(1, UndefValue::get(RHS->getType())); - SVI.setOperand(2, Mask); + SVI.setOperand(2, ConstantPacked::get(Elts)); MadeChange = true; } - // Canonicalize shuffle(undef,x,mask) -> shuffle(x, undef,mask'). - if (isa(LHS)) { - // shuffle(undef,x,<0,0,0,0>) -> undef. - if (isa(Mask)) - return ReplaceInstUsesWith(SVI, UndefValue::get(SVI.getType())); + // Analyze the shuffle, are the LHS or RHS and identity shuffle? + bool isLHSID = true, isRHSID = true; - ConstantPacked *CPM = cast(Mask); - std::vector Elts; - for (unsigned i = 0, e = CPM->getNumOperands(); i != e; ++i) { - if (isa(CPM->getOperand(i))) - Elts.push_back(CPM->getOperand(i)); - else { - unsigned EltNo = cast(CPM->getOperand(i))->getRawValue(); - if (EltNo >= e) - Elts.push_back(ConstantUInt::get(Type::UIntTy, EltNo-e)); - else // Referring to the undef. - Elts.push_back(UndefValue::get(Type::UIntTy)); - } - } - return new ShuffleVectorInst(RHS, LHS, ConstantPacked::get(Elts)); - } - - if (ConstantPacked *CP = dyn_cast(Mask)) { - bool isLHSID = true, isRHSID = true; - - // Analyze the shuffle. - for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i) { - if (isa(CP->getOperand(i))) - continue; - unsigned MV = cast(CP->getOperand(i))->getRawValue(); + for (unsigned i = 0, e = Mask.size(); i != e; ++i) { + if (Mask[i] >= e*2) continue; // Ignore undef values. + // Is this an identity shuffle of the LHS value? + isLHSID &= (Mask[i] == i); - // Is this an identity shuffle of the LHS value? - isLHSID &= (MV == i); - - // Is this an identity shuffle of the RHS value? - isRHSID &= (MV-e == i); - } - - // Eliminate identity shuffles. - if (isLHSID) return ReplaceInstUsesWith(SVI, LHS); - if (isRHSID) return ReplaceInstUsesWith(SVI, RHS); + // Is this an identity shuffle of the RHS value? + isRHSID &= (Mask[i]-e == i); } + + // Eliminate identity shuffles. + if (isLHSID) return ReplaceInstUsesWith(SVI, LHS); + if (isRHSID) return ReplaceInstUsesWith(SVI, RHS); return MadeChange ? &SVI : 0; } From lattner at cs.uiuc.edu Thu May 25 19:29:18 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 25 May 2006 19:29:18 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200605260029.TAA30686@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.486 -> 1.487 --- Log message: Transform things like (splat(splat)) -> splat --- Diffs of the changes: (+50 -4) InstructionCombining.cpp | 54 +++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 50 insertions(+), 4 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.486 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.487 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.486 Thu May 25 18:48:38 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Thu May 25 19:29:06 2006 @@ -7398,18 +7398,26 @@ // Remap any references to RHS to use LHS. std::vector Elts; for (unsigned i = 0, e = Mask.size(); i != e; ++i) { - if (Mask[i] > 2*e) + if (Mask[i] >= 2*e) Elts.push_back(UndefValue::get(Type::UIntTy)); - else - Elts.push_back(ConstantUInt::get(Type::UIntTy, Mask[i] & (e-1))); + else { + if ((Mask[i] >= e && isa(RHS)) || + (Mask[i] < e && isa(LHS))) + Mask[i] = 2*e; // Turn into undef. + else + Mask[i] &= (e-1); // Force to LHS. + Elts.push_back(ConstantUInt::get(Type::UIntTy, Mask[i])); + } } SVI.setOperand(0, SVI.getOperand(1)); SVI.setOperand(1, UndefValue::get(RHS->getType())); SVI.setOperand(2, ConstantPacked::get(Elts)); + LHS = SVI.getOperand(0); + RHS = SVI.getOperand(1); MadeChange = true; } - // Analyze the shuffle, are the LHS or RHS and identity shuffle? + // Analyze the shuffle, are the LHS or RHS and identity shuffles? bool isLHSID = true, isRHSID = true; for (unsigned i = 0, e = Mask.size(); i != e; ++i) { @@ -7425,6 +7433,44 @@ if (isLHSID) return ReplaceInstUsesWith(SVI, LHS); if (isRHSID) return ReplaceInstUsesWith(SVI, RHS); + // If the LHS is a shufflevector itself, see if we can combine it with this + // one without producing an unusual shuffle. Here we are really conservative: + // we are absolutely afraid of producing a shuffle mask not in the input + // program, because the code gen may not be smart enough to turn a merged + // shuffle into two specific shuffles: it may produce worse code. As such, + // we only merge two shuffles if the result is one of the two input shuffle + // masks. In this case, merging the shuffles just removes one instruction, + // which we know is safe. This is good for things like turning: + // (splat(splat)) -> splat. + if (ShuffleVectorInst *LHSSVI = dyn_cast(LHS)) { + if (isa(RHS)) { + std::vector LHSMask = getShuffleMask(LHSSVI); + + std::vector NewMask; + for (unsigned i = 0, e = Mask.size(); i != e; ++i) + if (Mask[i] >= 2*e) + NewMask.push_back(2*e); + else + NewMask.push_back(LHSMask[Mask[i]]); + + // If the result mask is equal to the src shuffle or this shuffle mask, do + // the replacement. + if (NewMask == LHSMask || NewMask == Mask) { + std::vector Elts; + for (unsigned i = 0, e = NewMask.size(); i != e; ++i) { + if (NewMask[i] >= e*2) { + Elts.push_back(UndefValue::get(Type::UIntTy)); + } else { + Elts.push_back(ConstantUInt::get(Type::UIntTy, NewMask[i])); + } + } + return new ShuffleVectorInst(LHSSVI->getOperand(0), + LHSSVI->getOperand(1), + ConstantPacked::get(Elts)); + } + } + } + return MadeChange ? &SVI : 0; } From evan.cheng at apple.com Fri May 26 01:22:47 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 26 May 2006 01:22:47 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86AsmPrinter.cpp Message-ID: <200605260622.BAA32010@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86AsmPrinter.cpp updated: 1.182 -> 1.183 --- Log message: Minor bug caught by Ashwin Chandra --- Diffs of the changes: (+1 -1) X86AsmPrinter.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/X86/X86AsmPrinter.cpp diff -u llvm/lib/Target/X86/X86AsmPrinter.cpp:1.182 llvm/lib/Target/X86/X86AsmPrinter.cpp:1.183 --- llvm/lib/Target/X86/X86AsmPrinter.cpp:1.182 Thu May 25 16:59:08 2006 +++ llvm/lib/Target/X86/X86AsmPrinter.cpp Fri May 26 01:22:34 2006 @@ -129,7 +129,7 @@ } else O << COMMDirective << name << "," << Size; } else { - if (Subtarget->TargetType == X86Subtarget::isCygwin) { + if (Subtarget->TargetType != X86Subtarget::isCygwin) { if (I->hasInternalLinkage()) O << "\t.local\t" << name << "\n"; } From evan.cheng at apple.com Fri May 26 03:00:30 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 26 May 2006 03:00:30 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/MachineInstr.cpp Message-ID: <200605260800.DAA08009@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: MachineInstr.cpp updated: 1.122 -> 1.123 --- Log message: Remove a bogus cast. --- Diffs of the changes: (+1 -1) MachineInstr.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/MachineInstr.cpp diff -u llvm/lib/CodeGen/MachineInstr.cpp:1.122 llvm/lib/CodeGen/MachineInstr.cpp:1.123 --- llvm/lib/CodeGen/MachineInstr.cpp:1.122 Thu May 4 14:36:09 2006 +++ llvm/lib/CodeGen/MachineInstr.cpp Fri May 26 03:00:14 2006 @@ -122,7 +122,7 @@ OutputReg(OS, MO.getReg(), MRI); break; case MachineOperand::MO_Immediate: - OS << (long)MO.getImmedValue(); + OS << MO.getImmedValue(); break; case MachineOperand::MO_MachineBasicBlock: OS << "mbb<" From evan.cheng at apple.com Fri May 26 03:04:45 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 26 May 2006 03:04:45 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp X86IntelAsmPrinter.cpp Message-ID: <200605260804.DAA08045@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ATTAsmPrinter.cpp updated: 1.48 -> 1.49 X86IntelAsmPrinter.cpp updated: 1.50 -> 1.51 --- Log message: Remove a couple of bogus casts. --- Diffs of the changes: (+2 -2) X86ATTAsmPrinter.cpp | 2 +- X86IntelAsmPrinter.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp diff -u llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.48 llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.49 --- llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.48 Thu May 25 16:59:08 2006 +++ llvm/lib/Target/X86/X86ATTAsmPrinter.cpp Fri May 26 03:04:31 2006 @@ -131,7 +131,7 @@ case MachineOperand::MO_Immediate: if (!Modifier || strcmp(Modifier, "debug") != 0) O << '$'; - O << (int)MO.getImmedValue(); + O << MO.getImmedValue(); return; case MachineOperand::MO_MachineBasicBlock: printBasicBlockLabel(MO.getMachineBasicBlock()); Index: llvm/lib/Target/X86/X86IntelAsmPrinter.cpp diff -u llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.50 llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.51 --- llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.50 Tue May 16 02:21:53 2006 +++ llvm/lib/Target/X86/X86IntelAsmPrinter.cpp Fri May 26 03:04:31 2006 @@ -98,7 +98,7 @@ return; case MachineOperand::MO_Immediate: - O << (int)MO.getImmedValue(); + O << MO.getImmedValue(); return; case MachineOperand::MO_MachineBasicBlock: printBasicBlockLabel(MO.getMachineBasicBlock()); From rafael.espindola at gmail.com Fri May 26 05:56:42 2006 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Fri, 26 May 2006 05:56:42 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/ARM/ARMAsmPrinter.cpp ARMInstrInfo.td Message-ID: <200605261056.FAA26472@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/ARM: ARMAsmPrinter.cpp updated: 1.3 -> 1.4 ARMInstrInfo.td updated: 1.2 -> 1.3 --- Log message: On ARM, alignment is in bits Add lr as a hard coded operand of bx --- Diffs of the changes: (+7 -2) ARMAsmPrinter.cpp | 3 ++- ARMInstrInfo.td | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) Index: llvm/lib/Target/ARM/ARMAsmPrinter.cpp diff -u llvm/lib/Target/ARM/ARMAsmPrinter.cpp:1.3 llvm/lib/Target/ARM/ARMAsmPrinter.cpp:1.4 --- llvm/lib/Target/ARM/ARMAsmPrinter.cpp:1.3 Thu May 25 07:57:06 2006 +++ llvm/lib/Target/ARM/ARMAsmPrinter.cpp Fri May 26 05:56:17 2006 @@ -44,6 +44,7 @@ ZeroDirective = "\t.skip\t"; CommentString = "!"; ConstantPoolSection = "\t.section \".rodata\",#alloc\n"; + AlignmentIsInBytes = false; } /// We name each basic block in a Function with a unique number, so @@ -110,7 +111,7 @@ assert(0 && "Not implemented"); break; } - EmitAlignment(4, F); + EmitAlignment(2, F); O << CurrentFnName << ":\n"; // Print out code for the function. Index: llvm/lib/Target/ARM/ARMInstrInfo.td diff -u llvm/lib/Target/ARM/ARMInstrInfo.td:1.2 llvm/lib/Target/ARM/ARMInstrInfo.td:1.3 --- llvm/lib/Target/ARM/ARMInstrInfo.td:1.2 Thu May 18 16:45:49 2006 +++ llvm/lib/Target/ARM/ARMInstrInfo.td Fri May 26 05:56:17 2006 @@ -42,7 +42,11 @@ "!ADJCALLSTACKDOWN $amt", [(callseq_start imm:$amt)]>; -def BX: InstARM<(ops), "bx", [(retflag)]>; +//bx supports other registers as operands. So this looks like a +//hack. Maybe a ret should be expanded to a "branch lr" and bx +//declared as a regular instruction + +def BX: InstARM<(ops), "bx lr", [(retflag)]>; def ldr : InstARM<(ops IntRegs:$dst, IntRegs:$addr), "ldr $dst, [$addr]", From resistor at mac.com Fri May 26 08:58:51 2006 From: resistor at mac.com (Owen Anderson) Date: Fri, 26 May 2006 08:58:51 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/LinkAllPasses.h Scalar.h Message-ID: <200605261358.IAA14289@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms: LinkAllPasses.h updated: 1.30 -> 1.31 Scalar.h updated: 1.64 -> 1.65 --- Log message: Skeletal LCSSA pass. This is currently non-functional. Expect functionality and documentation updates soo. --- Diffs of the changes: (+6 -0) LinkAllPasses.h | 1 + Scalar.h | 5 +++++ 2 files changed, 6 insertions(+) Index: llvm/include/llvm/Transforms/LinkAllPasses.h diff -u llvm/include/llvm/Transforms/LinkAllPasses.h:1.30 llvm/include/llvm/Transforms/LinkAllPasses.h:1.31 --- llvm/include/llvm/Transforms/LinkAllPasses.h:1.30 Mon Apr 10 14:26:09 2006 +++ llvm/include/llvm/Transforms/LinkAllPasses.h Fri May 26 08:58:26 2006 @@ -69,6 +69,7 @@ (void) llvm::createIndVarSimplifyPass(); (void) llvm::createInstructionCombiningPass(); (void) llvm::createInternalizePass(false); + (void) llvm::createLCSSAPass(); (void) llvm::createLICMPass(); (void) llvm::createLoadValueNumberingPass(); (void) llvm::createLoopExtractorPass(); Index: llvm/include/llvm/Transforms/Scalar.h diff -u llvm/include/llvm/Transforms/Scalar.h:1.64 llvm/include/llvm/Transforms/Scalar.h:1.65 --- llvm/include/llvm/Transforms/Scalar.h:1.64 Mon May 1 23:24:20 2006 +++ llvm/include/llvm/Transforms/Scalar.h Fri May 26 08:58:26 2006 @@ -302,6 +302,11 @@ // through conditional branches. FunctionPass *createBlockPlacementPass(); +//===----------------------------------------------------------------------===// +// This pass inserts phi nodes at loop boundaries to simplify other loop +// optimizations. +FunctionPass *createLCSSAPass(); + } // End llvm namespace #endif From resistor at mac.com Fri May 26 08:58:51 2006 From: resistor at mac.com (Owen Anderson) Date: Fri, 26 May 2006 08:58:51 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LCSSA.cpp Message-ID: <200605261358.IAA14290@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LCSSA.cpp added (r1.1) --- Log message: Skeletal LCSSA pass. This is currently non-functional. Expect functionality and documentation updates soo. --- Diffs of the changes: (+159 -0) LCSSA.cpp | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 159 insertions(+) Index: llvm/lib/Transforms/Scalar/LCSSA.cpp diff -c /dev/null llvm/lib/Transforms/Scalar/LCSSA.cpp:1.1 *** /dev/null Fri May 26 08:58:36 2006 --- llvm/lib/Transforms/Scalar/LCSSA.cpp Fri May 26 08:58:26 2006 *************** *** 0 **** --- 1,159 ---- + //===-- LCSSA.cpp - Convert loops into loop-closed SSA form ------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Owen Anderson and is distributed under the + // University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This pass transforms loops by placing phi nodes at the end of the loops for + // all values that are live across the loop boundary. For example, it turns + // the left into the right code: + // + // for (...) for (...) + // if (c) if(c) + // X1 = ... X1 = ... + // else else + // X2 = ... X2 = ... + // X3 = phi(X1, X2) X3 = phi(X1, X2) + // ... = X3 + 4 X4 = phi(X3) + // ... = X4 + 4 + // + // This is still valid LLVM; the extra phi nodes are purely redundant, and will + // be trivially eliminated by InstCombine. The major benefit of this + // transformation is that it makes many other loop optimizations, such as + // LoopUnswitching, simpler. + // + //===----------------------------------------------------------------------===// + + #include "llvm/Pass.h" + #include "llvm/Function.h" + #include "llvm/Instructions.h" + #include "llvm/Analysis/LoopInfo.h" + #include "llvm/Support/CFG.h" + #include "llvm/Transforms/Scalar.h" + #include "llvm/Transforms/Utils/BasicBlockUtils.h" + #include + #include + #include + + using namespace llvm; + + namespace { + class LCSSA : public FunctionPass { + public: + LoopInfo *LI; // Loop information + + // LoopProcessWorklist - List of loops we need to process. + std::vector LoopProcessWorklist; + + virtual bool runOnFunction(Function &F); + + bool visitLoop(Loop *L, Value *V); + + /// This transformation requires natural loop information & requires that + /// loop preheaders be inserted into the CFG... + /// + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequiredID(LoopSimplifyID); + AU.addPreservedID(LoopSimplifyID); + AU.addRequired(); + AU.addPreserved(); + } + private: + void addSubloopsToWorklist(Loop* L); + std::set loopValuesUsedOutsideLoop(Loop *L); + }; + + RegisterOpt X("lcssa", "Loop-Closed SSA Form Pass"); + } + + FunctionPass *llvm::createLCSSAPass() { return new LCSSA(); } + + bool LCSSA::runOnFunction(Function &F) { + bool changed = false; + LI = &getAnalysis(); + + for (LoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I) { + addSubloopsToWorklist(*I); + LoopProcessWorklist.push_back(*I); + } + + for (std::vector::iterator I = LoopProcessWorklist.begin(), + E = LoopProcessWorklist.end(); I != E; ++I) { + std::set AffectedValues = loopValuesUsedOutsideLoop(*I); + if (!AffectedValues.empty()) { + for (std::set::iterator VI = AffectedValues.begin(), + VE = AffectedValues.end(); VI != VE; ++VI) + changed |= visitLoop(*I, *VI); + } + } + + return changed; + } + + bool LCSSA::visitLoop(Loop *L, Value* V) { + // We will be doing lots of "loop contains block" queries. Loop::contains is + // linear time, use a set to speed this up. + std::set LoopBlocks; + + for (Loop::block_iterator BB = L->block_begin(), E = L->block_end(); + BB != E; ++BB) + LoopBlocks.insert(*BB); + + std::vector exitBlocks; + L->getExitBlocks(exitBlocks); + + for (std::vector::iterator BBI = exitBlocks.begin(), + BBE = exitBlocks.end(); BBI != BBE; ++BBI) { + PHINode *phi = new PHINode(V->getType(), "lcssa"); + (*BBI)->getInstList().insert((*BBI)->front(), phi); + + for (pred_iterator PI = pred_begin(*BBI), PE = pred_end(*BBI); PI != PE; + ++PI) + phi->addIncoming(V, *PI); + } + + for (Value::use_iterator UI = V->use_begin(), UE = V->use_end(); UI != UE; + ++UI) { + BasicBlock *UserBB = cast(*UI)->getParent(); + if (!LoopBlocks.count(UserBB)) + ; // FIXME: This should update the SSA form through the rest of the graph. + } + + return false; + } + + void LCSSA::addSubloopsToWorklist(Loop* L) { + for (Loop::iterator I = L->begin(), E = L->end(); I != E; ++I) { + addSubloopsToWorklist(*I); + LoopProcessWorklist.push_back(*I); + } + } + + /// loopValuesUsedOutsideLoop - Return true if there are any values defined in + /// the loop that are used by instructions outside of it. + std::set LCSSA::loopValuesUsedOutsideLoop(Loop *L) { + std::set AffectedValues; + + // We will be doing lots of "loop contains block" queries. Loop::contains is + // linear time, use a set to speed this up. + std::set LoopBlocks; + + for (Loop::block_iterator BB = L->block_begin(), E = L->block_end(); + BB != E; ++BB) + LoopBlocks.insert(*BB); + + for (Loop::block_iterator BB = L->block_begin(), E = L->block_end(); + BB != E; ++BB) { + for (BasicBlock::iterator I = (*BB)->begin(), E = (*BB)->end(); I != E; ++I) + for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E; + ++UI) { + BasicBlock *UserBB = cast(*UI)->getParent(); + if (!LoopBlocks.count(UserBB)) + AffectedValues.insert(I); + } + } + return AffectedValues; + } \ No newline at end of file From evan.cheng at apple.com Fri May 26 13:23:01 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 26 May 2006 13:23:01 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200605261823.NAA16625@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.216 -> 1.217 --- Log message: No need to handle illegal types. --- Diffs of the changes: (+0 -4) X86ISelLowering.cpp | 4 ---- 1 files changed, 4 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.216 llvm/lib/Target/X86/X86ISelLowering.cpp:1.217 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.216 Thu May 25 18:31:23 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Fri May 26 13:22:49 2006 @@ -384,7 +384,6 @@ switch (ObjectVT) { default: assert(0 && "Unhandled argument type!"); - case MVT::i1: case MVT::i8: ObjSize = 1; break; case MVT::i16: ObjSize = 2; break; case MVT::i32: ObjSize = 4; break; @@ -780,7 +779,6 @@ switch (ObjectVT) { default: assert(0 && "Unhandled argument type!"); - case MVT::i1: case MVT::i8: if (NumIntRegs < FASTCC_NUM_INT_ARGS_INREGS) ObjIntRegs = 1; @@ -871,7 +869,6 @@ if (ObjIntRegs || ObjXMMRegs) { switch (ObjectVT) { default: assert(0 && "Unhandled argument type!"); - case MVT::i1: case MVT::i8: Reg = AddLiveIn(MF, NumIntRegs ? X86::DL : X86::AL, X86::GR8RegisterClass); @@ -945,7 +942,6 @@ switch (getValueType(MF.getFunction()->getReturnType())) { default: assert(0 && "Unknown type!"); case MVT::isVoid: break; - case MVT::i1: case MVT::i8: case MVT::i16: case MVT::i32: From evan.cheng at apple.com Fri May 26 13:25:55 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 26 May 2006 13:25:55 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200605261825.NAA16643@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.217 -> 1.218 --- Log message: Fix some comments. --- Diffs of the changes: (+2 -2) X86ISelLowering.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.217 llvm/lib/Target/X86/X86ISelLowering.cpp:1.218 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.217 Fri May 26 13:22:49 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Fri May 26 13:25:43 2006 @@ -375,7 +375,7 @@ /// HowToPassCCCArgument - Returns how an formal argument of the specified type /// should be passed. If it is through stack, returns the size of the stack -/// frame; if it is through XMM register, returns the number of XMM registers +/// slot; if it is through XMM register, returns the number of XMM registers /// are needed. static void HowToPassCCCArgument(MVT::ValueType ObjectVT, unsigned NumXMMRegs, @@ -766,7 +766,7 @@ /// HowToPassFastCCArgument - Returns how an formal argument of the specified /// type should be passed. If it is through stack, returns the size of the stack -/// frame; if it is through integer or XMM register, returns the number of +/// slot; if it is through integer or XMM register, returns the number of /// integer or XMM registers are needed. static void HowToPassFastCCArgument(MVT::ValueType ObjectVT, From evan.cheng at apple.com Fri May 26 13:37:29 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 26 May 2006 13:37:29 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200605261837.NAA16737@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.218 -> 1.219 --- Log message: Update more comments. --- Diffs of the changes: (+2 -2) X86ISelLowering.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.218 llvm/lib/Target/X86/X86ISelLowering.cpp:1.219 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.218 Fri May 26 13:25:43 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Fri May 26 13:37:16 2006 @@ -416,7 +416,7 @@ // // [ESP] -- return address // [ESP + 4] -- first argument (leftmost lexically) - // [ESP + 8] -- second argument, if first argument is four bytes in size + // [ESP + 8] -- second argument, if first argument is <= 4 bytes in size // ... // unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot @@ -838,7 +838,7 @@ // // [ESP] -- return address // [ESP + 4] -- first nonreg argument (leftmost lexically) - // [ESP + 8] -- second nonreg argument, if first argument is 4 bytes in size + // [ESP + 8] -- second nonreg argument, if 1st argument is <= 4 bytes in size // ... unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot From evan.cheng at apple.com Fri May 26 13:40:11 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 26 May 2006 13:40:11 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200605261840.NAA16760@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.219 -> 1.220 --- Log message: Minor update to make the code more clear --- Diffs of the changes: (+2 -2) X86ISelLowering.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.219 llvm/lib/Target/X86/X86ISelLowering.cpp:1.220 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.219 Fri May 26 13:37:16 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Fri May 26 13:39:59 2006 @@ -428,7 +428,7 @@ unsigned ObjSize = 0; unsigned ObjXMMRegs = 0; HowToPassCCCArgument(ObjectVT, NumXMMRegs, ObjSize, ObjXMMRegs); - if (ObjSize >= 8) + if (ObjSize > 4) ArgIncrement = ObjSize; SDOperand ArgValue; @@ -861,7 +861,7 @@ HowToPassFastCCArgument(ObjectVT, NumIntRegs, NumXMMRegs, ObjSize, ObjIntRegs, ObjXMMRegs); - if (ObjSize >= 8) + if (ObjSize > 4) ArgIncrement = ObjSize; unsigned Reg; From lattner at cs.uiuc.edu Fri May 26 13:41:38 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 26 May 2006 13:41:38 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Assembler/2006-05-26-VarargsCallEncode.ll Message-ID: <200605261841.NAA16874@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Assembler: 2006-05-26-VarargsCallEncode.ll added (r1.1) --- Log message: New testcase, check that the bc file correctly encodes varargs nonccc calls. --- Diffs of the changes: (+8 -0) 2006-05-26-VarargsCallEncode.ll | 8 ++++++++ 1 files changed, 8 insertions(+) Index: llvm/test/Regression/Assembler/2006-05-26-VarargsCallEncode.ll diff -c /dev/null llvm/test/Regression/Assembler/2006-05-26-VarargsCallEncode.ll:1.1 *** /dev/null Fri May 26 13:41:36 2006 --- llvm/test/Regression/Assembler/2006-05-26-VarargsCallEncode.ll Fri May 26 13:41:26 2006 *************** *** 0 **** --- 1,8 ---- + ; RUN: llvm-as < %s | llvm-dis | grep 'tail call csretcc' + + declare csretcc void %foo({}*, ...) + + void %bar() { + tail call csretcc void({}*, ...)* %foo({}* null, int 0) + ret void + } From lattner at cs.uiuc.edu Fri May 26 13:42:47 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 26 May 2006 13:42:47 -0500 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Reader/Reader.cpp Message-ID: <200605261842.NAA16893@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Reader: Reader.cpp updated: 1.193 -> 1.194 --- Log message: Fix a bug in the bc reader/writer: we were not correctly encoding varargs nonccc calls (we were dropping the CC and tail flag). This broke several FORTRAN programs. Testcase here: Regression/Assembler/2006-05-26-VarargsCallEncode.ll --- Diffs of the changes: (+9 -8) Reader.cpp | 17 +++++++++-------- 1 files changed, 9 insertions(+), 8 deletions(-) Index: llvm/lib/Bytecode/Reader/Reader.cpp diff -u llvm/lib/Bytecode/Reader/Reader.cpp:1.193 llvm/lib/Bytecode/Reader/Reader.cpp:1.194 --- llvm/lib/Bytecode/Reader/Reader.cpp:1.193 Fri Apr 7 23:09:19 2006 +++ llvm/lib/Bytecode/Reader/Reader.cpp Fri May 26 13:42:34 2006 @@ -830,7 +830,15 @@ if (Opcode == 61 || Opcode == 59) isTailCall = true; - + + if (Opcode == 58) { + isTailCall = Oprnds.back() & 1; + CallingConv = Oprnds.back() >> 1; + Oprnds.pop_back(); + } else if (Opcode == 59 || Opcode == 60) { + CallingConv = CallingConv::Fast; + } + // Check to make sure we have a pointer to function type const PointerType *PTy = dyn_cast(F->getType()); if (PTy == 0) error("Call to non function pointer value!"); @@ -841,13 +849,6 @@ if (!FTy->isVarArg()) { FunctionType::param_iterator It = FTy->param_begin(); - if (Opcode == 58) { - isTailCall = Oprnds.back() & 1; - CallingConv = Oprnds.back() >> 1; - Oprnds.pop_back(); - } else if (Opcode == 59 || Opcode == 60) - CallingConv = CallingConv::Fast; - for (unsigned i = 1, e = Oprnds.size(); i != e; ++i) { if (It == FTy->param_end()) error("Invalid call instruction!"); From lattner at cs.uiuc.edu Fri May 26 13:42:46 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 26 May 2006 13:42:46 -0500 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Writer/Writer.cpp Message-ID: <200605261842.NAA16889@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Writer: Writer.cpp updated: 1.120 -> 1.121 --- Log message: Fix a bug in the bc reader/writer: we were not correctly encoding varargs nonccc calls (we were dropping the CC and tail flag). This broke several FORTRAN programs. Testcase here: Regression/Assembler/2006-05-26-VarargsCallEncode.ll --- Diffs of the changes: (+10 -1) Writer.cpp | 11 ++++++++++- 1 files changed, 10 insertions(+), 1 deletion(-) Index: llvm/lib/Bytecode/Writer/Writer.cpp diff -u llvm/lib/Bytecode/Writer/Writer.cpp:1.120 llvm/lib/Bytecode/Writer/Writer.cpp:1.121 --- llvm/lib/Bytecode/Writer/Writer.cpp:1.120 Fri May 19 16:57:37 2006 +++ llvm/lib/Bytecode/Writer/Writer.cpp Fri May 26 13:42:34 2006 @@ -527,7 +527,8 @@ // variable argument. NumFixedOperands = 3+NumParams; } - output_vbr(2 * I->getNumOperands()-NumFixedOperands); + output_vbr(2 * I->getNumOperands()-NumFixedOperands + + unsigned(Opcode == 56 || Opcode == 58)); // The type for the function has already been emitted in the type field of the // instruction. Just emit the slot # now. @@ -548,6 +549,14 @@ assert(Slot >= 0 && "No slot number for value!?!?"); output_vbr((unsigned)Slot); } + + // If this is the escape sequence for call, emit the tailcall/cc info. + if (Opcode == 58) { + const CallInst *CI = cast(I); + output_vbr((CI->getCallingConv() << 1) | unsigned(CI->isTailCall())); + } else if (Opcode == 56) { // Invoke escape sequence. + output_vbr(cast(I)->getCallingConv()); + } } From lattner at cs.uiuc.edu Fri May 26 14:18:52 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 26 May 2006 14:18:52 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/store.ll Message-ID: <200605261918.OAA17195@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: store.ll updated: 1.1 -> 1.2 --- Log message: New testcase for trivial DSE --- Diffs of the changes: (+8 -1) store.ll | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletion(-) Index: llvm/test/Regression/Transforms/InstCombine/store.ll diff -u llvm/test/Regression/Transforms/InstCombine/store.ll:1.1 llvm/test/Regression/Transforms/InstCombine/store.ll:1.2 --- llvm/test/Regression/Transforms/InstCombine/store.ll:1.1 Sun Jan 30 23:36:19 2005 +++ llvm/test/Regression/Transforms/InstCombine/store.ll Fri May 26 14:18:40 2006 @@ -1,9 +1,16 @@ +; RUN: llvm-as < %s | opt -instcombine -disable-output && ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep -v 'store.*,.*null' | not grep store - void %test1(int* %P) { store int undef, int* %P store int 123, int* undef store int 124, int* null ret void } + +void %test2(int* %P) { + %X = load int* %P + %Y = add int %X, 0 + store int %Y, int* %P + ret void +} From lattner at cs.uiuc.edu Fri May 26 14:19:33 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 26 May 2006 14:19:33 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200605261919.OAA17233@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.487 -> 1.488 --- Log message: Implement Transforms/InstCombine/store.ll:test2. --- Diffs of the changes: (+15 -1) InstructionCombining.cpp | 16 +++++++++++++++- 1 files changed, 15 insertions(+), 1 deletion(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.487 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.488 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.487 Thu May 25 19:29:06 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Fri May 26 14:19:20 2006 @@ -6833,8 +6833,22 @@ break; } + // If this is a load, we have to stop. However, if the loaded value is from + // the pointer we're loading and is producing the pointer we're storing, + // then *this* store is dead (X = load P; store X -> P). + if (LoadInst *LI = dyn_cast(BBI)) { + if (LI == Val && LI->getOperand(0) == Ptr) { + EraseInstFromFunction(SI); + ++NumCombined; + return 0; + } + // Otherwise, this is a load from some other location. Stores before it + // may not be dead. + break; + } + // Don't skip over loads or things that can modify memory. - if (BBI->mayWriteToMemory() || isa(BBI)) + if (BBI->mayWriteToMemory()) break; } From evan.cheng at apple.com Fri May 26 14:22:18 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 26 May 2006 14:22:18 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200605261922.OAA17259@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.220 -> 1.221 --- Log message: Mac OS X ABI document lied. The first four XMM registers are used to pass vector arguments, not three. --- Diffs of the changes: (+12 -10) X86ISelLowering.cpp | 22 ++++++++++++---------- 1 files changed, 12 insertions(+), 10 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.220 llvm/lib/Target/X86/X86ISelLowering.cpp:1.221 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.220 Fri May 26 13:39:59 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Fri May 26 14:22:06 2006 @@ -396,7 +396,7 @@ case MVT::v2i64: case MVT::v4f32: case MVT::v2f64: - if (NumXMMRegs < 3) + if (NumXMMRegs < 4) ObjXMMRegs = 1; else ObjSize = 16; @@ -421,7 +421,9 @@ // unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot unsigned NumXMMRegs = 0; // XMM regs used for parameter passing. - unsigned XMMArgRegs[] = { X86::XMM0, X86::XMM1, X86::XMM2 }; + static const unsigned XMMArgRegs[] = { + X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3 + }; for (unsigned i = 0; i < NumArgs; ++i) { MVT::ValueType ObjectVT = Op.getValue(i).getValueType(); unsigned ArgIncrement = 4; @@ -486,7 +488,7 @@ // Keep track of the number of XMM regs passed so far. unsigned NumXMMRegs = 0; static const unsigned XMMArgRegs[] = { - X86::XMM0, X86::XMM1, X86::XMM2 + X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3 }; // Count how many bytes are to be pushed on the stack. @@ -512,7 +514,7 @@ case MVT::v2i64: case MVT::v4f32: case MVT::v2f64: - if (NumXMMRegs < 3) + if (NumXMMRegs < 4) ++NumXMMRegs; else NumBytes += 16; @@ -568,7 +570,7 @@ case MVT::v2i64: case MVT::v4f32: case MVT::v2f64: - if (NumXMMRegs < 3) { + if (NumXMMRegs < 4) { RegsToPass.push_back(std::make_pair(XMMArgRegs[NumXMMRegs], Arg)); NumXMMRegs++; } else { @@ -817,7 +819,7 @@ case MVT::v2i64: case MVT::v4f32: case MVT::v2f64: - if (NumXMMRegs < 3) + if (NumXMMRegs < 4) ObjXMMRegs = 1; else ObjSize = 16; @@ -849,7 +851,7 @@ unsigned NumXMMRegs = 0; // XMM regs used for parameter passing. static const unsigned XMMArgRegs[] = { - X86::XMM0, X86::XMM1, X86::XMM2 + X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3 }; for (unsigned i = 0; i < NumArgs; ++i) { @@ -995,7 +997,7 @@ { X86::EAX, X86::EDX } }; static const unsigned XMMArgRegs[] = { - X86::XMM0, X86::XMM1, X86::XMM2 + X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3 }; for (unsigned i = 0; i != NumOps; ++i) { @@ -1023,7 +1025,7 @@ case MVT::v2i64: case MVT::v4f32: case MVT::v2f64: - if (NumXMMRegs < 3) + if (NumXMMRegs < 4) NumXMMRegs++; else NumBytes += 16; @@ -1082,7 +1084,7 @@ case MVT::v2i64: case MVT::v4f32: case MVT::v2f64: - if (NumXMMRegs < 3) { + if (NumXMMRegs < 4) { RegsToPass.push_back(std::make_pair(XMMArgRegs[NumXMMRegs], Arg)); NumXMMRegs++; } else { From evan.cheng at apple.com Fri May 26 15:38:00 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 26 May 2006 15:38:00 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200605262038.PAA17530@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.221 -> 1.222 --- Log message: Vector argument must be passed in memory location aligned on 16-byte boundary. --- Diffs of the changes: (+18 -2) X86ISelLowering.cpp | 20 ++++++++++++++++++-- 1 files changed, 18 insertions(+), 2 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.221 llvm/lib/Target/X86/X86ISelLowering.cpp:1.222 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.221 Fri May 26 14:22:06 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Fri May 26 15:37:47 2006 @@ -442,6 +442,9 @@ ArgValues.push_back(ArgValue); NumXMMRegs += ObjXMMRegs; } else { + // XMM arguments have to be aligned on 16-byte boundary. + if (ObjSize == 16) + ArgOffset = ((ArgOffset + 15) / 16) * 16; // Create the frame index object for this incoming parameter... int FI = MFI->CreateFixedObject(ObjSize, ArgOffset); SDOperand FIN = DAG.getFrameIndex(FI, getPointerTy()); @@ -516,8 +519,11 @@ case MVT::v2f64: if (NumXMMRegs < 4) ++NumXMMRegs; - else + else { + // XMM arguments have to be aligned on 16-byte boundary. + NumBytes = ((NumBytes + 15) / 16) * 16; NumBytes += 16; + } break; } } @@ -574,6 +580,8 @@ RegsToPass.push_back(std::make_pair(XMMArgRegs[NumXMMRegs], Arg)); NumXMMRegs++; } else { + // XMM arguments have to be aligned on 16-byte boundary. + ArgOffset = ((ArgOffset + 15) / 16) * 16; SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff); MemOpChains.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, @@ -911,6 +919,9 @@ } if (ObjSize) { + // XMM arguments have to be aligned on 16-byte boundary. + if (ObjSize == 16) + ArgOffset = ((ArgOffset + 15) / 16) * 16; // Create the SelectionDAG nodes corresponding to a load from this // parameter. int FI = MFI->CreateFixedObject(ObjSize, ArgOffset); @@ -1027,8 +1038,11 @@ case MVT::v2f64: if (NumXMMRegs < 4) NumXMMRegs++; - else + else { + // XMM arguments have to be aligned on 16-byte boundary. + NumBytes = ((NumBytes + 15) / 16) * 16; NumBytes += 16; + } break; } } @@ -1088,6 +1102,8 @@ RegsToPass.push_back(std::make_pair(XMMArgRegs[NumXMMRegs], Arg)); NumXMMRegs++; } else { + // XMM arguments have to be aligned on 16-byte boundary. + ArgOffset = ((ArgOffset + 15) / 16) * 16; SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff); MemOpChains.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, From resistor at mac.com Fri May 26 16:12:05 2006 From: resistor at mac.com (Owen Anderson) Date: Fri, 26 May 2006 16:12:05 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LCSSA.cpp Message-ID: <200605262112.QAA17691@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LCSSA.cpp updated: 1.1 -> 1.2 --- Log message: Clean up and refactor LCSSA a bunch. It should also run faster now, though there's still a lot of work to be done on it. --- Diffs of the changes: (+51 -67) LCSSA.cpp | 118 ++++++++++++++++++++++++++------------------------------------ 1 files changed, 51 insertions(+), 67 deletions(-) Index: llvm/lib/Transforms/Scalar/LCSSA.cpp diff -u llvm/lib/Transforms/Scalar/LCSSA.cpp:1.1 llvm/lib/Transforms/Scalar/LCSSA.cpp:1.2 --- llvm/lib/Transforms/Scalar/LCSSA.cpp:1.1 Fri May 26 08:58:26 2006 +++ llvm/lib/Transforms/Scalar/LCSSA.cpp Fri May 26 16:11:53 2006 @@ -1,4 +1,4 @@ -//===-- LCSSA.cpp - Convert loops into loop-closed SSA form ------===// +//===-- LCSSA.cpp - Convert loops into loop-closed SSA form ---------------===// // // The LLVM Compiler Infrastructure // @@ -27,14 +27,14 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Transforms/Scalar.h" #include "llvm/Pass.h" #include "llvm/Function.h" #include "llvm/Instructions.h" +#include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Support/CFG.h" -#include "llvm/Transforms/Scalar.h" -#include "llvm/Transforms/Utils/BasicBlockUtils.h" -#include +#include #include #include @@ -44,26 +44,28 @@ class LCSSA : public FunctionPass { public: LoopInfo *LI; // Loop information - - // LoopProcessWorklist - List of loops we need to process. - std::vector LoopProcessWorklist; + DominatorTree *DT; // Dominator Tree for the current Loop... + DominanceFrontier *DF; // Current Dominance Frontier virtual bool runOnFunction(Function &F); - - bool visitLoop(Loop *L, Value *V); + bool LCSSA::visitSubloop(Loop* L); /// This transformation requires natural loop information & requires that /// loop preheaders be inserted into the CFG... /// virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesCFG(); AU.addRequiredID(LoopSimplifyID); AU.addPreservedID(LoopSimplifyID); AU.addRequired(); AU.addPreserved(); + AU.addRequired(); // Not sure if this one will actually + // be needed. + AU.addRequired(); } private: - void addSubloopsToWorklist(Loop* L); - std::set loopValuesUsedOutsideLoop(Loop *L); + std::set getLoopValuesUsedOutsideLoop(Loop *L, + std::vector LoopBlocks); }; RegisterOpt X("lcssa", "Loop-Closed SSA Form Pass"); @@ -74,86 +76,68 @@ bool LCSSA::runOnFunction(Function &F) { bool changed = false; LI = &getAnalysis(); + DF = &getAnalysis(); + DT = &getAnalysis(); for (LoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I) { - addSubloopsToWorklist(*I); - LoopProcessWorklist.push_back(*I); - } - - for (std::vector::iterator I = LoopProcessWorklist.begin(), - E = LoopProcessWorklist.end(); I != E; ++I) { - std::set AffectedValues = loopValuesUsedOutsideLoop(*I); - if (!AffectedValues.empty()) { - for (std::set::iterator VI = AffectedValues.begin(), - VE = AffectedValues.end(); VI != VE; ++VI) - changed |= visitLoop(*I, *VI); - } + changed |= visitSubloop(*I); } return changed; } -bool LCSSA::visitLoop(Loop *L, Value* V) { - // We will be doing lots of "loop contains block" queries. Loop::contains is - // linear time, use a set to speed this up. - std::set LoopBlocks; - - for (Loop::block_iterator BB = L->block_begin(), E = L->block_end(); - BB != E; ++BB) - LoopBlocks.insert(*BB); +bool LCSSA::visitSubloop(Loop* L) { + for (Loop::iterator I = L->begin(), E = L->end(); I != E; ++I) + visitSubloop(*I); + + // Speed up queries by creating a sorted list of blocks + std::vector LoopBlocks(L->block_begin(), L->block_end()); + std::sort(LoopBlocks.begin(), LoopBlocks.end()); + + std::set AffectedValues = getLoopValuesUsedOutsideLoop(L, + LoopBlocks); std::vector exitBlocks; L->getExitBlocks(exitBlocks); - for (std::vector::iterator BBI = exitBlocks.begin(), - BBE = exitBlocks.end(); BBI != BBE; ++BBI) { - PHINode *phi = new PHINode(V->getType(), "lcssa"); - (*BBI)->getInstList().insert((*BBI)->front(), phi); - - for (pred_iterator PI = pred_begin(*BBI), PE = pred_end(*BBI); PI != PE; - ++PI) - phi->addIncoming(V, *PI); - } + for (std::set::iterator I = AffectedValues.begin(), + E = AffectedValues.end(); I != E; ++I) { + for (std::vector::iterator BBI = exitBlocks.begin(), + BBE = exitBlocks.end(); BBI != BBE; ++BBI) { + PHINode *phi = new PHINode((*I)->getType(), "lcssa"); + (*BBI)->getInstList().insert((*BBI)->front(), phi); + + for (pred_iterator PI = pred_begin(*BBI), PE = pred_end(*BBI); PI != PE; + ++PI) + phi->addIncoming(*I, *PI); + } - for (Value::use_iterator UI = V->use_begin(), UE = V->use_end(); UI != UE; - ++UI) { - BasicBlock *UserBB = cast(*UI)->getParent(); - if (!LoopBlocks.count(UserBB)) - ; // FIXME: This should update the SSA form through the rest of the graph. + for (Value::use_iterator UI = (*I)->use_begin(), UE = (*I)->use_end(); + UI != UE; ++UI) { + BasicBlock *UserBB = cast(*UI)->getParent(); + if (!std::binary_search(LoopBlocks.begin(), LoopBlocks.end(), UserBB)) + ; // FIXME: This should update the SSA form. + } } - return false; -} - -void LCSSA::addSubloopsToWorklist(Loop* L) { - for (Loop::iterator I = L->begin(), E = L->end(); I != E; ++I) { - addSubloopsToWorklist(*I); - LoopProcessWorklist.push_back(*I); - } + return true; // FIXME: Should be more intelligent in our return value. } -/// loopValuesUsedOutsideLoop - Return true if there are any values defined in -/// the loop that are used by instructions outside of it. -std::set LCSSA::loopValuesUsedOutsideLoop(Loop *L) { - std::set AffectedValues; - - // We will be doing lots of "loop contains block" queries. Loop::contains is - // linear time, use a set to speed this up. - std::set LoopBlocks; +/// getLoopValuesUsedOutsideLoop - Return any values defined in the loop that +/// are used by instructions outside of it. +std::set LCSSA::getLoopValuesUsedOutsideLoop(Loop *L, + std::vector LoopBlocks) { - for (Loop::block_iterator BB = L->block_begin(), E = L->block_end(); - BB != E; ++BB) - LoopBlocks.insert(*BB); - + std::set AffectedValues; for (Loop::block_iterator BB = L->block_begin(), E = L->block_end(); BB != E; ++BB) { for (BasicBlock::iterator I = (*BB)->begin(), E = (*BB)->end(); I != E; ++I) for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E; ++UI) { BasicBlock *UserBB = cast(*UI)->getParent(); - if (!LoopBlocks.count(UserBB)) + if (!std::binary_search(LoopBlocks.begin(), LoopBlocks.end(), UserBB)) AffectedValues.insert(I); } } return AffectedValues; -} \ No newline at end of file +} From resistor at mac.com Fri May 26 16:19:29 2006 From: resistor at mac.com (Owen Anderson) Date: Fri, 26 May 2006 16:19:29 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LCSSA.cpp Message-ID: <200605262119.QAA17731@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LCSSA.cpp updated: 1.2 -> 1.3 --- Log message: Fix a copy-and-paste-o that would break some compilers. --- Diffs of the changes: (+1 -1) LCSSA.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Transforms/Scalar/LCSSA.cpp diff -u llvm/lib/Transforms/Scalar/LCSSA.cpp:1.2 llvm/lib/Transforms/Scalar/LCSSA.cpp:1.3 --- llvm/lib/Transforms/Scalar/LCSSA.cpp:1.2 Fri May 26 16:11:53 2006 +++ llvm/lib/Transforms/Scalar/LCSSA.cpp Fri May 26 16:19:17 2006 @@ -48,7 +48,7 @@ DominanceFrontier *DF; // Current Dominance Frontier virtual bool runOnFunction(Function &F); - bool LCSSA::visitSubloop(Loop* L); + bool visitSubloop(Loop* L); /// This transformation requires natural loop information & requires that /// loop preheaders be inserted into the CFG... From llvm at cs.uiuc.edu Fri May 26 16:58:25 2006 From: llvm at cs.uiuc.edu (LLVM) Date: Fri, 26 May 2006 16:58:25 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/LCSSA/ Message-ID: <200605262158.QAA18057@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LCSSA: --- Log message: Directory /var/cvs/llvm/llvm/test/Regression/Transforms/LCSSA added to the repository --- Diffs of the changes: (+0 -0) 0 files changed From resistor at mac.com Fri May 26 16:59:33 2006 From: resistor at mac.com (Owen Anderson) Date: Fri, 26 May 2006 16:59:33 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/LCSSA/basictest.ll dg.exp Message-ID: <200605262159.QAA18087@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LCSSA: basictest.ll added (r1.1) dg.exp added (r1.1) --- Log message: Trivial testcase that LCSSA can already handle. --- Diffs of the changes: (+28 -0) basictest.ll | 25 +++++++++++++++++++++++++ dg.exp | 3 +++ 2 files changed, 28 insertions(+) Index: llvm/test/Regression/Transforms/LCSSA/basictest.ll diff -c /dev/null llvm/test/Regression/Transforms/LCSSA/basictest.ll:1.1 *** /dev/null Fri May 26 16:59:30 2006 --- llvm/test/Regression/Transforms/LCSSA/basictest.ll Fri May 26 16:59:20 2006 *************** *** 0 **** --- 1,25 ---- + ; RUN: llvm-as < %s | opt -lcssa | llvm-dis | grep "%lcssa = phi int" + + void %lcssa(bool %S2) { + entry: + br label %loop.interior + + loop.interior: ; preds = %entry + br bool %S2, label %if.true, label %if.false + + if.true: + %X1 = add int 0, 0 + br label %post.if + + if.false: + %X2 = add int 0, 1 + br label %post.if + + post.if: + %X3 = phi int [%X1, %if.true], [%X2, %if.false] + br bool %S2, label %loop.exit, label %loop.interior + + loop.exit: + %X4 = add int 3, %X3 + ret void + } \ No newline at end of file Index: llvm/test/Regression/Transforms/LCSSA/dg.exp diff -c /dev/null llvm/test/Regression/Transforms/LCSSA/dg.exp:1.1 *** /dev/null Fri May 26 16:59:33 2006 --- llvm/test/Regression/Transforms/LCSSA/dg.exp Fri May 26 16:59:20 2006 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $srcdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext $llvmgcc_version From evan.cheng at apple.com Fri May 26 18:08:27 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 26 May 2006 18:08:27 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp SelectionDAGISel.cpp Message-ID: <200605262308.SAA18590@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.378 -> 1.379 SelectionDAGISel.cpp updated: 1.251 -> 1.252 --- Log message: Change RET node to include signness information of the return values. e.g. RET chain, value1, sign1, value2, sign2 --- Diffs of the changes: (+17 -9) LegalizeDAG.cpp | 20 ++++++++++++-------- SelectionDAGISel.cpp | 6 +++++- 2 files changed, 17 insertions(+), 9 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.378 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.379 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.378 Wed May 24 12:04:04 2006 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri May 26 18:08:15 2006 @@ -1453,17 +1453,18 @@ LastCALLSEQ_END = DAG.getEntryNode(); switch (Node->getNumOperands()) { - case 2: // ret val + case 3: // ret val Tmp2 = Node->getOperand(1); + Tmp3 = Node->getOperand(2); // Signness switch (getTypeAction(Tmp2.getValueType())) { case Legal: - Result = DAG.UpdateNodeOperands(Result, Tmp1, LegalizeOp(Tmp2)); + Result = DAG.UpdateNodeOperands(Result, Tmp1, LegalizeOp(Tmp2), Tmp3); break; case Expand: if (Tmp2.getValueType() != MVT::Vector) { SDOperand Lo, Hi; ExpandOp(Tmp2, Lo, Hi); - Result = DAG.getNode(ISD::RET, MVT::Other, Tmp1, Lo, Hi); + Result = DAG.getNode(ISD::RET, MVT::Other, Tmp1, Lo, Tmp3, Hi, Tmp3); } else { SDNode *InVal = Tmp2.Val; unsigned NumElems = @@ -1476,11 +1477,11 @@ if (TVT != MVT::Other && TLI.isTypeLegal(TVT)) { // Turn this into a return of the packed type. Tmp2 = PackVectorOp(Tmp2, TVT); - Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2); + Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3); } else if (NumElems == 1) { // Turn this into a return of the scalar type. Tmp2 = PackVectorOp(Tmp2, EVT); - Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2); + Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3); // FIXME: Returns of gcc generic vectors smaller than a legal type // should be returned in integer registers! @@ -1493,14 +1494,14 @@ // type should be returned by reference! SDOperand Lo, Hi; SplitVectorOp(Tmp2, Lo, Hi); - Result = DAG.getNode(ISD::RET, MVT::Other, Tmp1, Lo, Hi); + Result = DAG.getNode(ISD::RET, MVT::Other, Tmp1, Lo, Tmp3, Hi, Tmp3); Result = LegalizeOp(Result); } } break; case Promote: Tmp2 = PromoteOp(Node->getOperand(1)); - Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2); + Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3); Result = LegalizeOp(Result); break; } @@ -1511,10 +1512,11 @@ default: { // ret std::vector NewValues; NewValues.push_back(Tmp1); - for (unsigned i = 1, e = Node->getNumOperands(); i != e; ++i) + for (unsigned i = 1, e = Node->getNumOperands(); i < e; i += 2) switch (getTypeAction(Node->getOperand(i).getValueType())) { case Legal: NewValues.push_back(LegalizeOp(Node->getOperand(i))); + NewValues.push_back(Node->getOperand(i+1)); break; case Expand: { SDOperand Lo, Hi; @@ -1522,7 +1524,9 @@ "FIXME: TODO: implement returning non-legal vector types!"); ExpandOp(Node->getOperand(i), Lo, Hi); NewValues.push_back(Lo); + NewValues.push_back(Node->getOperand(i+1)); NewValues.push_back(Hi); + NewValues.push_back(Node->getOperand(i+1)); break; } case Promote: Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.251 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.252 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.251 Wed May 24 19:55:32 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri May 26 18:08:15 2006 @@ -722,10 +722,13 @@ NewValues.push_back(getRoot()); for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) { SDOperand RetOp = getValue(I.getOperand(i)); + bool isSigned = I.getOperand(i)->getType()->isSigned(); // If this is an integer return value, we need to promote it ourselves to // the full width of a register, since LegalizeOp will use ANY_EXTEND rather // than sign/zero. + // 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. if (MVT::isInteger(RetOp.getValueType()) && RetOp.getValueType() < MVT::i64) { MVT::ValueType TmpVT; @@ -734,12 +737,13 @@ else TmpVT = MVT::i32; - if (I.getOperand(i)->getType()->isSigned()) + if (isSigned) RetOp = DAG.getNode(ISD::SIGN_EXTEND, TmpVT, RetOp); else RetOp = DAG.getNode(ISD::ZERO_EXTEND, TmpVT, RetOp); } NewValues.push_back(RetOp); + NewValues.push_back(DAG.getConstant(isSigned, MVT::i32)); } DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other, NewValues)); } From evan.cheng at apple.com Fri May 26 18:09:22 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 26 May 2006 18:09:22 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200605262309.SAA18606@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAGNodes.h updated: 1.133 -> 1.134 --- Log message: Change RET node to include signness information of the return values. e.g. RET chain, value1, sign1, value2, sign2 --- Diffs of the changes: (+3 -2) SelectionDAGNodes.h | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.133 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.134 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.133 Wed May 24 19:54:33 2006 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Fri May 26 18:09:09 2006 @@ -414,8 +414,9 @@ BR_CC, // RET - Return from function. The first operand is the chain, - // and any subsequent operands are the return values for the - // function. This operation can have variable number of operands. + // and any subsequent operands are pairs of return value and return value + // signness for the function. This operation can have variable number of + // operands. RET, // INLINEASM - Represents an inline asm block. This node always has two From evan.cheng at apple.com Fri May 26 18:10:27 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 26 May 2006 18:10:27 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200605262310.SAA18648@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.222 -> 1.223 --- Log message: Change RET node to include signness information of the return values. i.e. RET chain, value1, sign1, value2, sign2, ... --- Diffs of the changes: (+3 -3) X86ISelLowering.cpp | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.222 llvm/lib/Target/X86/X86ISelLowering.cpp:1.223 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.222 Fri May 26 15:37:47 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Fri May 26 18:10:12 2006 @@ -3326,7 +3326,7 @@ case 1: // ret void. return DAG.getNode(X86ISD::RET_FLAG, MVT::Other, Op.getOperand(0), DAG.getConstant(getBytesToPopOnReturn(), MVT::i16)); - case 2: { + case 3: { MVT::ValueType ArgVT = Op.getOperand(1).getValueType(); if (MVT::isVector(ArgVT)) { @@ -3394,13 +3394,13 @@ } break; } - case 3: + case 5: if (DAG.getMachineFunction().liveout_empty()) { DAG.getMachineFunction().addLiveOut(X86::EAX); DAG.getMachineFunction().addLiveOut(X86::EDX); } - Copy = DAG.getCopyToReg(Op.getOperand(0), X86::EDX, Op.getOperand(2), + Copy = DAG.getCopyToReg(Op.getOperand(0), X86::EDX, Op.getOperand(3), SDOperand()); Copy = DAG.getCopyToReg(Copy, X86::EAX,Op.getOperand(1),Copy.getValue(1)); break; From evan.cheng at apple.com Fri May 26 18:10:28 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 26 May 2006 18:10:28 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp Message-ID: <200605262310.SAA18654@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/ARM: ARMISelDAGToDAG.cpp updated: 1.8 -> 1.9 --- Log message: Change RET node to include signness information of the return values. i.e. RET chain, value1, sign1, value2, sign2, ... --- Diffs of the changes: (+2 -2) ARMISelDAGToDAG.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp diff -u llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp:1.8 llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp:1.9 --- llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp:1.8 Thu May 25 06:00:18 2006 +++ llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp Fri May 26 18:10:12 2006 @@ -62,8 +62,8 @@ abort(); case 1: return SDOperand(); // ret void is legal - case 2: - Copy = DAG.getCopyToReg(Op.getOperand(0), ARM::R0, Op.getOperand(1), SDOperand()); + case 3: + Copy = DAG.getCopyToReg(Op.getOperand(0), ARM::R0, Op.getOperand(2), SDOperand()); break; } From evan.cheng at apple.com Fri May 26 18:10:28 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 26 May 2006 18:10:28 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp Message-ID: <200605262310.SAA18664@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcISelDAGToDAG.cpp updated: 1.97 -> 1.98 --- Log message: Change RET node to include signness information of the return values. i.e. RET chain, value1, sign1, value2, sign2, ... --- Diffs of the changes: (+3 -3) SparcISelDAGToDAG.cpp | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp diff -u llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp:1.97 llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp:1.98 --- llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp:1.97 Thu May 25 17:26:02 2006 +++ llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp Fri May 26 18:10:12 2006 @@ -857,7 +857,7 @@ abort(); case 1: return SDOperand(); // ret void is legal - case 2: { + case 3: { unsigned ArgReg; switch(Op.getOperand(1).getValueType()) { default: assert(0 && "Unknown type to return!"); @@ -869,8 +869,8 @@ SDOperand()); break; } - case 3: - Copy = DAG.getCopyToReg(Op.getOperand(0), SP::I0, Op.getOperand(2), + case 5: + Copy = DAG.getCopyToReg(Op.getOperand(0), SP::I0, Op.getOperand(3), SDOperand()); Copy = DAG.getCopyToReg(Copy, SP::I1, Op.getOperand(1), Copy.getValue(1)); break; From evan.cheng at apple.com Fri May 26 18:10:28 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 26 May 2006 18:10:28 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64ISelLowering.cpp Message-ID: <200605262310.SAA18652@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64ISelLowering.cpp updated: 1.37 -> 1.38 --- Log message: Change RET node to include signness information of the return values. i.e. RET chain, value1, sign1, value2, sign2, ... --- Diffs of the changes: (+1 -1) IA64ISelLowering.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/IA64/IA64ISelLowering.cpp diff -u llvm/lib/Target/IA64/IA64ISelLowering.cpp:1.37 llvm/lib/Target/IA64/IA64ISelLowering.cpp:1.38 --- llvm/lib/Target/IA64/IA64ISelLowering.cpp:1.37 Sat Apr 22 13:53:45 2006 +++ llvm/lib/Target/IA64/IA64ISelLowering.cpp Fri May 26 18:10:12 2006 @@ -562,7 +562,7 @@ AR_PFSVal = DAG.getCopyToReg(AR_PFSVal.getValue(1), IA64::AR_PFS, AR_PFSVal); return DAG.getNode(IA64ISD::RET_FLAG, MVT::Other, AR_PFSVal); - case 2: { + case 3: { // Copy the result into the output register & restore ar.pfs MVT::ValueType ArgVT = Op.getOperand(1).getValueType(); unsigned ArgReg = MVT::isInteger(ArgVT) ? IA64::r8 : IA64::F8; From evan.cheng at apple.com Fri May 26 18:10:28 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 26 May 2006 18:10:28 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp Message-ID: <200605262310.SAA18660@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelDAGToDAG.cpp updated: 1.42 -> 1.43 --- Log message: Change RET node to include signness information of the return values. i.e. RET chain, value1, sign1, value2, sign2, ... --- Diffs of the changes: (+1 -1) AlphaISelDAGToDAG.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp diff -u llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.42 llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.43 --- llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.42 Wed May 24 19:24:28 2006 +++ llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp Fri May 26 18:10:12 2006 @@ -231,7 +231,7 @@ Select(Chain, N->getOperand(0)); // Token chain. SDOperand InFlag(0,0); - if (N->getNumOperands() == 2) { + if (N->getNumOperands() == 3) { SDOperand Val; Select(Val, N->getOperand(1)); if (N->getOperand(1).getValueType() == MVT::i64) { From evan.cheng at apple.com Fri May 26 18:10:29 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 26 May 2006 18:10:29 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp Message-ID: <200605262310.SAA18668@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelLowering.cpp updated: 1.184 -> 1.185 --- Log message: Change RET node to include signness information of the return values. i.e. RET chain, value1, sign1, value2, sign2, ... --- Diffs of the changes: (+3 -3) PPCISelLowering.cpp | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.184 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.185 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.184 Wed May 24 19:57:32 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Fri May 26 18:10:12 2006 @@ -1160,7 +1160,7 @@ abort(); case 1: return SDOperand(); // ret void is legal - case 2: { + case 3: { MVT::ValueType ArgVT = Op.getOperand(1).getValueType(); unsigned ArgReg; if (MVT::isVector(ArgVT)) @@ -1180,8 +1180,8 @@ DAG.getMachineFunction().addLiveOut(ArgReg); break; } - case 3: - Copy = DAG.getCopyToReg(Op.getOperand(0), PPC::R3, Op.getOperand(2), + case 5: + Copy = DAG.getCopyToReg(Op.getOperand(0), PPC::R3, Op.getOperand(3), SDOperand()); Copy = DAG.getCopyToReg(Copy, PPC::R4, Op.getOperand(1),Copy.getValue(1)); // If we haven't noted the R3+R4 are live out, do so now. From evan.cheng at apple.com Fri May 26 18:13:32 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 26 May 2006 18:13:32 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200605262313.SAA18717@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.252 -> 1.253 --- Log message: Make CALL node consistent with RET node. Signness of value has type MVT::i32 instead of MVT::i1. Either is fine except MVT::i32 is probably a legal type for most (if not all) platforms while MVT::i1 is not. --- Diffs of the changes: (+5 -5) SelectionDAGISel.cpp | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.252 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.253 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.252 Fri May 26 18:08:15 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri May 26 18:13:20 2006 @@ -2515,7 +2515,7 @@ default: assert(0 && "Unknown type action!"); case Legal: Ops.push_back(Op); - Ops.push_back(DAG.getConstant(isSigned, MVT::i1)); + Ops.push_back(DAG.getConstant(isSigned, MVT::i32)); break; case Promote: if (MVT::isInteger(VT)) { @@ -2526,7 +2526,7 @@ Op = DAG.getNode(ISD::FP_EXTEND, getTypeToTransformTo(VT), Op); } Ops.push_back(Op); - Ops.push_back(DAG.getConstant(isSigned, MVT::i1)); + Ops.push_back(DAG.getConstant(isSigned, MVT::i32)); break; case Expand: if (VT != MVT::Vector) { @@ -2544,9 +2544,9 @@ std::swap(Lo, Hi); Ops.push_back(Lo); - Ops.push_back(DAG.getConstant(isSigned, MVT::i1)); + Ops.push_back(DAG.getConstant(isSigned, MVT::i32)); Ops.push_back(Hi); - Ops.push_back(DAG.getConstant(isSigned, MVT::i1)); + Ops.push_back(DAG.getConstant(isSigned, MVT::i32)); } else { // Value scalarized into many values. Unimp for now. assert(0 && "Cannot expand i64 -> i16 yet!"); @@ -2565,7 +2565,7 @@ // Insert a VBIT_CONVERT of the MVT::Vector type to the packed type. Op = DAG.getNode(ISD::VBIT_CONVERT, TVT, Op); Ops.push_back(Op); - Ops.push_back(DAG.getConstant(isSigned, MVT::i1)); + Ops.push_back(DAG.getConstant(isSigned, MVT::i32)); } else { assert(0 && "Don't support illegal by-val vector call args yet!"); abort(); From resistor at mac.com Fri May 26 19:31:49 2006 From: resistor at mac.com (Owen Anderson) Date: Fri, 26 May 2006 19:31:49 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LCSSA.cpp Message-ID: <200605270031.TAA19918@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LCSSA.cpp updated: 1.3 -> 1.4 --- Log message: A few small clean-ups, and the addition of an LCSSA statistic. --- Diffs of the changes: (+8 -2) LCSSA.cpp | 10 ++++++++-- 1 files changed, 8 insertions(+), 2 deletions(-) Index: llvm/lib/Transforms/Scalar/LCSSA.cpp diff -u llvm/lib/Transforms/Scalar/LCSSA.cpp:1.3 llvm/lib/Transforms/Scalar/LCSSA.cpp:1.4 --- llvm/lib/Transforms/Scalar/LCSSA.cpp:1.3 Fri May 26 16:19:17 2006 +++ llvm/lib/Transforms/Scalar/LCSSA.cpp Fri May 26 19:31:37 2006 @@ -31,18 +31,22 @@ #include "llvm/Pass.h" #include "llvm/Function.h" #include "llvm/Instructions.h" +#include "llvm/ADT/Statistic.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Support/CFG.h" #include -#include #include using namespace llvm; namespace { + static Statistic<> NumLCSSA("lcssa", "Number of times LCSSA was applied"); + class LCSSA : public FunctionPass { public: + + LoopInfo *LI; // Loop information DominatorTree *DT; // Dominator Tree for the current Loop... DominanceFrontier *DF; // Current Dominance Frontier @@ -51,7 +55,8 @@ bool visitSubloop(Loop* L); /// This transformation requires natural loop information & requires that - /// loop preheaders be inserted into the CFG... + /// loop preheaders be inserted into the CFG. It maintains both of these, + /// as well as the CFG. It also requires dominator information. /// virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); @@ -102,6 +107,7 @@ for (std::set::iterator I = AffectedValues.begin(), E = AffectedValues.end(); I != E; ++I) { + ++NumLCSSA; // We are applying the transformation for (std::vector::iterator BBI = exitBlocks.begin(), BBE = exitBlocks.end(); BBI != BBE; ++BBI) { PHINode *phi = new PHINode((*I)->getType(), "lcssa"); From lattner at cs.uiuc.edu Fri May 26 19:40:28 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 26 May 2006 19:40:28 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200605270040.TAA20156@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAGNodes.h updated: 1.134 -> 1.135 --- Log message: Add a new sentry node type, allowing assertions to catch trivial use-after-deleted errors. --- Diffs of the changes: (+5 -0) SelectionDAGNodes.h | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.134 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.135 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.134 Fri May 26 18:09:09 2006 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Fri May 26 19:40:15 2006 @@ -47,6 +47,10 @@ /// SelectionDAG. /// enum NodeType { + // DELETED_NODE - This is an illegal flag value that is used to catch + // errors. This opcode is not a legal opcode for any node. + DELETED_NODE, + // EntryToken - This is the marker used to indicate the start of the region. EntryToken, @@ -712,6 +716,7 @@ public: virtual ~SDNode() { assert(NumOperands == 0 && "Operand list not cleared before deletion"); + NodeType = ISD::DELETED_NODE; } //===--------------------------------------------------------------------===// From lattner at cs.uiuc.edu Fri May 26 19:43:14 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 26 May 2006 19:43:14 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200605270043.TAA20243@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.170 -> 1.171 --- Log message: Fix a nasty dag combiner bug that caused nondeterminstic crashes (MY FAVORITE!): SimplifySelectOps would eliminate a Select, delete it, then return true. The clients would see that it did something and return null. The top level would see a null return, and decide that nothing happened, proceeding to process the node in other ways: boom. The fix is simple: clients of SimplifySelectOps should return the select node itself. In order to catch really obnoxious boogs like this in the future, add an assert that nodes are not deleted. We do this by checking for a sentry node type that the SDNode dtor sets when a node is destroyed. --- Diffs of the changes: (+15 -4) DAGCombiner.cpp | 19 +++++++++++++++---- 1 files changed, 15 insertions(+), 4 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.170 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.171 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.170 Tue May 16 12:42:15 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Fri May 26 19:43:02 2006 @@ -392,6 +392,8 @@ // If nothing happened, try a target-specific DAG combine. if (RV.Val == 0) { + assert(N->getOpcode() != ISD::DELETED_NODE && + "Node was deleted but visit returned NULL!"); if (N->getOpcode() >= ISD::BUILTIN_OP_END || TLI.hasTargetDAGCombine((ISD::NodeType)N->getOpcode())) RV = TLI.PerformDAGCombine(N, DagCombineInfo); @@ -404,6 +406,10 @@ // CombineTo was used. Since CombineTo takes care of the worklist // mechanics for us, we have no work to do in this case. if (RV.Val != N) { + assert(N->getOpcode() != ISD::DELETED_NODE && + RV.Val->getOpcode() != ISD::DELETED_NODE && + "Node was deleted but visit returned new node!"); + DEBUG(std::cerr << "\nReplacing "; N->dump(); std::cerr << "\nWith: "; RV.Val->dump(&DAG); std::cerr << '\n'); @@ -1573,9 +1579,11 @@ // fold X ? Y : X --> X ? Y : 0 --> X & Y if (MVT::i1 == VT && N0 == N2) return DAG.getNode(ISD::AND, VT, N0, N1); + // If we can fold this based on the true/false value, do so. if (SimplifySelectOps(N, N1, N2)) - return SDOperand(); + return SDOperand(N, 0); // Don't revisit N. + // fold selects based on a setcc into other things, such as min/max/abs if (N0.getOpcode() == ISD::SETCC) // FIXME: @@ -1611,7 +1619,7 @@ // If we can fold this based on the true/false value, do so. if (SimplifySelectOps(N, N2, N3)) - return SDOperand(); + return SDOperand(N, 0); // Don't revisit N. // fold select_cc into other things, such as min/max/abs return SimplifySelectCC(N0, N1, N2, N3, CC); @@ -2814,7 +2822,10 @@ /// SimplifySelectOps - Given a SELECT or a SELECT_CC node, where LHS and RHS /// are the two values being selected between, see if we can simplify the -/// select. +/// select. Callers of this should assume that TheSelect is deleted if this +/// returns true. As such, they should return the appropriate thing (e.g. the +/// node) back to the top-level of the DAG combiner loop to avoid it being +/// looked at. /// bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDOperand LHS, SDOperand RHS) { @@ -3247,7 +3258,7 @@ // Perform the xform if C1 is a single bit. if ((C1 & (C1-1)) == 0) { return DAG.getNode(ISD::SRL, VT, N0, - DAG.getConstant(Log2_64(C1),TLI.getShiftAmountTy())); + DAG.getConstant(Log2_64(C1),TLI.getShiftAmountTy())); } } } From lattner at cs.uiuc.edu Fri May 26 20:16:34 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 26 May 2006 20:16:34 -0500 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/Inline/inline_constprop.ll Message-ID: <200605270116.UAA20470@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/Inline: inline_constprop.ll added (r1.1) --- Log message: New testcase: check that the inliner constant folds instructions on the fly if it can. --- Diffs of the changes: (+15 -0) inline_constprop.ll | 15 +++++++++++++++ 1 files changed, 15 insertions(+) Index: llvm/test/Regression/Transforms/Inline/inline_constprop.ll diff -c /dev/null llvm/test/Regression/Transforms/Inline/inline_constprop.ll:1.1 *** /dev/null Fri May 26 20:16:32 2006 --- llvm/test/Regression/Transforms/Inline/inline_constprop.ll Fri May 26 20:16:22 2006 *************** *** 0 **** --- 1,15 ---- + ; RUN: llvm-as < %s | opt -inline -disable-output && + ; RUN: llvm-as < %s | opt -inline | llvm-dis | not grep callee && + ; RUN: llvm-as < %s | opt -inline | llvm-dis | not grep div + + implementation + + internal int %callee(int %A, int %B) { + %C = div int %A, %B + ret int %C + } + + int %test() { + %X = call int %callee(int 10, int 3) + ret int %X + } From lattner at cs.uiuc.edu Fri May 26 20:17:52 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 26 May 2006 20:17:52 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/Utils/Local.h Message-ID: <200605270117.UAA20557@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms/Utils: Local.h updated: 1.22 -> 1.23 --- Log message: Add an interface to constant fold and instruction given it's opcode, type and operands. --- Diffs of the changes: (+9 -0) Local.h | 9 +++++++++ 1 files changed, 9 insertions(+) Index: llvm/include/llvm/Transforms/Utils/Local.h diff -u llvm/include/llvm/Transforms/Utils/Local.h:1.22 llvm/include/llvm/Transforms/Utils/Local.h:1.23 --- llvm/include/llvm/Transforms/Utils/Local.h:1.22 Thu Oct 27 11:00:10 2005 +++ llvm/include/llvm/Transforms/Utils/Local.h Fri May 26 20:17:40 2006 @@ -48,6 +48,15 @@ /// Constant *ConstantFoldInstruction(Instruction *I); +/// ConstantFoldInstOperands - Attempt to constant fold an instruction with the +/// specified opcode and operands. If successful, the constant result is +/// returned, if not, null is returned. Note that this function can fail when +/// attempting to fold instructions like loads and stores, which have no +/// constant expression form. +/// +Constant *ConstantFoldInstOperands(unsigned Opc, const Type *DestTy, + const std::vector &Ops); + /// ConstantFoldLoadThroughGEPConstantExpr - Given a constant and a /// getelementptr constantexpr, return the constant value being addressed by the From lattner at cs.uiuc.edu Fri May 26 20:18:17 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 26 May 2006 20:18:17 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/Local.cpp Message-ID: <200605270118.UAA20614@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: Local.cpp updated: 1.57 -> 1.58 --- Log message: Refactor some code to expose an interface to constant fold and instruction given it's opcode, typeand operands. --- Diffs of the changes: (+49 -35) Local.cpp | 84 ++++++++++++++++++++++++++++++++++++-------------------------- 1 files changed, 49 insertions(+), 35 deletions(-) Index: llvm/lib/Transforms/Utils/Local.cpp diff -u llvm/lib/Transforms/Utils/Local.cpp:1.57 llvm/lib/Transforms/Utils/Local.cpp:1.58 --- llvm/lib/Transforms/Utils/Local.cpp:1.57 Thu May 25 16:25:12 2006 +++ llvm/lib/Transforms/Utils/Local.cpp Fri May 26 20:18:04 2006 @@ -64,18 +64,6 @@ // If we reach here, all incoming values are the same constant. return Result; - } else if (CallInst *CI = dyn_cast(I)) { - if (Function *F = CI->getCalledFunction()) - if (canConstantFoldCallTo(F)) { - std::vector Args; - for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i) - if (Constant *Op = dyn_cast(CI->getOperand(i))) - Args.push_back(Op); - else - return 0; - return ConstantFoldCall(F, Args); - } - return 0; } Constant *Op0 = 0, *Op1 = 0; @@ -91,37 +79,63 @@ case 0: return 0; } - if (isa(I) || isa(I)) - return ConstantExpr::get(I->getOpcode(), Op0, Op1); + if (isa(I) || isa(I)) { + if (Constant *Op0 = dyn_cast(I->getOperand(0))) + if (Constant *Op1 = dyn_cast(I->getOperand(1))) + return ConstantExpr::get(I->getOpcode(), Op0, Op1); + return 0; // Operands not constants. + } - switch (I->getOpcode()) { + // Scan the operand list, checking to see if the are all constants, if so, + // hand off to ConstantFoldInstOperands. + std::vector Ops; + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) + if (Constant *Op = dyn_cast(I->getOperand(i))) + Ops.push_back(Op); + else + return 0; // All operands not constant! + + return ConstantFoldInstOperands(I->getOpcode(), I->getType(), Ops); +} + +/// ConstantFoldInstOperands - Attempt to constant fold an instruction with the +/// specified opcode and operands. If successful, the constant result is +/// returned, if not, null is returned. Note that this function can fail when +/// attempting to fold instructions like loads and stores, which have no +/// constant expression form. +/// +Constant *llvm::ConstantFoldInstOperands(unsigned Opc, const Type *DestTy, + const std::vector &Ops) { + if (Opc >= Instruction::BinaryOpsBegin && Opc < Instruction::BinaryOpsEnd) + return ConstantExpr::get(Opc, Ops[0], Ops[1]); + + switch (Opc) { default: return 0; + case Instruction::Call: + if (Function *F = dyn_cast(Ops[0])) { + if (canConstantFoldCallTo(F)) { + std::vector Args(Ops.begin()+1, Ops.end()); + return ConstantFoldCall(F, Args); + } + } + return 0; + case Instruction::Shl: + case Instruction::Shr: + return ConstantExpr::get(Opc, Ops[0], Ops[1]); case Instruction::Cast: - return ConstantExpr::getCast(Op0, I->getType()); + return ConstantExpr::getCast(Ops[0], DestTy); case Instruction::Select: - if (Constant *Op2 = dyn_cast(I->getOperand(2))) - return ConstantExpr::getSelect(Op0, Op1, Op2); - return 0; + return ConstantExpr::getSelect(Ops[0], Ops[1], Ops[2]); case Instruction::ExtractElement: - return ConstantExpr::getExtractElement(Op0, Op1); + return ConstantExpr::getExtractElement(Ops[0], Ops[1]); case Instruction::InsertElement: - if (Constant *Op2 = dyn_cast(I->getOperand(2))) - return ConstantExpr::getInsertElement(Op0, Op1, Op2); - return 0; + return ConstantExpr::getInsertElement(Ops[0], Ops[1], Ops[2]); case Instruction::ShuffleVector: - if (Constant *Op2 = dyn_cast(I->getOperand(2))) - return ConstantExpr::getShuffleVector(Op0, Op1, Op2); - return 0; + return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]); case Instruction::GetElementPtr: - std::vector IdxList; - IdxList.reserve(I->getNumOperands()-1); - if (Op1) IdxList.push_back(Op1); - for (unsigned i = 2, e = I->getNumOperands(); i != e; ++i) - if (Constant *C = dyn_cast(I->getOperand(i))) - IdxList.push_back(C); - else - return 0; // Non-constant operand - return ConstantExpr::getGetElementPtr(Op0, IdxList); + return ConstantExpr::getGetElementPtr(Ops[0], + std::vector(Ops.begin()+1, + Ops.end())); } } From lattner at cs.uiuc.edu Fri May 26 20:22:03 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 26 May 2006 20:22:03 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/Utils/Cloning.h Message-ID: <200605270122.UAA20682@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms/Utils: Cloning.h updated: 1.19 -> 1.20 --- Log message: Implement a new method: CloneAndPruneFunctionInto, as documented. --- Diffs of the changes: (+13 -0) Cloning.h | 13 +++++++++++++ 1 files changed, 13 insertions(+) Index: llvm/include/llvm/Transforms/Utils/Cloning.h diff -u llvm/include/llvm/Transforms/Utils/Cloning.h:1.19 llvm/include/llvm/Transforms/Utils/Cloning.h:1.20 --- llvm/include/llvm/Transforms/Utils/Cloning.h:1.19 Wed May 17 13:05:35 2006 +++ llvm/include/llvm/Transforms/Utils/Cloning.h Fri May 26 20:21:50 2006 @@ -130,6 +130,19 @@ const char *NameSuffix = "", ClonedCodeInfo *CodeInfo = 0); +/// CloneAndPruneFunctionInto - This works exactly like CloneFunctionInto, +/// except that it does some simple constant prop and DCE on the fly. The +/// effect of this is to copy significantly less code in cases where (for +/// example) a function call with constant arguments is inlined, and those +/// constant arguments cause a significant amount of code in the callee to be +/// dead. Since this doesn't produce an exactly copy of the input, it can't be +/// used for things like CloneFunction or CloneModule. +void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc, + std::map &ValueMap, + std::vector &Returns, + const char *NameSuffix = "", + ClonedCodeInfo *CodeInfo = 0); + /// CloneTraceInto - Clone T into NewFunc. Original<->clone mapping is /// saved in ValueMap. From lattner at cs.uiuc.edu Fri May 26 20:22:36 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 26 May 2006 20:22:36 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/ValueMapper.cpp CloneFunction.cpp Message-ID: <200605270122.UAA20742@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: ValueMapper.cpp updated: 1.25 -> 1.26 CloneFunction.cpp updated: 1.26 -> 1.27 --- Log message: Implement a new method, CloneAndPruneFunctionInto, as documented. --- Diffs of the changes: (+189 -3) CloneFunction.cpp | 188 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ ValueMapper.cpp | 4 - 2 files changed, 189 insertions(+), 3 deletions(-) Index: llvm/lib/Transforms/Utils/ValueMapper.cpp diff -u llvm/lib/Transforms/Utils/ValueMapper.cpp:1.25 llvm/lib/Transforms/Utils/ValueMapper.cpp:1.26 --- llvm/lib/Transforms/Utils/ValueMapper.cpp:1.25 Fri Apr 7 20:19:12 2006 +++ llvm/lib/Transforms/Utils/ValueMapper.cpp Fri May 26 20:22:24 2006 @@ -30,7 +30,7 @@ if (Constant *C = const_cast(dyn_cast(V))) { if (isa(C) || isa(C) || isa(C) || isa(C) || - isa(C) || isa(V)) + isa(C)) return VMSlot = C; // Primitive constants map directly else if (ConstantArray *CA = dyn_cast(C)) { for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) { @@ -130,8 +130,6 @@ } } - V->dump(); - assert(0 && "Unknown value type: why didn't it get resolved?!"); return 0; } Index: llvm/lib/Transforms/Utils/CloneFunction.cpp diff -u llvm/lib/Transforms/Utils/CloneFunction.cpp:1.26 llvm/lib/Transforms/Utils/CloneFunction.cpp:1.27 --- llvm/lib/Transforms/Utils/CloneFunction.cpp:1.26 Fri Jan 13 12:39:17 2006 +++ llvm/lib/Transforms/Utils/CloneFunction.cpp Fri May 26 20:22:24 2006 @@ -19,6 +19,7 @@ #include "llvm/Instructions.h" #include "llvm/Function.h" #include "ValueMapper.h" +#include "llvm/Transforms/Utils/Local.h" using namespace llvm; // CloneBasicBlock - See comments in Cloning.h @@ -143,3 +144,190 @@ return NewF; } + + +namespace { + /// PruningFunctionCloner - This class is a private class used to implement + /// the CloneAndPruneFunctionInto method. + struct PruningFunctionCloner { + Function *NewFunc; + const Function *OldFunc; + std::map &ValueMap; + std::vector &Returns; + const char *NameSuffix; + ClonedCodeInfo *CodeInfo; + + public: + PruningFunctionCloner(Function *newFunc, const Function *oldFunc, + std::map &valueMap, + std::vector &returns, + const char *nameSuffix, + ClonedCodeInfo *codeInfo) + : NewFunc(newFunc), OldFunc(oldFunc), ValueMap(valueMap), Returns(returns), + NameSuffix(nameSuffix), CodeInfo(codeInfo) { + } + + /// CloneBlock - The specified block is found to be reachable, clone it and + /// anything that it can reach. + void CloneBlock(const BasicBlock *BB); + + public: + /// ConstantFoldMappedInstruction - Constant fold the specified instruction, + /// mapping its operands through ValueMap if they are available. + Constant *ConstantFoldMappedInstruction(const Instruction *I); + }; +} + +/// CloneBlock - The specified block is found to be reachable, clone it and +/// anything that it can reach. +void PruningFunctionCloner::CloneBlock(const BasicBlock *BB) { + Value *&BBEntry = ValueMap[BB]; + + // Have we already cloned this block? + if (BBEntry) return; + + // Nope, clone it now. + BasicBlock *NewBB; + BBEntry = NewBB = new BasicBlock(); + if (BB->hasName()) NewBB->setName(BB->getName()+NameSuffix); + + bool hasCalls = false, hasDynamicAllocas = false, hasStaticAllocas = false; + + // Loop over all instructions, and copy them over, DCE'ing as we go. This + // loop doesn't include the terminator. + for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end(); + II != IE; ++II) { + // If this instruction constant folds, don't bother cloning the instruction, + // instead, just add the constant to the value map. + if (Constant *C = ConstantFoldMappedInstruction(II)) { + ValueMap[II] = C; + continue; + } + + Instruction *NewInst = II->clone(); + if (II->hasName()) + NewInst->setName(II->getName()+NameSuffix); + NewBB->getInstList().push_back(NewInst); + ValueMap[II] = NewInst; // Add instruction map to value. + + hasCalls |= isa(II); + if (const AllocaInst *AI = dyn_cast(II)) { + if (isa(AI->getArraySize())) + hasStaticAllocas = true; + else + hasDynamicAllocas = true; + } + } + + if (CodeInfo) { + CodeInfo->ContainsCalls |= hasCalls; + CodeInfo->ContainsUnwinds |= isa(BB->getTerminator()); + CodeInfo->ContainsDynamicAllocas |= hasDynamicAllocas; + CodeInfo->ContainsDynamicAllocas |= hasStaticAllocas && + BB != &BB->getParent()->front(); + } + + if (ReturnInst *RI = dyn_cast(NewBB->getTerminator())) + Returns.push_back(RI); + + // Recursively clone any reachable successor blocks. + const TerminatorInst *TI = BB->getTerminator(); + for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) + CloneBlock(TI->getSuccessor(i)); +} + +/// ConstantFoldMappedInstruction - Constant fold the specified instruction, +/// mapping its operands through ValueMap if they are available. +Constant *PruningFunctionCloner:: +ConstantFoldMappedInstruction(const Instruction *I) { + if (isa(I) || isa(I)) { + if (Constant *Op0 = dyn_cast_or_null(MapValue(I->getOperand(0), + ValueMap))) + if (Constant *Op1 = dyn_cast_or_null(MapValue(I->getOperand(1), + ValueMap))) + return ConstantExpr::get(I->getOpcode(), Op0, Op1); + return 0; + } + + std::vector Ops; + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) + if (Constant *Op = dyn_cast_or_null(MapValue(I->getOperand(i), + ValueMap))) + Ops.push_back(Op); + else + return 0; // All operands not constant! + + return ConstantFoldInstOperands(I->getOpcode(), I->getType(), Ops); +} + + +/// CloneAndPruneFunctionInto - This works exactly like CloneFunctionInto, +/// except that it does some simple constant prop and DCE on the fly. The +/// effect of this is to copy significantly less code in cases where (for +/// example) a function call with constant arguments is inlined, and those +/// constant arguments cause a significant amount of code in the callee to be +/// dead. Since this doesn't produce an exactly copy of the input, it can't be +/// used for things like CloneFunction or CloneModule. +void llvm::CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc, + std::map &ValueMap, + std::vector &Returns, + const char *NameSuffix, + ClonedCodeInfo *CodeInfo) { + assert(NameSuffix && "NameSuffix cannot be null!"); + +#ifndef NDEBUG + for (Function::const_arg_iterator I = OldFunc->arg_begin(), + E = OldFunc->arg_end(); I != E; ++I) + assert(ValueMap.count(I) && "No mapping from source argument specified!"); +#endif + + PruningFunctionCloner PFC(NewFunc, OldFunc, ValueMap, Returns, + NameSuffix, CodeInfo); + + // Clone the entry block, and anything recursively reachable from it. + PFC.CloneBlock(&OldFunc->getEntryBlock()); + + // Loop over all of the basic blocks in the old function. If the block was + // reachable, we have cloned it and the old block is now in the value map: + // insert it into the new function in the right order. If not, ignore it. + // + for (Function::const_iterator BI = OldFunc->begin(), BE = OldFunc->end(); + BI != BE; ++BI) { + BasicBlock *NewBB = cast_or_null(ValueMap[BI]); + if (NewBB == 0) continue; // Dead block. + + // Add the new block to the new function. + NewFunc->getBasicBlockList().push_back(NewBB); + + // Loop over all of the instructions in the block, fixing up operand + // references as we go. This uses ValueMap to do all the hard work. + // + BasicBlock::iterator I = NewBB->begin(); + + // Handle PHI nodes specially, as we have to remove references to dead + // blocks. + if (PHINode *PN = dyn_cast(I)) { + unsigned NumPreds = PN->getNumIncomingValues(); + for (; (PN = dyn_cast(I)); ++I) { + for (unsigned pred = 0, e = NumPreds; pred != e; ++pred) { + if (BasicBlock *MappedBlock = + cast(ValueMap[PN->getIncomingBlock(pred)])) { + Value *InVal = MapValue(PN->getIncomingValue(pred), ValueMap); + assert(InVal && "Unknown input value?"); + PN->setIncomingValue(pred, InVal); + PN->setIncomingBlock(pred, MappedBlock); + } else { + PN->removeIncomingValue(pred, false); + --pred, --e; // Revisit the next entry. + } + } + } + } + + // Otherwise, remap the rest of the instructions normally. + for (; I != NewBB->end(); ++I) + RemapInstruction(I, ValueMap); + } +} + + From lattner at cs.uiuc.edu Fri May 26 20:23:42 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 26 May 2006 20:23:42 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/ARM/.cvsignore Message-ID: <200605270123.UAA20824@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/ARM: .cvsignore added (r1.1) --- Log message: Ignore generated files --- Diffs of the changes: (+1 -0) .cvsignore | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/ARM/.cvsignore diff -c /dev/null llvm/lib/Target/ARM/.cvsignore:1.1 *** /dev/null Fri May 26 20:23:40 2006 --- llvm/lib/Target/ARM/.cvsignore Fri May 26 20:23:30 2006 *************** *** 0 **** --- 1 ---- + *.inc From lattner at cs.uiuc.edu Fri May 26 20:28:17 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 26 May 2006 20:28:17 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/InlineFunction.cpp Message-ID: <200605270128.UAA20863@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: InlineFunction.cpp updated: 1.41 -> 1.42 --- Log message: Switch the inliner over to using CloneAndPruneFunctionInto. This effectively makes it so that it constant folds instructions on the fly. This is good for several reasons: 0. Many instructions are constant foldable after inlining, particularly if inlining a call with constant arguments. 1. Without this, the inliner has to allocate memory for all of the instructions that can be constant folded, then a subsequent pass has to delete them. This gets the job done without this extra work. 2. This makes the inliner *pass* a bit more aggressive: in particular, it partially solves a phase order issue where the inliner would inline lots of code that folds away to nothing, but think that the resultant function is big because of this code that will be gone. Now the code never exists. This is the first part of a 2-step process. The second part will be smart enough to see when this implicit constant folding propagates a constant into a branch or switch instruction, making CFG edges dead. This implements Transforms/Inline/inline_constprop.ll --- Diffs of the changes: (+9 -5) InlineFunction.cpp | 14 +++++++++----- 1 files changed, 9 insertions(+), 5 deletions(-) Index: llvm/lib/Transforms/Utils/InlineFunction.cpp diff -u llvm/lib/Transforms/Utils/InlineFunction.cpp:1.41 llvm/lib/Transforms/Utils/InlineFunction.cpp:1.42 --- llvm/lib/Transforms/Utils/InlineFunction.cpp:1.41 Sat Jan 14 14:07:50 2006 +++ llvm/lib/Transforms/Utils/InlineFunction.cpp Fri May 26 20:28:04 2006 @@ -193,20 +193,24 @@ std::vector Returns; ClonedCodeInfo InlinedFunctionInfo; { // Scope to destroy ValueMap after cloning. - // Calculate the vector of arguments to pass into the function cloner... std::map ValueMap; + + // Calculate the vector of arguments to pass into the function cloner, which + // matches up the formal to the actual argument values. assert(std::distance(CalledFunc->arg_begin(), CalledFunc->arg_end()) == std::distance(CS.arg_begin(), CS.arg_end()) && "No varargs calls can be inlined!"); - CallSite::arg_iterator AI = CS.arg_begin(); for (Function::const_arg_iterator I = CalledFunc->arg_begin(), E = CalledFunc->arg_end(); I != E; ++I, ++AI) ValueMap[I] = *AI; - // Clone the entire body of the callee into the caller. - CloneFunctionInto(Caller, CalledFunc, ValueMap, Returns, ".i", - &InlinedFunctionInfo); + // We want the inliner to prune the code as it copies. We would LOVE to + // have no dead or constant instructions leftover after inlining occurs + // (which can happen, e.g., because an argument was constant), but we'll be + // happy with whatever the cloner can do. + CloneAndPruneFunctionInto(Caller, CalledFunc, ValueMap, Returns, ".i", + &InlinedFunctionInfo); } // Remember the first block that is newly cloned over. From lattner at cs.uiuc.edu Sat May 27 01:58:08 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 27 May 2006 01:58:08 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/Dominators.h Message-ID: <200605270658.BAA21715@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: Dominators.h updated: 1.55 -> 1.56 --- Log message: Fix pastos in comments --- Diffs of the changes: (+4 -3) Dominators.h | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) Index: llvm/include/llvm/Analysis/Dominators.h diff -u llvm/include/llvm/Analysis/Dominators.h:1.55 llvm/include/llvm/Analysis/Dominators.h:1.56 --- llvm/include/llvm/Analysis/Dominators.h:1.55 Fri May 19 12:17:12 2006 +++ llvm/include/llvm/Analysis/Dominators.h Sat May 27 01:57:55 2006 @@ -574,7 +574,8 @@ }; //===----------------------------------------------------------------------===// -/// DominanceFrontier - Calculate the dominance frontiers for a function. +/// DominanceFrontierBase - Common base class for computing forward and inverse +/// dominance frontiers for a function. /// class DominanceFrontierBase : public DominatorBase { public: @@ -620,8 +621,8 @@ //===------------------------------------- -/// DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to -/// compute a normal dominator tree. +/// DominanceFrontier Class - Concrete subclass of DominanceFrontierBase that is +/// used to compute a forward dominator frontiers. /// class DominanceFrontier : public DominanceFrontierBase { public: From lattner at cs.uiuc.edu Sat May 27 12:28:38 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 27 May 2006 12:28:38 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/CloneFunction.cpp Message-ID: <200605271728.MAA02650@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: CloneFunction.cpp updated: 1.27 -> 1.28 --- Log message: Fix some regression from the inliner patch I committed last night. This fixes ldecod, lencod, and SPASS. --- Diffs of the changes: (+1 -1) CloneFunction.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Transforms/Utils/CloneFunction.cpp diff -u llvm/lib/Transforms/Utils/CloneFunction.cpp:1.27 llvm/lib/Transforms/Utils/CloneFunction.cpp:1.28 --- llvm/lib/Transforms/Utils/CloneFunction.cpp:1.27 Fri May 26 20:22:24 2006 +++ llvm/lib/Transforms/Utils/CloneFunction.cpp Sat May 27 12:28:13 2006 @@ -311,7 +311,7 @@ for (; (PN = dyn_cast(I)); ++I) { for (unsigned pred = 0, e = NumPreds; pred != e; ++pred) { if (BasicBlock *MappedBlock = - cast(ValueMap[PN->getIncomingBlock(pred)])) { + cast_or_null(ValueMap[PN->getIncomingBlock(pred)])) { Value *InVal = MapValue(PN->getIncomingValue(pred), ValueMap); assert(InVal && "Unknown input value?"); PN->setIncomingValue(pred, InVal); From resistor at mac.com Sat May 27 13:47:23 2006 From: resistor at mac.com (Owen Anderson) Date: Sat, 27 May 2006 13:47:23 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LCSSA.cpp Message-ID: <200605271847.NAA02958@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LCSSA.cpp updated: 1.4 -> 1.5 --- Log message: Make LCSSA insert proper Phi nodes throughout the rest of the CFG by computing the iterated Dominance Frontier of the loop-closure Phi's. This is the second phase of the LCSSA pass. The third phase (coming soon) will be to update all uses of loop variables to use the loop-closure Phi's instead. --- Diffs of the changes: (+51 -8) LCSSA.cpp | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 51 insertions(+), 8 deletions(-) Index: llvm/lib/Transforms/Scalar/LCSSA.cpp diff -u llvm/lib/Transforms/Scalar/LCSSA.cpp:1.4 llvm/lib/Transforms/Scalar/LCSSA.cpp:1.5 --- llvm/lib/Transforms/Scalar/LCSSA.cpp:1.4 Fri May 26 19:31:37 2006 +++ llvm/lib/Transforms/Scalar/LCSSA.cpp Sat May 27 13:47:11 2006 @@ -36,12 +36,13 @@ #include "llvm/Analysis/LoopInfo.h" #include "llvm/Support/CFG.h" #include +#include #include using namespace llvm; namespace { - static Statistic<> NumLCSSA("lcssa", "Number of times LCSSA was applied"); + static Statistic<> NumLCSSA("lcssa", "Number of live out of a loop"); class LCSSA : public FunctionPass { public: @@ -64,8 +65,7 @@ AU.addPreservedID(LoopSimplifyID); AU.addRequired(); AU.addPreserved(); - AU.addRequired(); // Not sure if this one will actually - // be needed. + AU.addRequired(); AU.addRequired(); } private: @@ -105,6 +105,11 @@ std::vector exitBlocks; L->getExitBlocks(exitBlocks); + // Phi nodes that need to be IDF-processed + std::vector workList; + + // Iterate over all affected values for this loop and insert Phi nodes + // for them in the appropriate exit blocks for (std::set::iterator I = AffectedValues.begin(), E = AffectedValues.end(); I != E; ++I) { ++NumLCSSA; // We are applying the transformation @@ -112,20 +117,58 @@ BBE = exitBlocks.end(); BBI != BBE; ++BBI) { PHINode *phi = new PHINode((*I)->getType(), "lcssa"); (*BBI)->getInstList().insert((*BBI)->front(), phi); + workList.push_back(phi); + // Since LoopSimplify has been run, we know that all of these predecessors + // are in the loop, so just hook them up in the obvious manner. for (pred_iterator PI = pred_begin(*BBI), PE = pred_end(*BBI); PI != PE; ++PI) phi->addIncoming(*I, *PI); } + } - for (Value::use_iterator UI = (*I)->use_begin(), UE = (*I)->use_end(); - UI != UE; ++UI) { - BasicBlock *UserBB = cast(*UI)->getParent(); - if (!std::binary_search(LoopBlocks.begin(), LoopBlocks.end(), UserBB)) - ; // FIXME: This should update the SSA form. + // Calculate the IDF of these LCSSA Phi nodes, inserting new Phi's where + // necessary. Keep track of these new Phi's in DFPhis. + std::map DFPhis; + for (std::vector::iterator I = workList.begin(), + E = workList.end(); I != E; ++I) { + + // Get the current Phi's DF, and insert Phi nodes. Add these new + // nodes to our worklist. + DominanceFrontier::const_iterator it = DF->find((*I)->getParent()); + if (it != DF->end()) { + const DominanceFrontier::DomSetType &S = it->second; + for (DominanceFrontier::DomSetType::const_iterator P = S.begin(), + PE = S.end(); P != PE; ++P) { + if (DFPhis[*P] == 0) { + // Still doesn't have operands... + PHINode *phi = new PHINode((*I)->getType(), "lcssa"); + (*P)->getInstList().insert((*P)->front(), phi); + DFPhis[*P] = phi; + + workList.push_back(phi); + } + } } + + // Get the predecessor blocks of the current Phi, and use them to hook up + // the operands of the current Phi to any members of DFPhis that dominate + // it. This is a nop for the Phis inserted directly in the exit blocks, + // since they are not dominated by any members of DFPhis. + for (pred_iterator PI = pred_begin((*I)->getParent()), + E = pred_end((*I)->getParent()); PI != E; ++PI) + for (std::map::iterator MI = DFPhis.begin(), + ME = DFPhis.end(); MI != ME; ++MI) + if (DT->getNode((*MI).first)->dominates(DT->getNode(*PI))) { + (*I)->addIncoming((*MI).second, *PI); + + // Since dominate() is not cheap, don't do it more than we have to. + break; + } } + // FIXME: Should update all uses. + return true; // FIXME: Should be more intelligent in our return value. } From lattner at cs.uiuc.edu Sat May 27 22:09:53 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 27 May 2006 22:09:53 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/2004-09-22-LCPCLLVMTutorial.html Message-ID: <200605280309.WAA05105@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: 2004-09-22-LCPCLLVMTutorial.html updated: 1.1 -> 1.2 --- Log message: Add bibtex entry, contributed by Nick Lewycky --- Diffs of the changes: (+0 -0) 0 files changed From reid at x10sys.com Sat May 27 23:21:53 2006 From: reid at x10sys.com (Reid Spencer) Date: Sat, 27 May 2006 23:21:53 -0500 Subject: [llvm-commits] CVS: llvm/test/Feature/llvm2cpp.exp Message-ID: <200605280421.XAA05336@zion.cs.uiuc.edu> Changes in directory llvm/test/Feature: llvm2cpp.exp added (r1.1) --- Log message: Provide an infrastructure for testing the llvm2cpp program (yet to be committed). This infrastructure is only activated when RUNLLVM2CPP=1 is specified on the make command line. Currently it is only supported in the Feature test suite. --- Diffs of the changes: (+3 -0) llvm2cpp.exp | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/test/Feature/llvm2cpp.exp diff -c /dev/null llvm/test/Feature/llvm2cpp.exp:1.1 *** /dev/null Sat May 27 23:21:50 2006 --- llvm/test/Feature/llvm2cpp.exp Sat May 27 23:21:40 2006 *************** *** 0 **** --- 1,3 ---- + load_lib llvm2cpp.exp + + llvm2cpp-test [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx}]] From reid at x10sys.com Sat May 27 23:21:53 2006 From: reid at x10sys.com (Reid Spencer) Date: Sat, 27 May 2006 23:21:53 -0500 Subject: [llvm-commits] CVS: llvm/test/lib/llvm2cpp.exp Message-ID: <200605280421.XAA05344@zion.cs.uiuc.edu> Changes in directory llvm/test/lib: llvm2cpp.exp added (r1.1) --- Log message: Provide an infrastructure for testing the llvm2cpp program (yet to be committed). This infrastructure is only activated when RUNLLVM2CPP=1 is specified on the make command line. Currently it is only supported in the Feature test suite. --- Diffs of the changes: (+79 -0) llvm2cpp.exp | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 79 insertions(+) Index: llvm/test/lib/llvm2cpp.exp diff -c /dev/null llvm/test/lib/llvm2cpp.exp:1.1 *** /dev/null Sat May 27 23:21:50 2006 --- llvm/test/lib/llvm2cpp.exp Sat May 27 23:21:40 2006 *************** *** 0 **** --- 1,79 ---- + # This file defines a tcl proc to assist with testing the llvm2cpp. There are + # no llvm2cpp specific test cases. Instead, it utilizes all the existing test + # cases and makes sure llvm2cpp can run them. The basic idea is that we find + # all the LLVM Assembly (*.ll) files, run llvm2cpp on them to generate a C++ + # program, compile those programs, run them and see if what they produce matches + # the original input to llvm2cpp. + + proc llvm2cpp-test { files } { + # if { $env(LLVM_RUNLLVM2CPP_TEST) == 1 } { + global subdir tooldir libdir objdir srcdir objroot srcroot + set timeout 30 + set path [file join $objdir $subdir] + set llvm2cpp [file join $tooldir llvm2cpp ] + set llvmas [file join $tooldir llvm-as ] + set llvmdis [file join $tooldir llvm-dis ] + + #Make Output Directory if it does not exist already + if { [file exists path] } { + cd $path + } else { + file mkdir $path + cd $path + } + + file mkdir Output + + foreach test $files { + + set filename [file tail $test] + set generated [file join Output $filename.cpp] + set executable [file join Output $filename.exe] + set output [file join Output $filename.gen] + set assembly [file join Output $filename.asm] + + set retval [ catch { + exec -keepnewline $llvmas $test -o - | $llvmdis -f -o $assembly } msg ] + + if { $retval != 0 } { + fail "$test: llvm-as/llvm-dis returned $retval\n$msg" + continue + } + + set retval [ catch { + exec -keepnewline $llvm2cpp -f -o $generated $test } msg] + + if { $retval != 0 } { + fail "$test: llvm2cpp returned $retval\n$msg" + continue + } + + set retval [ catch { + exec -keepnewline gcc -g -D__STDC_LIMIT_MACROS -o $executable $generated -I$srcroot/include -I$objroot/include -L$libdir $libdir/LLVMCore.o -lLLVMSupport $libdir/LLVMbzip2.o -lLLVMSystem -lstdc++ } msg ] + + if { $retval != 0 } { + fail "$test: gcc returned $retval\n$msg" + continue + } + + set retval [ catch { + exec -keepnewline $executable > $output } msg ] + + if { $retval != 0 } { + fail "$test: $filename returned $retval\n$msg" + continue + } + + set retval [ catch { + exec -keepnewline diff -u $assembly $generated } msg ] + + if { $retval != 0 } { + fail "$test: diff returned $retval\n$msg" + continue + } + pass "$test" + } + # } + } + + From reid at x10sys.com Sat May 27 23:21:53 2006 From: reid at x10sys.com (Reid Spencer) Date: Sat, 27 May 2006 23:21:53 -0500 Subject: [llvm-commits] CVS: llvm/test/Makefile Message-ID: <200605280421.XAA05340@zion.cs.uiuc.edu> Changes in directory llvm/test: Makefile updated: 1.87 -> 1.88 --- Log message: Provide an infrastructure for testing the llvm2cpp program (yet to be committed). This infrastructure is only activated when RUNLLVM2CPP=1 is specified on the make command line. Currently it is only supported in the Feature test suite. --- Diffs of the changes: (+8 -0) Makefile | 8 ++++++++ 1 files changed, 8 insertions(+) Index: llvm/test/Makefile diff -u llvm/test/Makefile:1.87 llvm/test/Makefile:1.88 --- llvm/test/Makefile:1.87 Thu Apr 13 15:33:59 2006 +++ llvm/test/Makefile Sat May 27 23:21:40 2006 @@ -27,6 +27,10 @@ RUNTESTFLAGS := --tool $(CLEANED_TESTSUITE) endif +ifndef RUNLLVM2CPP +RUNTESTFLAGS += --ignore llvm2cpp.exp +endif + check-local:: site.exp PATH="$(LLVMToolDir):$(LLVMExmplDir):$(LLVM_SRC_ROOT)/test/Scripts:$(PATH)" \ $(RUNTEST) $(RUNTESTFLAGS) @@ -43,6 +47,10 @@ @echo 'set target_triplet "$(TARGET_TRIPLE)"' >> site.tmp @echo 'set llvmgcc_version "$(LLVMGCC_VERSION)"' >> site.tmp @echo 'set prcontext "$(TCLSH) $(LLVM_SRC_ROOT)/test/Scripts/prcontext.tcl"' >> site.tmp + @echo 'set tooldir "$(ToolDir)"' >>site.tmp + @echo 'set libdir "$(LibDir)"' >>site.tmp + @echo 'set srcroot "$(LLVM_SRC_ROOT)"' >>site.tmp + @echo 'set objroot "$(LLVM_OBJ_ROOT)"' >>site.tmp @echo 'set srcdir "$(LLVM_SRC_ROOT)/test"' >>site.tmp @echo 'set objdir "$(LLVM_OBJ_ROOT)/test"' >>site.tmp @echo 'set llvmgcc "PATH=\"$(LLVMToolDir):$(PATH)\" \"$(LLVMGCC)\""' >> site.tmp From reid at x10sys.com Sun May 28 02:22:57 2006 From: reid at x10sys.com (Reid Spencer) Date: Sun, 28 May 2006 02:22:57 -0500 Subject: [llvm-commits] CVS: llvm/test/Feature/dg.exp Message-ID: <200605280722.CAA11582@zion.cs.uiuc.edu> Changes in directory llvm/test/Feature: dg.exp updated: 1.4 -> 1.5 --- Log message: Fix a problem where dejagnu won't accept the value of global tcl variable "libdir" for some reason. Changing to llvmlibsdir instead fixes it. --- Diffs of the changes: (+0 -1) dg.exp | 1 - 1 files changed, 1 deletion(-) Index: llvm/test/Feature/dg.exp diff -u llvm/test/Feature/dg.exp:1.4 llvm/test/Feature/dg.exp:1.5 --- llvm/test/Feature/dg.exp:1.4 Wed Apr 12 16:57:23 2006 +++ llvm/test/Feature/dg.exp Sun May 28 02:22:42 2006 @@ -1,4 +1,3 @@ load_lib llvm-dg.exp llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $srcdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext $llvmgcc_version - From reid at x10sys.com Sun May 28 02:22:57 2006 From: reid at x10sys.com (Reid Spencer) Date: Sun, 28 May 2006 02:22:57 -0500 Subject: [llvm-commits] CVS: llvm/test/lib/llvm2cpp.exp Message-ID: <200605280722.CAA11581@zion.cs.uiuc.edu> Changes in directory llvm/test/lib: llvm2cpp.exp updated: 1.1 -> 1.2 --- Log message: Fix a problem where dejagnu won't accept the value of global tcl variable "libdir" for some reason. Changing to llvmlibsdir instead fixes it. --- Diffs of the changes: (+5 -6) llvm2cpp.exp | 11 +++++------ 1 files changed, 5 insertions(+), 6 deletions(-) Index: llvm/test/lib/llvm2cpp.exp diff -u llvm/test/lib/llvm2cpp.exp:1.1 llvm/test/lib/llvm2cpp.exp:1.2 --- llvm/test/lib/llvm2cpp.exp:1.1 Sat May 27 23:21:40 2006 +++ llvm/test/lib/llvm2cpp.exp Sun May 28 02:22:42 2006 @@ -7,12 +7,12 @@ proc llvm2cpp-test { files } { # if { $env(LLVM_RUNLLVM2CPP_TEST) == 1 } { - global subdir tooldir libdir objdir srcdir objroot srcroot + global subdir llvmtoolsdir llvmlibsdir objdir srcdir objroot srcroot set timeout 30 set path [file join $objdir $subdir] - set llvm2cpp [file join $tooldir llvm2cpp ] - set llvmas [file join $tooldir llvm-as ] - set llvmdis [file join $tooldir llvm-dis ] + set llvm2cpp [file join $llvmtoolsdir llvm2cpp ] + set llvmas [file join $llvmtoolsdir llvm-as ] + set llvmdis [file join $llvmtoolsdir llvm-dis ] #Make Output Directory if it does not exist already if { [file exists path] } { @@ -49,8 +49,7 @@ } set retval [ catch { - exec -keepnewline gcc -g -D__STDC_LIMIT_MACROS -o $executable $generated -I$srcroot/include -I$objroot/include -L$libdir $libdir/LLVMCore.o -lLLVMSupport $libdir/LLVMbzip2.o -lLLVMSystem -lstdc++ } msg ] - + exec -keepnewline gcc -g -D__STDC_LIMIT_MACROS -o $executable $generated -I$srcroot/include -I$objroot/include -L$llvmlibsdir $llvmlibsdir/LLVMCore.o -lLLVMSupport $llvmlibsdir/LLVMbzip2.o -lLLVMSystem -lstdc++ } msg ] if { $retval != 0 } { fail "$test: gcc returned $retval\n$msg" continue From reid at x10sys.com Sun May 28 02:22:57 2006 From: reid at x10sys.com (Reid Spencer) Date: Sun, 28 May 2006 02:22:57 -0500 Subject: [llvm-commits] CVS: llvm/test/Makefile Message-ID: <200605280722.CAA11583@zion.cs.uiuc.edu> Changes in directory llvm/test: Makefile updated: 1.88 -> 1.89 --- Log message: Fix a problem where dejagnu won't accept the value of global tcl variable "libdir" for some reason. Changing to llvmlibsdir instead fixes it. --- Diffs of the changes: (+2 -2) Makefile | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/test/Makefile diff -u llvm/test/Makefile:1.88 llvm/test/Makefile:1.89 --- llvm/test/Makefile:1.88 Sat May 27 23:21:40 2006 +++ llvm/test/Makefile Sun May 28 02:22:40 2006 @@ -47,8 +47,8 @@ @echo 'set target_triplet "$(TARGET_TRIPLE)"' >> site.tmp @echo 'set llvmgcc_version "$(LLVMGCC_VERSION)"' >> site.tmp @echo 'set prcontext "$(TCLSH) $(LLVM_SRC_ROOT)/test/Scripts/prcontext.tcl"' >> site.tmp - @echo 'set tooldir "$(ToolDir)"' >>site.tmp - @echo 'set libdir "$(LibDir)"' >>site.tmp + @echo 'set llvmtoolsdir "$(ToolDir)"' >>site.tmp + @echo 'set llvmlibsdir "$(LibDir)"' >>site.tmp @echo 'set srcroot "$(LLVM_SRC_ROOT)"' >>site.tmp @echo 'set objroot "$(LLVM_OBJ_ROOT)"' >>site.tmp @echo 'set srcdir "$(LLVM_SRC_ROOT)/test"' >>site.tmp From resistor at mac.com Sun May 28 14:33:41 2006 From: resistor at mac.com (Owen Anderson) Date: Sun, 28 May 2006 14:33:41 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LCSSA.cpp Message-ID: <200605281933.OAA26524@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LCSSA.cpp updated: 1.5 -> 1.6 --- Log message: Major think-o. Iterate over all live out-of-loop values, and perform the other calculations on each individually, rather than trying to delay it and do them all at the end. --- Diffs of the changes: (+37 -37) LCSSA.cpp | 74 +++++++++++++++++++++++++++++++------------------------------- 1 files changed, 37 insertions(+), 37 deletions(-) Index: llvm/lib/Transforms/Scalar/LCSSA.cpp diff -u llvm/lib/Transforms/Scalar/LCSSA.cpp:1.5 llvm/lib/Transforms/Scalar/LCSSA.cpp:1.6 --- llvm/lib/Transforms/Scalar/LCSSA.cpp:1.5 Sat May 27 13:47:11 2006 +++ llvm/lib/Transforms/Scalar/LCSSA.cpp Sun May 28 14:33:28 2006 @@ -42,7 +42,8 @@ using namespace llvm; namespace { - static Statistic<> NumLCSSA("lcssa", "Number of live out of a loop"); + static Statistic<> NumLCSSA("lcssa", + "Number of live out of a loop variables"); class LCSSA : public FunctionPass { public: @@ -125,50 +126,49 @@ ++PI) phi->addIncoming(*I, *PI); } - } - // Calculate the IDF of these LCSSA Phi nodes, inserting new Phi's where - // necessary. Keep track of these new Phi's in DFPhis. - std::map DFPhis; - for (std::vector::iterator I = workList.begin(), - E = workList.end(); I != E; ++I) { - - // Get the current Phi's DF, and insert Phi nodes. Add these new - // nodes to our worklist. - DominanceFrontier::const_iterator it = DF->find((*I)->getParent()); - if (it != DF->end()) { - const DominanceFrontier::DomSetType &S = it->second; - for (DominanceFrontier::DomSetType::const_iterator P = S.begin(), + // Calculate the IDF of these LCSSA Phi nodes, inserting new Phi's where + // necessary. Keep track of these new Phi's in DFPhis. + std::map DFPhis; + for (std::vector::iterator DFI = workList.begin(), + E = workList.end(); DFI != E; ++DFI) { + + // Get the current Phi's DF, and insert Phi nodes. Add these new + // nodes to our worklist. + DominanceFrontier::const_iterator it = DF->find((*DFI)->getParent()); + if (it != DF->end()) { + const DominanceFrontier::DomSetType &S = it->second; + for (DominanceFrontier::DomSetType::const_iterator P = S.begin(), PE = S.end(); P != PE; ++P) { - if (DFPhis[*P] == 0) { - // Still doesn't have operands... - PHINode *phi = new PHINode((*I)->getType(), "lcssa"); - (*P)->getInstList().insert((*P)->front(), phi); - DFPhis[*P] = phi; + if (DFPhis[*P] == 0) { + // Still doesn't have operands... + PHINode *phi = new PHINode((*DFI)->getType(), "lcssa"); + (*P)->getInstList().insert((*P)->front(), phi); + DFPhis[*P] = phi; - workList.push_back(phi); + workList.push_back(phi); + } } } - } - // Get the predecessor blocks of the current Phi, and use them to hook up - // the operands of the current Phi to any members of DFPhis that dominate - // it. This is a nop for the Phis inserted directly in the exit blocks, - // since they are not dominated by any members of DFPhis. - for (pred_iterator PI = pred_begin((*I)->getParent()), - E = pred_end((*I)->getParent()); PI != E; ++PI) - for (std::map::iterator MI = DFPhis.begin(), - ME = DFPhis.end(); MI != ME; ++MI) - if (DT->getNode((*MI).first)->dominates(DT->getNode(*PI))) { - (*I)->addIncoming((*MI).second, *PI); + // Get the predecessor blocks of the current Phi, and use them to hook up + // the operands of the current Phi to any members of DFPhis that dominate + // it. This is a nop for the Phis inserted directly in the exit blocks, + // since they are not dominated by any members of DFPhis. + for (pred_iterator PI = pred_begin((*DFI)->getParent()), + E = pred_end((*DFI)->getParent()); PI != E; ++PI) + for (std::map::iterator MI = DFPhis.begin(), + ME = DFPhis.end(); MI != ME; ++MI) + if (DT->getNode((*MI).first)->dominates(DT->getNode(*PI))) { + (*DFI)->addIncoming((*MI).second, *PI); - // Since dominate() is not cheap, don't do it more than we have to. - break; - } - } - - // FIXME: Should update all uses. + // Since dominate() is not cheap, don't do it more than we have to. + break; + } + } + // FIXME: Should update all uses. + } return true; // FIXME: Should be more intelligent in our return value. } From llvm at cs.uiuc.edu Sun May 28 19:24:07 2006 From: llvm at cs.uiuc.edu (LLVM) Date: Sun, 28 May 2006 19:24:07 -0500 Subject: [llvm-commits] CVS: llvm/tools/llvm2cpp/ Message-ID: <200605290024.TAA27638@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm2cpp: --- Log message: Directory /var/cvs/llvm/llvm/tools/llvm2cpp added to the repository --- Diffs of the changes: (+0 -0) 0 files changed From reid at x10sys.com Sun May 28 19:57:34 2006 From: reid at x10sys.com (Reid Spencer) Date: Sun, 28 May 2006 19:57:34 -0500 Subject: [llvm-commits] CVS: llvm/tools/llvm2cpp/CppWriter.cpp CppWriter.h Makefile llvm2cpp.cpp Message-ID: <200605290057.TAA27768@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm2cpp: CppWriter.cpp added (r1.1) CppWriter.h added (r1.1) Makefile added (r1.1) llvm2cpp.cpp added (r1.1) --- Log message: Initial Commit of llvm2cpp This is a safekeeping commit. The program is not finished. It currently handles modules, types, global variables and function declarations. Blocks and instructions remain to be done. --- Diffs of the changes: (+2174 -0) CppWriter.cpp | 1995 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ CppWriter.h | 18 Makefile | 23 llvm2cpp.cpp | 138 ++++ 4 files changed, 2174 insertions(+) Index: llvm/tools/llvm2cpp/CppWriter.cpp diff -c /dev/null llvm/tools/llvm2cpp/CppWriter.cpp:1.1 *** /dev/null Sun May 28 19:57:32 2006 --- llvm/tools/llvm2cpp/CppWriter.cpp Sun May 28 19:57:22 2006 *************** *** 0 **** --- 1,1995 ---- + //===-- CppWriter.cpp - Printing LLVM IR as a C++ Source File -------------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file implements the writing of the LLVM IR as a set of C++ calls to the + // LLVM IR interface. The input module is assumed to be verified. + // + //===----------------------------------------------------------------------===// + + #include "llvm/CallingConv.h" + #include "llvm/Constants.h" + #include "llvm/DerivedTypes.h" + #include "llvm/InlineAsm.h" + #include "llvm/Instruction.h" + #include "llvm/Instructions.h" + #include "llvm/Module.h" + #include "llvm/SymbolTable.h" + #include "llvm/Support/CFG.h" + #include "llvm/ADT/StringExtras.h" + #include "llvm/ADT/STLExtras.h" + #include "llvm/Support/MathExtras.h" + #include + #include + + using namespace llvm; + + namespace { + /// This class provides computation of slot numbers for LLVM Assembly writing. + /// @brief LLVM Assembly Writing Slot Computation. + class SlotMachine { + + /// @name Types + /// @{ + public: + + /// @brief A mapping of Values to slot numbers + typedef std::map ValueMap; + typedef std::map TypeMap; + + /// @brief A plane with next slot number and ValueMap + struct ValuePlane { + unsigned next_slot; ///< The next slot number to use + ValueMap map; ///< The map of Value* -> unsigned + ValuePlane() { next_slot = 0; } ///< Make sure we start at 0 + }; + + struct TypePlane { + unsigned next_slot; + TypeMap map; + TypePlane() { next_slot = 0; } + void clear() { map.clear(); next_slot = 0; } + }; + + /// @brief The map of planes by Type + typedef std::map TypedPlanes; + + /// @} + /// @name Constructors + /// @{ + public: + /// @brief Construct from a module + SlotMachine(const Module *M ); + + /// @} + /// @name Accessors + /// @{ + public: + /// Return the slot number of the specified value in it's type + /// plane. Its an error to ask for something not in the SlotMachine. + /// Its an error to ask for a Type* + int getSlot(const Value *V); + int getSlot(const Type*Ty); + + /// Determine if a Value has a slot or not + bool hasSlot(const Value* V); + bool hasSlot(const Type* Ty); + + /// @} + /// @name Mutators + /// @{ + public: + /// If you'd like to deal with a function instead of just a module, use + /// this method to get its data into the SlotMachine. + void incorporateFunction(const Function *F) { + TheFunction = F; + FunctionProcessed = false; + } + + /// After calling incorporateFunction, use this method to remove the + /// most recently incorporated function from the SlotMachine. This + /// will reset the state of the machine back to just the module contents. + void purgeFunction(); + + /// @} + /// @name Implementation Details + /// @{ + private: + /// Values can be crammed into here at will. If they haven't + /// been inserted already, they get inserted, otherwise they are ignored. + /// Either way, the slot number for the Value* is returned. + unsigned createSlot(const Value *V); + unsigned createSlot(const Type* Ty); + + /// Insert a value into the value table. Return the slot number + /// that it now occupies. BadThings(TM) will happen if you insert a + /// Value that's already been inserted. + unsigned insertValue( const Value *V ); + unsigned insertValue( const Type* Ty); + + /// Add all of the module level global variables (and their initializers) + /// and function declarations, but not the contents of those functions. + void processModule(); + + /// Add all of the functions arguments, basic blocks, and instructions + void processFunction(); + + SlotMachine(const SlotMachine &); // DO NOT IMPLEMENT + void operator=(const SlotMachine &); // DO NOT IMPLEMENT + + /// @} + /// @name Data + /// @{ + public: + + /// @brief The module for which we are holding slot numbers + const Module* TheModule; + + /// @brief The function for which we are holding slot numbers + const Function* TheFunction; + bool FunctionProcessed; + + /// @brief The TypePlanes map for the module level data + TypedPlanes mMap; + TypePlane mTypes; + + /// @brief The TypePlanes map for the function level data + TypedPlanes fMap; + TypePlane fTypes; + + /// @} + + }; + + typedef std::vector TypeList; + typedef std::map TypeMap; + typedef std::map ValueMap; + + void WriteAsOperandInternal(std::ostream &Out, const Value *V, + bool PrintName, TypeMap &TypeTable, + SlotMachine *Machine); + + void WriteAsOperandInternal(std::ostream &Out, const Type *T, + bool PrintName, TypeMap& TypeTable, + SlotMachine *Machine); + + const Module *getModuleFromVal(const Value *V) { + if (const Argument *MA = dyn_cast(V)) + return MA->getParent() ? MA->getParent()->getParent() : 0; + else if (const BasicBlock *BB = dyn_cast(V)) + return BB->getParent() ? BB->getParent()->getParent() : 0; + else if (const Instruction *I = dyn_cast(V)) { + const Function *M = I->getParent() ? I->getParent()->getParent() : 0; + return M ? M->getParent() : 0; + } else if (const GlobalValue *GV = dyn_cast(V)) + return GV->getParent(); + return 0; + } + + // getLLVMName - Turn the specified string into an 'LLVM name', which is either + // prefixed with % (if the string only contains simple characters) or is + // surrounded with ""'s (if it has special chars in it). + std::string getLLVMName(const std::string &Name, + bool prefixName = true) { + assert(!Name.empty() && "Cannot get empty name!"); + + // First character cannot start with a number... + if (Name[0] >= '0' && Name[0] <= '9') + return "\"" + Name + "\""; + + // Scan to see if we have any characters that are not on the "white list" + for (unsigned i = 0, e = Name.size(); i != e; ++i) { + char C = Name[i]; + assert(C != '"' && "Illegal character in LLVM value name!"); + if ((C < 'a' || C > 'z') && (C < 'A' || C > 'Z') && (C < '0' || C > '9') && + C != '-' && C != '.' && C != '_') + return "\"" + Name + "\""; + } + + // If we get here, then the identifier is legal to use as a "VarID". + if (prefixName) + return "%"+Name; + else + return Name; + } + + + /// fillTypeNameTable - If the module has a symbol table, take all global types + /// and stuff their names into the TypeNames map. + /// + void fillTypeNameTable(const Module *M, TypeMap& TypeNames) { + if (!M) return; + const SymbolTable &ST = M->getSymbolTable(); + SymbolTable::type_const_iterator TI = ST.type_begin(); + for (; TI != ST.type_end(); ++TI ) { + // As a heuristic, don't insert pointer to primitive types, because + // they are used too often to have a single useful name. + // + const Type *Ty = cast(TI->second); + if (!isa(Ty) || + !cast(Ty)->getElementType()->isPrimitiveType() || + isa(cast(Ty)->getElementType())) + TypeNames.insert(std::make_pair(Ty, getLLVMName(TI->first))); + } + } + + void calcTypeName(const Type *Ty, + std::vector &TypeStack, + TypeMap& TypeNames, + std::string & Result){ + if (Ty->isPrimitiveType() && !isa(Ty)) { + Result += Ty->getDescription(); // Base case + return; + } + + // Check to see if the type is named. + TypeMap::iterator I = TypeNames.find(Ty); + if (I != TypeNames.end()) { + Result += I->second; + return; + } + + if (isa(Ty)) { + Result += "opaque"; + return; + } + + // Check to see if the Type is already on the stack... + unsigned Slot = 0, CurSize = TypeStack.size(); + while (Slot < CurSize && TypeStack[Slot] != Ty) ++Slot; // Scan for type + + // This is another base case for the recursion. In this case, we know + // that we have looped back to a type that we have previously visited. + // Generate the appropriate upreference to handle this. + if (Slot < CurSize) { + Result += "\\" + utostr(CurSize-Slot); // Here's the upreference + return; + } + + TypeStack.push_back(Ty); // Recursive case: Add us to the stack.. + + switch (Ty->getTypeID()) { + case Type::FunctionTyID: { + const FunctionType *FTy = cast(Ty); + calcTypeName(FTy->getReturnType(), TypeStack, TypeNames, Result); + Result += " ("; + for (FunctionType::param_iterator I = FTy->param_begin(), + E = FTy->param_end(); I != E; ++I) { + if (I != FTy->param_begin()) + Result += ", "; + calcTypeName(*I, TypeStack, TypeNames, Result); + } + if (FTy->isVarArg()) { + if (FTy->getNumParams()) Result += ", "; + Result += "..."; + } + Result += ")"; + break; + } + case Type::StructTyID: { + const StructType *STy = cast(Ty); + Result += "{ "; + for (StructType::element_iterator I = STy->element_begin(), + E = STy->element_end(); I != E; ++I) { + if (I != STy->element_begin()) + Result += ", "; + calcTypeName(*I, TypeStack, TypeNames, Result); + } + Result += " }"; + break; + } + case Type::PointerTyID: + calcTypeName(cast(Ty)->getElementType(), + TypeStack, TypeNames, Result); + Result += "*"; + break; + case Type::ArrayTyID: { + const ArrayType *ATy = cast(Ty); + Result += "[" + utostr(ATy->getNumElements()) + " x "; + calcTypeName(ATy->getElementType(), TypeStack, TypeNames, Result); + Result += "]"; + break; + } + case Type::PackedTyID: { + const PackedType *PTy = cast(Ty); + Result += "<" + utostr(PTy->getNumElements()) + " x "; + calcTypeName(PTy->getElementType(), TypeStack, TypeNames, Result); + Result += ">"; + break; + } + case Type::OpaqueTyID: + Result += "opaque"; + break; + default: + Result += ""; + } + + TypeStack.pop_back(); // Remove self from stack... + return; + } + + + /// printTypeInt - The internal guts of printing out a type that has a + /// potentially named portion. + /// + std::ostream &printTypeInt(std::ostream &Out, const Type *Ty,TypeMap&TypeNames){ + // Primitive types always print out their description, regardless of whether + // they have been named or not. + // + if (Ty->isPrimitiveType() && !isa(Ty)) + return Out << Ty->getDescription(); + + // Check to see if the type is named. + TypeMap::iterator I = TypeNames.find(Ty); + if (I != TypeNames.end()) return Out << I->second; + + // Otherwise we have a type that has not been named but is a derived type. + // Carefully recurse the type hierarchy to print out any contained symbolic + // names. + // + std::vector TypeStack; + std::string TypeName; + calcTypeName(Ty, TypeStack, TypeNames, TypeName); + TypeNames.insert(std::make_pair(Ty, TypeName));//Cache type name for later use + return (Out << TypeName); + } + + + /// WriteTypeSymbolic - This attempts to write the specified type as a symbolic + /// type, iff there is an entry in the modules symbol table for the specified + /// type or one of it's component types. This is slower than a simple x << Type + /// + std::ostream &WriteTypeSymbolic(std::ostream &Out, const Type *Ty, + const Module *M) { + Out << ' '; + + // If they want us to print out a type, attempt to make it symbolic if there + // is a symbol table in the module... + if (M) { + TypeMap TypeNames; + fillTypeNameTable(M, TypeNames); + + return printTypeInt(Out, Ty, TypeNames); + } else { + return Out << Ty->getDescription(); + } + } + + // PrintEscapedString - Print each character of the specified string, escaping + // it if it is not printable or if it is an escape char. + void PrintEscapedString(const std::string &Str, std::ostream &Out) { + for (unsigned i = 0, e = Str.size(); i != e; ++i) { + unsigned char C = Str[i]; + if (isprint(C) && C != '"' && C != '\\') { + Out << C; + } else { + Out << '\\' + << (char) ((C/16 < 10) ? ( C/16 +'0') : ( C/16 -10+'A')) + << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A')); + } + } + } + + /// @brief Internal constant writer. + void WriteConstantInternal(std::ostream &Out, const Constant *CV, + bool PrintName, + TypeMap& TypeTable, + SlotMachine *Machine) { + const int IndentSize = 4; + static std::string Indent = "\n"; + if (const ConstantBool *CB = dyn_cast(CV)) { + Out << (CB == ConstantBool::True ? "true" : "false"); + } else if (const ConstantSInt *CI = dyn_cast(CV)) { + Out << CI->getValue(); + } else if (const ConstantUInt *CI = dyn_cast(CV)) { + Out << CI->getValue(); + } else if (const ConstantFP *CFP = dyn_cast(CV)) { + // We would like to output the FP constant value in exponential notation, + // but we cannot do this if doing so will lose precision. Check here to + // make sure that we only output it in exponential format if we can parse + // the value back and get the same value. + // + std::string StrVal = ftostr(CFP->getValue()); + + // Check to make sure that the stringized number is not some string like + // "Inf" or NaN, that atof will accept, but the lexer will not. Check that + // the string matches the "[-+]?[0-9]" regex. + // + if ((StrVal[0] >= '0' && StrVal[0] <= '9') || + ((StrVal[0] == '-' || StrVal[0] == '+') && + (StrVal[1] >= '0' && StrVal[1] <= '9'))) + // Reparse stringized version! + if (atof(StrVal.c_str()) == CFP->getValue()) { + Out << StrVal; + return; + } + + // Otherwise we could not reparse it to exactly the same value, so we must + // output the string in hexadecimal format! + assert(sizeof(double) == sizeof(uint64_t) && + "assuming that double is 64 bits!"); + Out << "0x" << utohexstr(DoubleToBits(CFP->getValue())); + + } else if (isa(CV)) { + Out << "zeroinitializer"; + } else if (const ConstantArray *CA = dyn_cast(CV)) { + // As a special case, print the array as a string if it is an array of + // ubytes or an array of sbytes with positive values. + // + const Type *ETy = CA->getType()->getElementType(); + if (CA->isString()) { + Out << "c\""; + PrintEscapedString(CA->getAsString(), Out); + Out << "\""; + + } else { // Cannot output in string format... + Out << '['; + if (CA->getNumOperands()) { + Out << ' '; + printTypeInt(Out, ETy, TypeTable); + WriteAsOperandInternal(Out, CA->getOperand(0), + PrintName, TypeTable, Machine); + for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) { + Out << ", "; + printTypeInt(Out, ETy, TypeTable); + WriteAsOperandInternal(Out, CA->getOperand(i), PrintName, + TypeTable, Machine); + } + } + Out << " ]"; + } + } else if (const ConstantStruct *CS = dyn_cast(CV)) { + Out << '{'; + unsigned N = CS->getNumOperands(); + if (N) { + if (N > 2) { + Indent += std::string(IndentSize, ' '); + Out << Indent; + } else { + Out << ' '; + } + printTypeInt(Out, CS->getOperand(0)->getType(), TypeTable); + + WriteAsOperandInternal(Out, CS->getOperand(0), + PrintName, TypeTable, Machine); + + for (unsigned i = 1; i < N; i++) { + Out << ", "; + if (N > 2) Out << Indent; + printTypeInt(Out, CS->getOperand(i)->getType(), TypeTable); + + WriteAsOperandInternal(Out, CS->getOperand(i), + PrintName, TypeTable, Machine); + } + if (N > 2) Indent.resize(Indent.size() - IndentSize); + } + + Out << " }"; + } else if (const ConstantPacked *CP = dyn_cast(CV)) { + const Type *ETy = CP->getType()->getElementType(); + assert(CP->getNumOperands() > 0 && + "Number of operands for a PackedConst must be > 0"); + Out << '<'; + Out << ' '; + printTypeInt(Out, ETy, TypeTable); + WriteAsOperandInternal(Out, CP->getOperand(0), + PrintName, TypeTable, Machine); + for (unsigned i = 1, e = CP->getNumOperands(); i != e; ++i) { + Out << ", "; + printTypeInt(Out, ETy, TypeTable); + WriteAsOperandInternal(Out, CP->getOperand(i), PrintName, + TypeTable, Machine); + } + Out << " >"; + } else if (isa(CV)) { + Out << "null"; + + } else if (isa(CV)) { + Out << "undef"; + + } else if (const ConstantExpr *CE = dyn_cast(CV)) { + Out << CE->getOpcodeName() << " ("; + + for (User::const_op_iterator OI=CE->op_begin(); OI != CE->op_end(); ++OI) { + printTypeInt(Out, (*OI)->getType(), TypeTable); + WriteAsOperandInternal(Out, *OI, PrintName, TypeTable, Machine); + if (OI+1 != CE->op_end()) + Out << ", "; + } + + if (CE->getOpcode() == Instruction::Cast) { + Out << " to "; + printTypeInt(Out, CE->getType(), TypeTable); + } + Out << ')'; + + } else { + Out << ""; + } + } + + + /// WriteAsOperand - Write the name of the specified value out to the specified + /// ostream. This can be useful when you just want to print int %reg126, not + /// the whole instruction that generated it. + /// + void WriteAsOperandInternal(std::ostream &Out, const Value *V, + bool PrintName, TypeMap& TypeTable, + SlotMachine *Machine) { + Out << ' '; + if ((PrintName || isa(V)) && V->hasName()) + Out << getLLVMName(V->getName()); + else { + const Constant *CV = dyn_cast(V); + if (CV && !isa(CV)) { + WriteConstantInternal(Out, CV, PrintName, TypeTable, Machine); + } else if (const InlineAsm *IA = dyn_cast(V)) { + Out << "asm "; + if (IA->hasSideEffects()) + Out << "sideeffect "; + Out << '"'; + PrintEscapedString(IA->getAsmString(), Out); + Out << "\", \""; + PrintEscapedString(IA->getConstraintString(), Out); + Out << '"'; + } else { + int Slot = Machine->getSlot(V); + if (Slot != -1) + Out << '%' << Slot; + else + Out << ""; + } + } + } + + /// WriteAsOperand - Write the name of the specified value out to the specified + /// ostream. This can be useful when you just want to print int %reg126, not + /// the whole instruction that generated it. + /// + std::ostream &WriteAsOperand(std::ostream &Out, const Value *V, + bool PrintType, bool PrintName, + const Module *Context) { + TypeMap TypeNames; + if (Context == 0) Context = getModuleFromVal(V); + + if (Context) + fillTypeNameTable(Context, TypeNames); + + if (PrintType) + printTypeInt(Out, V->getType(), TypeNames); + + WriteAsOperandInternal(Out, V, PrintName, TypeNames, 0); + return Out; + } + + /// WriteAsOperandInternal - Write the name of the specified value out to + /// the specified ostream. This can be useful when you just want to print + /// int %reg126, not the whole instruction that generated it. + /// + void WriteAsOperandInternal(std::ostream &Out, const Type *T, + bool PrintName, TypeMap& TypeTable, + SlotMachine *Machine) { + Out << ' '; + int Slot = Machine->getSlot(T); + if (Slot != -1) + Out << '%' << Slot; + else + Out << ""; + } + + /// WriteAsOperand - Write the name of the specified value out to the specified + /// ostream. This can be useful when you just want to print int %reg126, not + /// the whole instruction that generated it. + /// + std::ostream &WriteAsOperand(std::ostream &Out, const Type *Ty, + bool PrintType, bool PrintName, + const Module *Context) { + TypeMap TypeNames; + assert(Context != 0 && "Can't write types as operand without module context"); + + fillTypeNameTable(Context, TypeNames); + + // if (PrintType) + // printTypeInt(Out, V->getType(), TypeNames); + + printTypeInt(Out, Ty, TypeNames); + + WriteAsOperandInternal(Out, Ty, PrintName, TypeNames, 0); + return Out; + } + + class CppWriter { + std::ostream &Out; + SlotMachine &Machine; + const Module *TheModule; + unsigned long uniqueNum; + TypeMap TypeNames; + ValueMap ValueNames; + TypeMap UnresolvedTypes; + TypeList TypeStack; + + public: + inline CppWriter(std::ostream &o, SlotMachine &Mac, const Module *M) + : Out(o), Machine(Mac), TheModule(M), uniqueNum(0), TypeNames(), + ValueNames(), UnresolvedTypes(), TypeStack() { } + + inline void write(const Module *M) { printModule(M); } + inline void write(const GlobalVariable *G) { printGlobal(G); } + inline void write(const Function *F) { printFunction(F); } + inline void write(const BasicBlock *BB) { printBasicBlock(BB); } + inline void write(const Instruction *I) { printInstruction(*I); } + inline void write(const Constant *CPV) { printConstant(CPV); } + inline void write(const Type *Ty) { printType(Ty); } + + void writeOperand(const Value *Op, bool PrintType, bool PrintName = true); + + const Module* getModule() { return TheModule; } + + private: + void printModule(const Module *M); + void printTypes(const Module* M); + void printConstants(const Module* M); + void printConstant(const Constant *CPV); + void printGlobal(const GlobalVariable *GV); + void printFunction(const Function *F); + void printArgument(const Argument *FA); + void printBasicBlock(const BasicBlock *BB); + void printInstruction(const Instruction &I); + void printSymbolTable(const SymbolTable &ST); + void printLinkageType(GlobalValue::LinkageTypes LT); + void printCallingConv(unsigned cc); + + + // printType - Go to extreme measures to attempt to print out a short, + // symbolic version of a type name. + // + std::ostream &printType(const Type *Ty) { + return printTypeInt(Out, Ty, TypeNames); + } + + // printTypeAtLeastOneLevel - Print out one level of the possibly complex type + // without considering any symbolic types that we may have equal to it. + // + std::ostream &printTypeAtLeastOneLevel(const Type *Ty); + + // printInfoComment - Print a little comment after the instruction indicating + // which slot it occupies. + void printInfoComment(const Value &V); + + std::string getCppName(const Type* val); + std::string getCppName(const Value* val); + inline void printCppName(const Value* val); + inline void printCppName(const Type* val); + bool isOnStack(const Type*) const; + inline void printTypeDef(const Type* Ty); + bool printTypeDefInternal(const Type* Ty); + }; + + std::string + CppWriter::getCppName(const Value* val) { + std::string name; + ValueMap::iterator I = ValueNames.find(val); + if (I != ValueNames.end()) { + name = I->second; + } else { + const char* prefix; + switch (val->getType()->getTypeID()) { + case Type::VoidTyID: prefix = "void_"; break; + case Type::BoolTyID: prefix = "bool_"; break; + case Type::UByteTyID: prefix = "ubyte_"; break; + case Type::SByteTyID: prefix = "sbyte_"; break; + case Type::UShortTyID: prefix = "ushort_"; break; + case Type::ShortTyID: prefix = "short_"; break; + case Type::UIntTyID: prefix = "uint_"; break; + case Type::IntTyID: prefix = "int_"; break; + case Type::ULongTyID: prefix = "ulong_"; break; + case Type::LongTyID: prefix = "long_"; break; + case Type::FloatTyID: prefix = "float_"; break; + case Type::DoubleTyID: prefix = "double_"; break; + case Type::LabelTyID: prefix = "label_"; break; + case Type::FunctionTyID: prefix = "func_"; break; + case Type::StructTyID: prefix = "struct_"; break; + case Type::ArrayTyID: prefix = "array_"; break; + case Type::PointerTyID: prefix = "ptr_"; break; + case Type::PackedTyID: prefix = "packed_"; break; + default: prefix = "other_"; break; + } + name = ValueNames[val] = std::string(prefix) + + (val->hasName() ? val->getName() : utostr(uniqueNum++)); + } + return name; + } + + void + CppWriter::printCppName(const Value* val) { + PrintEscapedString(getCppName(val),Out); + } + + void + CppWriter::printCppName(const Type* Ty) + { + PrintEscapedString(getCppName(Ty),Out); + } + + // Gets the C++ name for a type. Returns true if we already saw the type, + // false otherwise. + // + inline const std::string* + findTypeName(const SymbolTable& ST, const Type* Ty) + { + SymbolTable::type_const_iterator TI = ST.type_begin(); + SymbolTable::type_const_iterator TE = ST.type_end(); + for (;TI != TE; ++TI) + if (TI->second == Ty) + return &(TI->first); + return 0; + } + + std::string + CppWriter::getCppName(const Type* Ty) + { + // First, handle the primitive types .. easy + if (Ty->isPrimitiveType()) { + switch (Ty->getTypeID()) { + case Type::VoidTyID: return "Type::VoidTy"; + case Type::BoolTyID: return "Type::BoolTy"; + case Type::UByteTyID: return "Type::UByteTy"; + case Type::SByteTyID: return "Type::SByteTy"; + case Type::UShortTyID: return "Type::UShortTy"; + case Type::ShortTyID: return "Type::ShortTy"; + case Type::UIntTyID: return "Type::UIntTy"; + case Type::IntTyID: return "Type::IntTy"; + case Type::ULongTyID: return "Type::ULongTy"; + case Type::LongTyID: return "Type::LongTy"; + case Type::FloatTyID: return "Type::FloatTy"; + case Type::DoubleTyID: return "Type::DoubleTy"; + case Type::LabelTyID: return "Type::LabelTy"; + default: + assert(!"Can't get here"); + break; + } + return "Type::VoidTy"; // shouldn't be returned, but make it sensible + } + + // Now, see if we've seen the type before and return that + TypeMap::iterator I = TypeNames.find(Ty); + if (I != TypeNames.end()) + return I->second; + + // Okay, let's build a new name for this type. Start with a prefix + const char* prefix = 0; + switch (Ty->getTypeID()) { + case Type::FunctionTyID: prefix = "FuncTy_"; break; + case Type::StructTyID: prefix = "StructTy_"; break; + case Type::ArrayTyID: prefix = "ArrayTy_"; break; + case Type::PointerTyID: prefix = "PointerTy_"; break; + case Type::OpaqueTyID: prefix = "OpaqueTy_"; break; + case Type::PackedTyID: prefix = "PackedTy_"; break; + default: prefix = "OtherTy_"; break; // prevent breakage + } + + // See if the type has a name in the symboltable and build accordingly + const std::string* tName = findTypeName(TheModule->getSymbolTable(), Ty); + std::string name; + if (tName) + name = std::string(prefix) + *tName; + else + name = std::string(prefix) + utostr(uniqueNum++); + + // Save the name + return TypeNames[Ty] = name; + } + + /// printTypeAtLeastOneLevel - Print out one level of the possibly complex type + /// without considering any symbolic types that we may have equal to it. + /// + std::ostream &CppWriter::printTypeAtLeastOneLevel(const Type *Ty) { + if (const FunctionType *FTy = dyn_cast(Ty)) { + printType(FTy->getReturnType()) << " ("; + for (FunctionType::param_iterator I = FTy->param_begin(), + E = FTy->param_end(); I != E; ++I) { + if (I != FTy->param_begin()) + Out << ", "; + printType(*I); + } + if (FTy->isVarArg()) { + if (FTy->getNumParams()) Out << ", "; + Out << "..."; + } + Out << ')'; + } else if (const StructType *STy = dyn_cast(Ty)) { + Out << "{ "; + for (StructType::element_iterator I = STy->element_begin(), + E = STy->element_end(); I != E; ++I) { + if (I != STy->element_begin()) + Out << ", "; + printType(*I); + } + Out << " }"; + } else if (const PointerType *PTy = dyn_cast(Ty)) { + printType(PTy->getElementType()) << '*'; + } else if (const ArrayType *ATy = dyn_cast(Ty)) { + Out << '[' << ATy->getNumElements() << " x "; + printType(ATy->getElementType()) << ']'; + } else if (const PackedType *PTy = dyn_cast(Ty)) { + Out << '<' << PTy->getNumElements() << " x "; + printType(PTy->getElementType()) << '>'; + } + else if (const OpaqueType *OTy = dyn_cast(Ty)) { + Out << "opaque"; + } else { + if (!Ty->isPrimitiveType()) + Out << ""; + printType(Ty); + } + return Out; + } + + + void CppWriter::writeOperand(const Value *Operand, bool PrintType, + bool PrintName) { + if (Operand != 0) { + if (PrintType) { Out << ' '; printType(Operand->getType()); } + WriteAsOperandInternal(Out, Operand, PrintName, TypeNames, &Machine); + } else { + Out << ""; + } + } + + + void CppWriter::printModule(const Module *M) { + Out << "\n// Module Construction\n"; + Out << "Module* mod = new Module(\""; + PrintEscapedString(M->getModuleIdentifier(),Out); + Out << "\");\n"; + Out << "mod->setEndianness("; + switch (M->getEndianness()) { + case Module::LittleEndian: Out << "Module::LittleEndian);\n"; break; + case Module::BigEndian: Out << "Module::BigEndian);\n"; break; + case Module::AnyEndianness:Out << "Module::AnyEndianness);\n"; break; + } + Out << "mod->setPointerSize("; + switch (M->getPointerSize()) { + case Module::Pointer32: Out << "Module::Pointer32);\n"; break; + case Module::Pointer64: Out << "Module::Pointer64);\n"; break; + case Module::AnyPointerSize: Out << "Module::AnyPointerSize);\n"; break; + } + if (!M->getTargetTriple().empty()) + Out << "mod->setTargetTriple(\"" << M->getTargetTriple() << "\");\n"; + + if (!M->getModuleInlineAsm().empty()) { + Out << "mod->setModuleInlineAsm(\""; + PrintEscapedString(M->getModuleInlineAsm(),Out); + Out << "\");\n"; + } + + // Loop over the dependent libraries and emit them. + Module::lib_iterator LI = M->lib_begin(); + Module::lib_iterator LE = M->lib_end(); + while (LI != LE) { + Out << "mod->addLibrary(\"" << *LI << "\");\n"; + ++LI; + } + + // Print out all the type definitions + Out << "\n// Type Definitions\n"; + printTypes(M); + + // Print out all the constants declarations + Out << "\n// Constants Construction\n"; + printConstants(M); + + // Process the global variables + Out << "\n// Global Variable Construction\n"; + for (Module::const_global_iterator I = M->global_begin(), E = M->global_end(); + I != E; ++I) { + printGlobal(I); + } + + // Output all of the functions. + Out << "\n// Function Construction\n"; + for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) + printFunction(I); + } + + void + CppWriter::printCallingConv(unsigned cc){ + // Print the calling convention. + switch (cc) { + default: + case CallingConv::C: Out << "CallingConv::C"; break; + case CallingConv::CSRet: Out << "CallingConv::CSRet"; break; + case CallingConv::Fast: Out << "CallingConv::Fast"; break; + case CallingConv::Cold: Out << "CallingConv::Cold"; break; + case CallingConv::FirstTargetCC: Out << "CallingConv::FirstTargetCC"; break; + } + } + + void + CppWriter::printLinkageType(GlobalValue::LinkageTypes LT) { + switch (LT) { + case GlobalValue::InternalLinkage: + Out << "GlobalValue::InternalLinkage"; break; + case GlobalValue::LinkOnceLinkage: + Out << "GlobalValue::LinkOnceLinkage "; break; + case GlobalValue::WeakLinkage: + Out << "GlobalValue::WeakLinkage"; break; + case GlobalValue::AppendingLinkage: + Out << "GlobalValue::AppendingLinkage"; break; + case GlobalValue::ExternalLinkage: + Out << "GlobalValue::ExternalLinkage"; break; + case GlobalValue::GhostLinkage: + Out << "GlobalValue::GhostLinkage"; break; + } + } + void CppWriter::printGlobal(const GlobalVariable *GV) { + Out << "\n"; + Out << "GlobalVariable* "; + printCppName(GV); + Out << " = new GlobalVariable(\n"; + Out << " /*Type=*/"; + printCppName(GV->getType()->getElementType()); + Out << ",\n"; + Out << " /*isConstant=*/" << (GV->isConstant()?"true":"false") + << ",\n /*Linkage=*/"; + printLinkageType(GV->getLinkage()); + Out << ",\n /*Initializer=*/"; + if (GV->hasInitializer()) { + printCppName(GV->getInitializer()); + } else { + Out << "0"; + } + Out << ",\n /*Name=*/\""; + PrintEscapedString(GV->getName(),Out); + Out << "\",\n mod);\n"; + + if (GV->hasSection()) { + printCppName(GV); + Out << "->setSection(\""; + PrintEscapedString(GV->getSection(),Out); + Out << "\");\n"; + } + if (GV->getAlignment()) { + printCppName(GV); + Out << "->setAlignment(" << utostr(GV->getAlignment()) << ");\n"; + }; + } + + bool + CppWriter::isOnStack(const Type* Ty) const { + TypeList::const_iterator TI = + std::find(TypeStack.begin(),TypeStack.end(),Ty); + return TI != TypeStack.end(); + } + + // Prints a type definition. Returns true if it could not resolve all the types + // in the definition but had to use a forward reference. + void + CppWriter::printTypeDef(const Type* Ty) { + assert(TypeStack.empty()); + TypeStack.clear(); + printTypeDefInternal(Ty); + assert(TypeStack.empty()); + // early resolve as many unresolved types as possible. Search the unresolved + // types map for the type we just printed. Now that its definition is complete + // we can resolve any preview references to it. This prevents a cascade of + // unresolved types. + TypeMap::iterator I = UnresolvedTypes.find(Ty); + if (I != UnresolvedTypes.end()) { + Out << "cast(" << I->second + << "_fwd.get())->refineAbstractTypeTo(" << I->second << ");\n"; + Out << I->second << " = cast<"; + switch (Ty->getTypeID()) { + case Type::FunctionTyID: Out << "FunctionType"; break; + case Type::ArrayTyID: Out << "ArrayType"; break; + case Type::StructTyID: Out << "StructType"; break; + case Type::PackedTyID: Out << "PackedType"; break; + case Type::PointerTyID: Out << "PointerType"; break; + case Type::OpaqueTyID: Out << "OpaqueType"; break; + default: Out << "NoSuchDerivedType"; break; + } + Out << ">(" << I->second << "_fwd.get());\n"; + UnresolvedTypes.erase(I); + } + Out << "\n"; + } + + bool + CppWriter::printTypeDefInternal(const Type* Ty) { + // We don't print definitions for primitive types + if (Ty->isPrimitiveType()) + return false; + + // Determine if the name is in the name list before we modify that list. + TypeMap::const_iterator TNI = TypeNames.find(Ty); + + // Everything below needs the name for the type so get it now + std::string typeName(getCppName(Ty)); + + // Search the type stack for recursion. If we find it, then generate this + // as an OpaqueType, but make sure not to do this multiple times because + // the type could appear in multiple places on the stack. Once the opaque + // definition is issues, it must not be re-issued. Consequently we have to + // check the UnresolvedTypes list as well. + if (isOnStack(Ty)) { + TypeMap::const_iterator I = UnresolvedTypes.find(Ty); + if (I == UnresolvedTypes.end()) { + Out << "PATypeHolder " << typeName << "_fwd = OpaqueType::get();\n"; + UnresolvedTypes[Ty] = typeName; + return true; + } + } + + // Avoid printing things we have already printed. Since TNI was obtained + // before the name was inserted with getCppName and because we know the name + // is not on the stack (currently being defined), we can surmise here that if + // we got the name we've also already emitted its definition. + if (TNI != TypeNames.end()) + return false; + + // We're going to print a derived type which, by definition, contains other + // types. So, push this one we're printing onto the type stack to assist with + // recursive definitions. + TypeStack.push_back(Ty); // push on type stack + bool didRecurse = false; + + // Print the type definition + switch (Ty->getTypeID()) { + case Type::FunctionTyID: { + const FunctionType* FT = cast(Ty); + Out << "std::vector" << typeName << "_args;\n"; + FunctionType::param_iterator PI = FT->param_begin(); + FunctionType::param_iterator PE = FT->param_end(); + for (; PI != PE; ++PI) { + const Type* argTy = static_cast(*PI); + bool isForward = printTypeDefInternal(argTy); + std::string argName(getCppName(argTy)); + Out << typeName << "_args.push_back(" << argName; + if (isForward) + Out << "_fwd"; + Out << ");\n"; + } + bool isForward = printTypeDefInternal(FT->getReturnType()); + std::string retTypeName(getCppName(FT->getReturnType())); + Out << "FunctionType* " << typeName << " = FunctionType::get(\n" + << " /*Result=*/" << retTypeName; + if (isForward) + Out << "_fwd"; + Out << ",\n /*Params=*/" << typeName << "_args,\n /*isVarArg=*/" + << (FT->isVarArg() ? "true" : "false") << ");\n"; + break; + } + case Type::StructTyID: { + const StructType* ST = cast(Ty); + Out << "std::vector" << typeName << "_fields;\n"; + StructType::element_iterator EI = ST->element_begin(); + StructType::element_iterator EE = ST->element_end(); + for (; EI != EE; ++EI) { + const Type* fieldTy = static_cast(*EI); + bool isForward = printTypeDefInternal(fieldTy); + std::string fieldName(getCppName(fieldTy)); + Out << typeName << "_fields.push_back(" << fieldName; + if (isForward) + Out << "_fwd"; + Out << ");\n"; + } + Out << "StructType* " << typeName << " = StructType::get(" + << typeName << "_fields);\n"; + break; + } + case Type::ArrayTyID: { + const ArrayType* AT = cast(Ty); + const Type* ET = AT->getElementType(); + bool isForward = printTypeDefInternal(ET); + std::string elemName(getCppName(ET)); + Out << "ArrayType* " << typeName << " = ArrayType::get(" + << elemName << (isForward ? "_fwd" : "") + << ", " << utostr(AT->getNumElements()) << ");\n"; + break; + } + case Type::PointerTyID: { + const PointerType* PT = cast(Ty); + const Type* ET = PT->getElementType(); + bool isForward = printTypeDefInternal(ET); + std::string elemName(getCppName(ET)); + Out << "PointerType* " << typeName << " = PointerType::get(" + << elemName << (isForward ? "_fwd" : "") << ");\n"; + break; + } + case Type::PackedTyID: { + const PackedType* PT = cast(Ty); + const Type* ET = PT->getElementType(); + bool isForward = printTypeDefInternal(ET); + std::string elemName(getCppName(ET)); + Out << "PackedType* " << typeName << " = PackedType::get(" + << elemName << (isForward ? "_fwd" : "") + << ", " << utostr(PT->getNumElements()) << ");\n"; + break; + } + case Type::OpaqueTyID: { + const OpaqueType* OT = cast(Ty); + Out << "OpaqueType* " << typeName << " = OpaqueType::get();\n"; + break; + } + default: + assert(!"Invalid TypeID"); + } + + // Pop us off the type stack + TypeStack.pop_back(); + + // We weren't a recursive type + return false; + } + + void + CppWriter::printTypes(const Module* M) { + // Add all of the global variables to the value table... + for (Module::const_global_iterator I = TheModule->global_begin(), + E = TheModule->global_end(); I != E; ++I) { + if (I->hasInitializer()) + printTypeDef(I->getInitializer()->getType()); + printTypeDef(I->getType()); + } + + // Add all the functions to the table + for (Module::const_iterator FI = TheModule->begin(), FE = TheModule->end(); + FI != FE; ++FI) { + printTypeDef(FI->getReturnType()); + printTypeDef(FI->getFunctionType()); + // Add all the function arguments + for(Function::const_arg_iterator AI = FI->arg_begin(), + AE = FI->arg_end(); AI != AE; ++AI) { + printTypeDef(AI->getType()); + } + + // Add all of the basic blocks and instructions + for (Function::const_iterator BB = FI->begin(), + E = FI->end(); BB != E; ++BB) { + printTypeDef(BB->getType()); + for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; + ++I) { + printTypeDef(I->getType()); + } + } + } + } + + void + CppWriter::printConstants(const Module* M) { + const SymbolTable& ST = M->getSymbolTable(); + + // Print the constants, in type plane order. + for (SymbolTable::plane_const_iterator PI = ST.plane_begin(); + PI != ST.plane_end(); ++PI ) { + SymbolTable::value_const_iterator VI = ST.value_begin(PI->first); + SymbolTable::value_const_iterator VE = ST.value_end(PI->first); + + for (; VI != VE; ++VI) { + const Value* V = VI->second; + const Constant *CPV = dyn_cast(V) ; + if (CPV && !isa(V)) { + printConstant(CPV); + } + } + } + + // Add all of the global variables to the value table... + for (Module::const_global_iterator I = TheModule->global_begin(), + E = TheModule->global_end(); I != E; ++I) + if (I->hasInitializer()) + printConstant(I->getInitializer()); + } + + // printSymbolTable - Run through symbol table looking for constants + // and types. Emit their declarations. + void CppWriter::printSymbolTable(const SymbolTable &ST) { + + // Print the types. + for (SymbolTable::type_const_iterator TI = ST.type_begin(); + TI != ST.type_end(); ++TI ) { + Out << "\t" << getLLVMName(TI->first) << " = type "; + + // Make sure we print out at least one level of the type structure, so + // that we do not get %FILE = type %FILE + // + printTypeAtLeastOneLevel(TI->second) << "\n"; + } + + } + + + /// printConstant - Print out a constant pool entry... + /// + void CppWriter::printConstant(const Constant *CV) { + const int IndentSize = 2; + static std::string Indent = "\n"; + std::string constName(getCppName(CV)); + std::string typeName(getCppName(CV->getType())); + if (CV->isNullValue()) { + Out << "Constant* " << constName << " = Constant::getNullValue(" + << typeName << ");\n"; + return; + } + if (const ConstantBool *CB = dyn_cast(CV)) { + Out << "Constant* " << constName << " = ConstantBool::get(" + << (CB == ConstantBool::True ? "true" : "false") + << ");"; + } else if (const ConstantSInt *CI = dyn_cast(CV)) { + Out << "Constant* " << constName << " = ConstantSInt::get(" + << typeName << ", " << CI->getValue() << ");"; + } else if (const ConstantUInt *CI = dyn_cast(CV)) { + Out << "Constant* " << constName << " = ConstantUInt::get(" + << typeName << ", " << CI->getValue() << ");"; + } else if (isa(CV)) { + Out << "Constant* " << constName << " = ConstantAggregateZero::get(" + << typeName << ");"; + } else if (isa(CV)) { + Out << "Constant* " << constName << " = ConstanPointerNull::get(" + << typeName << ");"; + } else if (const ConstantFP *CFP = dyn_cast(CV)) { + Out << "ConstantFP::get(" << typeName << ", "; + // We would like to output the FP constant value in exponential notation, + // but we cannot do this if doing so will lose precision. Check here to + // make sure that we only output it in exponential format if we can parse + // the value back and get the same value. + // + std::string StrVal = ftostr(CFP->getValue()); + + // Check to make sure that the stringized number is not some string like + // "Inf" or NaN, that atof will accept, but the lexer will not. Check that + // the string matches the "[-+]?[0-9]" regex. + // + if ((StrVal[0] >= '0' && StrVal[0] <= '9') || + ((StrVal[0] == '-' || StrVal[0] == '+') && + (StrVal[1] >= '0' && StrVal[1] <= '9'))) + // Reparse stringized version! + if (atof(StrVal.c_str()) == CFP->getValue()) { + Out << StrVal; + return; + } + + // Otherwise we could not reparse it to exactly the same value, so we must + // output the string in hexadecimal format! + assert(sizeof(double) == sizeof(uint64_t) && + "assuming that double is 64 bits!"); + Out << "0x" << utohexstr(DoubleToBits(CFP->getValue())) << ");"; + } else if (const ConstantArray *CA = dyn_cast(CV)) { + if (CA->isString()) { + Out << "Constant* " << constName << " = ConstantArray::get(\""; + PrintEscapedString(CA->getAsString(),Out); + Out << "\");"; + } else { + Out << "std::vector " << constName << "_elems;\n"; + unsigned N = CA->getNumOperands(); + for (unsigned i = 0; i < N; ++i) { + printConstant(CA->getOperand(i)); + Out << constName << "_elems.push_back(" + << getCppName(CA->getOperand(i)) << ");\n"; + } + Out << "Constant* " << constName << " = ConstantArray::get(" + << typeName << ", " << constName << "_elems);"; + } + } else if (const ConstantStruct *CS = dyn_cast(CV)) { + Out << "std::vector " << constName << "_fields;\n"; + unsigned N = CS->getNumOperands(); + for (unsigned i = 0; i < N; i++) { + printConstant(CS->getOperand(i)); + Out << constName << "_fields.push_back(" + << getCppName(CA->getOperand(i)) << ");\n"; + } + Out << "Constant* " << constName << " = ConstantStruct::get(" + << typeName << ", " << constName << "_fields);"; + } else if (const ConstantPacked *CP = dyn_cast(CV)) { + Out << "std::vector " << constName << "_elems;\n"; + unsigned N = CP->getNumOperands(); + for (unsigned i = 0; i < N; ++i) { + printConstant(CP->getOperand(i)); + Out << constName << "_elems.push_back(" + << getCppName(CP->getOperand(i)) << ");\n"; + } + Out << "Constant* " << constName << " = ConstantPacked::get(" + << typeName << ", " << constName << "_elems);"; + } else if (isa(CV)) { + Out << "Constant* " << constName << " = UndefValue::get(" + << typeName << ");\n"; + } else if (const ConstantExpr *CE = dyn_cast(CV)) { + Out << CE->getOpcodeName() << " ("; + + for (User::const_op_iterator OI=CE->op_begin(); OI != CE->op_end(); ++OI) { + //printTypeInt(Out, (*OI)->getType(), TypeTable); + //WriteAsOperandInternal(Out, *OI, PrintName, TypeTable, Machine); + if (OI+1 != CE->op_end()) + Out << ", "; + } + + if (CE->getOpcode() == Instruction::Cast) { + Out << " to "; + // printTypeInt(Out, CE->getType(), TypeTable); + } + Out << ')'; + + } else { + Out << ""; + } + Out << "\n"; + } + + /// printFunction - Print all aspects of a function. + /// + void CppWriter::printFunction(const Function *F) { + std::string funcTypeName(getCppName(F->getFunctionType())); + + Out << "Function* "; + printCppName(F); + Out << " = new Function(" << funcTypeName << ", " ; + printLinkageType(F->getLinkage()); + Out << ", \"" << F->getName() << "\", mod);\n"; + printCppName(F); + Out << "->setCallingConv("; + printCallingConv(F->getCallingConv()); + Out << ");\n"; + if (F->hasSection()) { + printCppName(F); + Out << "->setSection(" << F->getSection() << ");\n"; + } + if (F->getAlignment()) { + printCppName(F); + Out << "->setAlignment(" << F->getAlignment() << ");\n"; + } + + Machine.incorporateFunction(F); + + if (!F->isExternal()) { + Out << "{"; + // Output all of its basic blocks... for the function + for (Function::const_iterator I = F->begin(), E = F->end(); I != E; ++I) + printBasicBlock(I); + Out << "}\n"; + } + + Machine.purgeFunction(); + } + + /// printArgument - This member is called for every argument that is passed into + /// the function. Simply print it out + /// + void CppWriter::printArgument(const Argument *Arg) { + // Insert commas as we go... the first arg doesn't get a comma + if (Arg != Arg->getParent()->arg_begin()) Out << ", "; + + // Output type... + printType(Arg->getType()); + + // Output name, if available... + if (Arg->hasName()) + Out << ' ' << getLLVMName(Arg->getName()); + } + + /// printBasicBlock - This member is called for each basic block in a method. + /// + void CppWriter::printBasicBlock(const BasicBlock *BB) { + if (BB->hasName()) { // Print out the label if it exists... + Out << "\n" << getLLVMName(BB->getName(), false) << ':'; + } else if (!BB->use_empty()) { // Don't print block # of no uses... + Out << "\n;