From lattner at cs.uiuc.edu Mon Oct 20 00:46:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Oct 20 00:46:02 2003 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/JIT/Emitter.cpp Message-ID: <200310200545.AAA04139@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/JIT: Emitter.cpp updated: 1.29 -> 1.30 --- Log message: Hrm, a relic from the past. How cute :) --- Diffs of the changes: (+1 -1) Index: llvm/lib/ExecutionEngine/JIT/Emitter.cpp diff -u llvm/lib/ExecutionEngine/JIT/Emitter.cpp:1.29 llvm/lib/ExecutionEngine/JIT/Emitter.cpp:1.30 --- llvm/lib/ExecutionEngine/JIT/Emitter.cpp:1.29 Thu Oct 16 18:33:38 2003 +++ llvm/lib/ExecutionEngine/JIT/Emitter.cpp Mon Oct 20 00:45:49 2003 @@ -21,7 +21,7 @@ #include "Config/sys/mman.h" namespace { - Statistic<> NumBytes("jello", "Number of bytes of machine code compiled"); + Statistic<> NumBytes("jit", "Number of bytes of machine code compiled"); VM *TheVM = 0; /// JITMemoryManager - Manage memory for the JIT code generation in a logical, From lattner at cs.uiuc.edu Mon Oct 20 00:54:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Oct 20 00:54:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/PeepholeOptimizer.cpp X86InstrInfo.td Message-ID: <200310200553.AAA04167@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: PeepholeOptimizer.cpp updated: 1.3 -> 1.4 X86InstrInfo.td updated: 1.12 -> 1.13 --- Log message: Emit x86 instructions for: A = B op C, where A and B are 16-bit registers, C is a constant which can be sign-extended from 8 bits without value loss, and op is one of: add, sub, imul, and, or, xor. This allows the JIT to emit the one byte version of the constant instead of the two or 4 byte version. Because these instructions are very common, this can save a LOT of code space. For example, I sampled two benchmarks, 176.gcc and 254.gap. BM Old New Reduction 176.gcc 2673621 2548962 4.89% 254.gap 498261 475104 4.87% Note that while the percentage is not spectacular, this did eliminate 124.6 _KILOBYTES_ of codespace from gcc. Not bad. Note that this doesn't effect the llc version at all, because the assembler already does this optimization. --- Diffs of the changes: (+54 -0) Index: llvm/lib/Target/X86/PeepholeOptimizer.cpp diff -u llvm/lib/Target/X86/PeepholeOptimizer.cpp:1.3 llvm/lib/Target/X86/PeepholeOptimizer.cpp:1.4 --- llvm/lib/Target/X86/PeepholeOptimizer.cpp:1.3 Wed Aug 13 13:18:14 2003 +++ llvm/lib/Target/X86/PeepholeOptimizer.cpp Mon Oct 20 00:53:31 2003 @@ -51,6 +51,46 @@ } return false; + // A large number of X86 instructions have forms which take an 8-bit + // immediate despite the fact that the operands are 16 or 32 bits. Because + // this can save three bytes of code size (and icache space), we want to + // shrink them if possible. + case X86::ADDri16: case X86::ADDri32: + case X86::SUBri16: case X86::SUBri32: + case X86::IMULri16: case X86::IMULri32: + case X86::ANDri16: case X86::ANDri32: + case X86::ORri16: case X86::ORri32: + case X86::XORri16: case X86::XORri32: + assert(MI->getNumOperands() == 3 && "These should all have 3 operands!"); + if (MI->getOperand(2).isImmediate()) { + int Val = MI->getOperand(2).getImmedValue(); + // If the value is the same when signed extended from 8 bits... + if (Val == (signed int)(signed char)Val) { + unsigned Opcode; + switch (MI->getOpcode()) { + default: assert(0 && "Unknown opcode value!"); + case X86::ADDri16: Opcode = X86::ADDri16b; break; + case X86::ADDri32: Opcode = X86::ADDri32b; break; + case X86::SUBri16: Opcode = X86::SUBri16b; break; + case X86::SUBri32: Opcode = X86::SUBri32b; break; + case X86::IMULri16: Opcode = X86::IMULri16b; break; + case X86::IMULri32: Opcode = X86::IMULri32b; break; + case X86::ANDri16: Opcode = X86::ANDri16b; break; + case X86::ANDri32: Opcode = X86::ANDri32b; break; + case X86::ORri16: Opcode = X86::ORri16b; break; + case X86::ORri32: Opcode = X86::ORri32b; break; + case X86::XORri16: Opcode = X86::XORri16b; break; + case X86::XORri32: Opcode = X86::XORri32b; break; + } + unsigned R0 = MI->getOperand(0).getReg(); + unsigned R1 = MI->getOperand(1).getReg(); + *I = BuildMI(Opcode, 2, R0).addReg(R1).addZImm((char)Val); + delete MI; + return true; + } + } + return false; + #if 0 case X86::MOVir32: Size++; case X86::MOVir16: Size++; Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.12 llvm/lib/Target/X86/X86InstrInfo.td:1.13 --- llvm/lib/Target/X86/X86InstrInfo.td:1.12 Sun Oct 19 22:42:58 2003 +++ llvm/lib/Target/X86/X86InstrInfo.td Mon Oct 20 00:53:31 2003 @@ -243,6 +243,8 @@ def ADDri8 : I2A8 <"add", 0x80, MRMS0r >, Pattern<(set R8 , (plus R8 , imm))>; def ADDri16 : I2A16<"add", 0x81, MRMS0r >, OpSize, Pattern<(set R16, (plus R16, imm))>; def ADDri32 : I2A32<"add", 0x81, MRMS0r >, Pattern<(set R32, (plus R32, imm))>; +def ADDri16b : I2A8 <"add", 0x83, MRMS0r >, OpSize; // ADDri with sign extended 8 bit imm +def ADDri32b : I2A8 <"add", 0x83, MRMS0r >; def ADCrr32 : I2A32<"adc", 0x11, MRMDestReg>; // R32 += imm32+Carry @@ -252,6 +254,8 @@ def SUBri8 : I2A8 <"sub", 0x80, MRMS5r >, Pattern<(set R8 , (minus R8 , imm))>; def SUBri16 : I2A16<"sub", 0x81, MRMS5r >, OpSize, Pattern<(set R16, (minus R16, imm))>; def SUBri32 : I2A32<"sub", 0x81, MRMS5r >, Pattern<(set R32, (minus R32, imm))>; +def SUBri16b : I2A8 <"sub", 0x83, MRMS5r >, OpSize; +def SUBri32b : I2A8 <"sub", 0x83, MRMS5r >; def SBBrr32 : I2A32<"sbb", 0x19, MRMDestReg>; // R32 -= R32+Carry @@ -259,6 +263,9 @@ def IMULrr32 : I2A32<"imul", 0xAF, MRMSrcReg>, TB , Pattern<(set R32, (times R32, R32))>; def IMULri16 : I2A16<"imul", 0x69, MRMSrcReg>, OpSize; def IMULri32 : I2A32<"imul", 0x69, MRMSrcReg>; +def IMULri16b : I2A8<"imul", 0x6B, MRMSrcReg>, OpSize; +def IMULri32b : I2A8<"imul", 0x6B, MRMSrcReg>; + // Logical operators... def ANDrr8 : I2A8 <"and", 0x20, MRMDestReg>, Pattern<(set R8 , (and R8 , R8 ))>; @@ -267,6 +274,8 @@ def ANDri8 : I2A8 <"and", 0x80, MRMS4r >, Pattern<(set R8 , (and R8 , imm))>; def ANDri16 : I2A16<"and", 0x81, MRMS4r >, OpSize, Pattern<(set R16, (and R16, imm))>; def ANDri32 : I2A32<"and", 0x81, MRMS4r >, Pattern<(set R32, (and R32, imm))>; +def ANDri16b : I2A8 <"and", 0x83, MRMS4r >, OpSize; +def ANDri32b : I2A8 <"and", 0x83, MRMS4r >; def ORrr8 : I2A8 <"or" , 0x08, MRMDestReg>, Pattern<(set R8 , (or R8 , R8 ))>; def ORrr16 : I2A16<"or" , 0x09, MRMDestReg>, OpSize, Pattern<(set R16, (or R16, R16))>; @@ -274,6 +283,9 @@ def ORri8 : I2A8 <"or" , 0x80, MRMS1r >, Pattern<(set R8 , (or R8 , imm))>; def ORri16 : I2A16<"or" , 0x81, MRMS1r >, OpSize, Pattern<(set R16, (or R16, imm))>; def ORri32 : I2A32<"or" , 0x81, MRMS1r >, Pattern<(set R32, (or R32, imm))>; +def ORri16b : I2A8 <"or" , 0x83, MRMS1r >, OpSize; +def ORri32b : I2A8 <"or" , 0x83, MRMS1r >; + def XORrr8 : I2A8 <"xor", 0x30, MRMDestReg>, Pattern<(set R8 , (xor R8 , R8 ))>; def XORrr16 : I2A16<"xor", 0x31, MRMDestReg>, OpSize, Pattern<(set R16, (xor R16, R16))>; @@ -281,6 +293,8 @@ def XORri8 : I2A8 <"xor", 0x80, MRMS6r >, Pattern<(set R8 , (xor R8 , imm))>; def XORri16 : I2A16<"xor", 0x81, MRMS6r >, OpSize, Pattern<(set R16, (xor R16, imm))>; def XORri32 : I2A32<"xor", 0x81, MRMS6r >, Pattern<(set R32, (xor R32, imm))>; +def XORri16b : I2A8 <"xor", 0x83, MRMS6r >, OpSize; +def XORri32b : I2A8 <"xor", 0x83, MRMS6r >; // Test instructions are just like AND, except they don't generate a result. def TESTrr8 : X86Inst<"test", 0x84, MRMDestReg, Arg8 >; // flags = R8 & R8 From lattner at cs.uiuc.edu Mon Oct 20 00:55:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Oct 20 00:55:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/InlineSimple.cpp Message-ID: <200310200554.AAA04181@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: InlineSimple.cpp updated: 1.54 -> 1.55 --- Log message: Reorder for minor efficiency gain --- Diffs of the changes: (+1 -1) Index: llvm/lib/Transforms/IPO/InlineSimple.cpp diff -u llvm/lib/Transforms/IPO/InlineSimple.cpp:1.54 llvm/lib/Transforms/IPO/InlineSimple.cpp:1.55 --- llvm/lib/Transforms/IPO/InlineSimple.cpp:1.54 Wed Oct 15 11:48:29 2003 +++ llvm/lib/Transforms/IPO/InlineSimple.cpp Mon Oct 20 00:54:26 2003 @@ -49,7 +49,7 @@ // If there is only one call of the function, and it has internal linkage, // make it almost guaranteed to be inlined. // - if (Callee->hasOneUse() && Callee->hasInternalLinkage()) + if (Callee->hasInternalLinkage() && Callee->hasOneUse()) InlineCost -= 30000; // Add to the inline quality for properties that make the call valuable to From lattner at cs.uiuc.edu Mon Oct 20 09:14:03 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Oct 20 09:14:03 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/Sparc.burg.in Message-ID: <200310201413.JAA16864@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: Sparc.burg.in updated: 1.8 -> 1.9 --- Log message: Apparently the dependencies are wrong for this file, so it didn't rebuild it when changing Instruction.def. :( --- Diffs of the changes: (+1 -1) Index: llvm/lib/Target/Sparc/Sparc.burg.in diff -u llvm/lib/Target/Sparc/Sparc.burg.in:1.8 llvm/lib/Target/Sparc/Sparc.burg.in:1.9 --- llvm/lib/Target/Sparc/Sparc.burg.in:1.8 Sat Oct 18 00:55:58 2003 +++ llvm/lib/Target/Sparc/Sparc.burg.in Mon Oct 20 09:12:52 2003 @@ -67,7 +67,7 @@ %term GetElemPtr=GetElementPtrOPCODE %term GetElemPtrIdx=125 /* getElemPtr with index vector */ -%term Phi=PHINodeOPCODE +%term Phi=PHIOPCODE %term Cast=CastOPCODE /* cast that will be ignored. others are made explicit */ %term ToBoolTy=127 From gaeke at cs.uiuc.edu Mon Oct 20 10:15:03 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon Oct 20 10:15:03 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetMachine.h Message-ID: <200310201514.KAA18692@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetMachine.h updated: 1.36 -> 1.37 --- Log message: Make replaceMachineCodeForFunction return void. Make it assert by default. --- Diffs of the changes: (+6 -4) Index: llvm/include/llvm/Target/TargetMachine.h diff -u llvm/include/llvm/Target/TargetMachine.h:1.36 llvm/include/llvm/Target/TargetMachine.h:1.37 --- llvm/include/llvm/Target/TargetMachine.h:1.36 Fri Oct 17 13:26:45 2003 +++ llvm/include/llvm/Target/TargetMachine.h Mon Oct 20 10:14:33 2003 @@ -8,6 +8,7 @@ #define LLVM_TARGET_TARGETMACHINE_H #include "llvm/Target/TargetData.h" +#include class TargetInstrInfo; class TargetInstrDescriptor; @@ -100,11 +101,12 @@ } /// replaceMachineCodeForFunction - Make it so that calling the - /// function whose machine code is at OLD turns into a call to NEW. Returns - /// true iff an error occurred. FIXME: this is JIT-specific. + /// function whose machine code is at OLD turns into a call to NEW, + /// perhaps by overwriting OLD with a branch to NEW. FIXME: this is + /// JIT-specific. /// - virtual bool replaceMachineCodeForFunction (void *Old, void *New) { - return true; + virtual void replaceMachineCodeForFunction (void *Old, void *New) { + assert (0 && "Current target cannot replace machine code for functions"); } }; From gaeke at cs.uiuc.edu Mon Oct 20 10:16:04 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon Oct 20 10:16:04 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86TargetMachine.cpp Message-ID: <200310201515.KAA18716@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86TargetMachine.cpp updated: 1.33 -> 1.34 --- Log message: Make replaceMachineCodeForFunction return void. --- Diffs of the changes: (+1 -2) Index: llvm/lib/Target/X86/X86TargetMachine.cpp diff -u llvm/lib/Target/X86/X86TargetMachine.cpp:1.33 llvm/lib/Target/X86/X86TargetMachine.cpp:1.34 --- llvm/lib/Target/X86/X86TargetMachine.cpp:1.33 Sun Oct 19 23:11:23 2003 +++ llvm/lib/Target/X86/X86TargetMachine.cpp Mon Oct 20 10:15:17 2003 @@ -137,7 +137,7 @@ return false; // success! } -bool X86TargetMachine::replaceMachineCodeForFunction (void *Old, void *New) { +void X86TargetMachine::replaceMachineCodeForFunction (void *Old, void *New) { // FIXME: This code could perhaps live in a more appropriate place. char *OldByte = (char *) Old; *OldByte++ = 0xE9; // Emit JMP opcode. @@ -145,5 +145,4 @@ int32_t NewAddr = (int32_t) New; int32_t OldAddr = (int32_t) OldWord; *OldWord = NewAddr - OldAddr - 4; // Emit PC-relative addr of New code. - return false; // success! } From gaeke at cs.uiuc.edu Mon Oct 20 10:16:07 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon Oct 20 10:16:07 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp Message-ID: <200310201515.KAA18708@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcV9CodeEmitter.cpp updated: 1.36 -> 1.37 --- Log message: Make replaceMachineCodeForFunction return void. --- Diffs of the changes: (+1 -2) Index: llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp diff -u llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.36 llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.37 --- llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.36 Fri Oct 17 13:27:37 2003 +++ llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp Mon Oct 20 10:15:16 2003 @@ -562,12 +562,11 @@ } } -bool UltraSparc::replaceMachineCodeForFunction (void *Old, void *New) { +void UltraSparc::replaceMachineCodeForFunction (void *Old, void *New) { if (!TheJITResolver) return true; // fail if not in JIT. uint64_t Target = (uint64_t)(intptr_t)New; uint64_t CodeBegin = (uint64_t)(intptr_t)Old; TheJITResolver->insertJumpAtAddr(Target, CodeBegin); - return false; } int64_t SparcV9CodeEmitter::getMachineOpValue(MachineInstr &MI, From gaeke at cs.uiuc.edu Mon Oct 20 10:18:06 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon Oct 20 10:18:06 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInternals.h Message-ID: <200310201517.KAA22033@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcInternals.h updated: 1.102 -> 1.103 --- Log message: Make replaceMachineCodeForFunction() return void. --- Diffs of the changes: (+1 -1) Index: llvm/lib/Target/Sparc/SparcInternals.h diff -u llvm/lib/Target/Sparc/SparcInternals.h:1.102 llvm/lib/Target/Sparc/SparcInternals.h:1.103 --- llvm/lib/Target/Sparc/SparcInternals.h:1.102 Fri Oct 17 13:27:24 2003 +++ llvm/lib/Target/Sparc/SparcInternals.h Mon Oct 20 10:17:12 2003 @@ -677,7 +677,7 @@ virtual bool addPassesToJITCompile(FunctionPassManager &PM); virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM, MachineCodeEmitter &MCE); - virtual bool replaceMachineCodeForFunction(void *Old, void *New); + virtual void replaceMachineCodeForFunction(void *Old, void *New); // getPrologEpilogInsertionPass - Inserts prolog/epilog code. FunctionPass* getPrologEpilogInsertionPass(); From criswell at cs.uiuc.edu Mon Oct 20 11:41:02 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon Oct 20 11:41:02 2003 Subject: [llvm-commits] CVS: llvm/docs/GettingStarted.html Message-ID: <200310201640.LAA21810@choi.cs.uiuc.edu> Changes in directory llvm/docs: GettingStarted.html updated: 1.39 -> 1.40 --- Log message: Made the Requirements information its own major section and moved it between the "Getting Started Quickly" and "Getting Started Slowly" sections. :) Removed some of the nit-picky requirements information (i.e. GNU tar and GNU zip). Attempted to compact the requirements information so that it is less scary. --- Diffs of the changes: (+119 -140) Index: llvm/docs/GettingStarted.html diff -u llvm/docs/GettingStarted.html:1.39 llvm/docs/GettingStarted.html:1.40 --- llvm/docs/GettingStarted.html:1.39 Mon Oct 13 11:19:30 2003 +++ llvm/docs/GettingStarted.html Mon Oct 20 11:39:52 2003 @@ -19,14 +19,13 @@


Known problems with the C front-end


Known problems with the Sparc back-end

Programming Documentation: @@ -332,14 +345,32 @@ LLVM Coding standards - Details the LLVM coding standards and provides useful information on writing efficient C++ code. -
  • Open Projects in - the LLVM system. Look here if you are interested in - doing something with LLVM, but aren't sure what needs - to be done.
  • + +
  • Open Projects + - Look here if you are interested in doing something with + LLVM but aren't sure what needs to be done.
  • + +
  • Doxygen generated documentation + (classes) +
  • + - Other Useful Information: +

    + Support +

    +

    From lattner at cs.uiuc.edu Tue Oct 21 15:29:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 21 15:29:01 2003 Subject: [llvm-commits] CVS: llvm-www/www-index.html Message-ID: <200310212028.PAA26238@zion.cs.uiuc.edu> Changes in directory llvm-www: www-index.html updated: 1.62 -> 1.63 --- Log message: No really, don't list the LangRef twice Also, make the support section consistent --- Diffs of the changes: (+1 -14) Index: llvm-www/www-index.html diff -u llvm-www/www-index.html:1.62 llvm-www/www-index.html:1.63 --- llvm-www/www-index.html:1.62 Tue Oct 21 15:21:13 2003 +++ llvm-www/www-index.html Tue Oct 21 15:28:17 2003 @@ -307,16 +307,6 @@

  • LLVM Test Suite Guide - A reference manual for using the LLVM test suite. - -
  • - - LLVM Reference Manual - - - Defines the LLVM - intermediate representation, the assembly - form of the different nodes, and provides - reference information about the different - tools in LLVM.
  • Programming Documentation: @@ -356,10 +346,7 @@ -

    - Support -

    - + Support: @@ -280,13 +280,6 @@ each of these names with the appropriate pathname on your local system. All these paths are absolute:

    -
    CVSROOTDIR -
    - This is the path for the CVS repository containing the LLVM source - code. Ask the person responsible for your local LLVM installation to - give you this path. -

    -

    SRC_ROOT
    This is the top level directory of the LLVM source tree. @@ -364,7 +357,9 @@ follows:
    • cd where-you-want-llvm-to-live -
    • cvs -d CVSROOTDIR checkout llvm

      +
    • cvs -d :pserver:anon at llvm-cvs.cs.uiuc.edu:/var/cvs/llvm login +
    • Hit the return key when prompted for the password. +
    • cvs -d :pserver:anon at llvm-cvs.cs.uiuc.edu:/var/cvs/llvm co llvm

    This will create an 'llvm' directory in the current @@ -402,8 +397,8 @@

    Once checked out from the CVS repository, the LLVM suite source code must be configured via the configure script. This script sets variables in llvm/Makefile.config and - llvm/include/Config/config.h. It also populates OBJ_ROOT with - the Makefiles needed to build LLVM. + llvm/include/Config/config.h. It also populates OBJ_ROOT + with the Makefiles needed to build LLVM.

    The following environment variables are used by the configure From lattner at cs.uiuc.edu Tue Oct 21 16:34:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 21 16:34:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/C++Frontend/2003-10-21-InnerClass.cpp.tr Message-ID: <200310212133.QAA03273@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/C++Frontend: 2003-10-21-InnerClass.cpp.tr added (r1.1) --- Log message: New testcase, fixed in the C++ frontend --- Diffs of the changes: (+12 -0) Index: llvm/test/Regression/C++Frontend/2003-10-21-InnerClass.cpp.tr diff -c /dev/null llvm/test/Regression/C++Frontend/2003-10-21-InnerClass.cpp.tr:1.1 *** /dev/null Tue Oct 21 16:33:28 2003 --- llvm/test/Regression/C++Frontend/2003-10-21-InnerClass.cpp.tr Tue Oct 21 16:33:18 2003 *************** *** 0 **** --- 1,12 ---- + // RUN: %llvmgcc -xc++ -S -o - %s | grep '"struct.X::Y"' + struct X { + + struct Y { + Y(); + }; + + }; + + X::Y::Y() { + + } From lattner at cs.uiuc.edu Tue Oct 21 16:53:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 21 16:53:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/Linker.cpp Message-ID: <200310212152.QAA22839@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: Linker.cpp updated: 1.57 -> 1.58 --- Log message: Fix message to make more sense and confuse Chris less --- Diffs of the changes: (+7 -2) Index: llvm/lib/Transforms/Utils/Linker.cpp diff -u llvm/lib/Transforms/Utils/Linker.cpp:1.57 llvm/lib/Transforms/Utils/Linker.cpp:1.58 --- llvm/lib/Transforms/Utils/Linker.cpp:1.57 Mon Oct 20 14:43:20 2003 +++ llvm/lib/Transforms/Utils/Linker.cpp Tue Oct 21 16:52:20 2003 @@ -463,11 +463,16 @@ "' have different linkage specifiers!"); } else if (SGV->hasExternalLinkage()) { // Allow linking two exactly identical external global variables... - if (SGV->isConstant() != DGV->isConstant() || - SGV->getInitializer() != DGV->getInitializer()) + if (SGV->isConstant() != DGV->isConstant()) return Error(Err, "Global Variable Collision on '" + SGV->getType()->getDescription() + " %" + SGV->getName() + "' - Global variables differ in const'ness"); + + if (SGV->getInitializer() != DGV->getInitializer()) + return Error(Err, "Global Variable Collision on '" + + SGV->getType()->getDescription() + " %" + SGV->getName() + + "' - External linkage globals have different initializers"); + ValueMap.insert(std::make_pair(SGV, DGV)); } else if (SGV->hasLinkOnceLinkage()) { // If the global variable has a name, and that name is already in use in From gaeke at cs.uiuc.edu Tue Oct 21 16:59:01 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue Oct 21 16:59:01 2003 Subject: [llvm-commits] CVS: llvm/docs/CFEBuildInstrs.html Message-ID: <200310212158.QAA18564@gally.cs.uiuc.edu> Changes in directory llvm/docs: CFEBuildInstrs.html added (r1.1) --- Log message: Add C/C++ build instructions, first draft. --- Diffs of the changes: (+140 -0) Index: llvm/docs/CFEBuildInstrs.html diff -c /dev/null llvm/docs/CFEBuildInstrs.html:1.1 *** /dev/null Tue Oct 21 16:58:48 2003 --- llvm/docs/CFEBuildInstrs.html Tue Oct 21 16:58:38 2003 *************** *** 0 **** --- 1,140 ---- + + Bootstrapping the C/C++ Front-End + + +

    Bootstrapping the C/C++ Front-End

    + +

    + + + +
    + Instructions +
      + + +

      This document is intended to explain the process of building the LLVM + C/C++ front-end, based on GCC 3.4, from source.

      + +

      NOTE: This is currently a somewhat fragile, error-prone + process, and you should only try to do it if (A) you really, really, + really can't use the binaries we distribute, and (B) you are a wicked + good GCC hacker.

      + +

      We welcome patches to help make this process simpler.

      + +
        +
      1. Configure and build the LLVM libraries and tools using:

        +
        +  % cd llvm
        +  % ./configure [options...]
        +  % gmake tools-only
        + 
        +

        The use of the non-default target "tools-only" means that the + LLVM tools and libraries will build, and the binaries will be + deposited in llvm/tools/Debug, but the runtime (bytecode) + libraries will not build.

        + +
      2. Add the directory containing the tools to your PATH.

        +
        +  % set path = ( `cd llvm/tools/Debug && pwd` $path )
        + 
        + +
      3. Unpack the C/C++ front-end source into cfrontend/src.

        + +
      4. Edit src/configure. Change the first line (starting w/ #!) to + contain the correct full pathname of sh.

        + +
      5. Make "build" and "install" directories as siblings of the "src" + tree.

        +
        +  % pwd
        +  /usr/local/example/cfrontend/src
        +  % cd ..
        +  % mkdir build install
        +  % set CFEINSTALL = `pwd`/install
        + 
        + +
      6. Configure, build and install the C front-end:

        +
        +  % cd build
        +  % ../src/configure --prefix=$CFEINSTALL --disable-nls --disable-shared \
        +    --enable-languages=c,c++
        +  % gmake all-gcc
        +  % setenv LLVM_LIB_SEARCH_PATH `pwd`/gcc 
        +  % gmake all; gmake install
        + 
        + +

        Common Problem 1: You may get error messages regarding the fact + that LLVM does not support inline assembly. Here are two common + fixes:

        + +
          +
        • Fix 1: If you have system header files that include + inline assembly, you may have to modify them to remove the inline + assembly, and install the modified versions in + $CFEINSTALL/target-triplet/sys-include.

          + +
        • Fix 2: If you are building the C++ front-end on a CPU we + haven't tried yet, you will probably have to edit the appropriate + version of atomicity.h under + src/libstdc++-v3/config/cpu/name-of-cpu/atomicity.h + and apply a patch so that it does not use inline assembly.

          +
        + +

        Common Problem 2: FIXME: Chris should add a section about + common problems porting to a new architecture, including changes you + might have to make to the gcc/gcc/config/name-of-cpu + directory. For example (expand these):

        + +
          +
        • Munge linker flags so they are compatible with gccld. +
        • Change the target so it doesn't have long double; just use double + instead. +
        • No inline assembly for position independent code. +
        • We handle init and fini differently. +
        • Do not include inline assembly map things for SPARC, or profile things. +
        + +
      7. Go back into the LLVM source tree proper. Edit Makefile.config + to redefine LLVMGCCDIR to the full pathname of the + $CFEINSTALL directory, which is the directory you just + installed the C front-end into. (The ./configure script is likely to + have set this to a directory which does not exist on your system.)

        + +
      8. If you edited header files during the C/C++ front-end build as + described in "Fix 1" above, you must now copy those header files from + $CFEINSTALL/target-triplet/sys-include to + $CFEINSTALL/lib/gcc/target-triplet/3.4-llvm/include. + (This should be the "include" directory in the same directory as the + libgcc.a library, which you can find by running + $CFEINSTALL/bin/gcc --print-libgcc-file-name.)

        + +
      9. Build and install the runtime (bytecode) libraries by running:

        +
        +  % gmake -C runtime
        +  % mkdir $CFEINSTALL/bytecode-libs
        +  % gmake -C runtime install
        +  % setenv LLVM_LIB_SEARCH_PATH $CFEINSTALL/bytecode-libs
        + 
        + +
      10. Test the newly-installed C frontend by one or more of the + following means:

        +
          +
        • compiling and running a "hello, world" program in C or C++. +
        • running the tests under test/Programs using gmake -C + test/Programs; +
        + +

        +
      + + +
    + + +
    +
    Brian Gaeke
    + Last modified: $Date: 2003/10/21 21:58:38 $ +
    + From brukman at cs.uiuc.edu Tue Oct 21 17:17:00 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Tue Oct 21 17:17:00 2003 Subject: [llvm-commits] CVS: llvm-www/pubs/2002-08-08-CASES02-ControlC.html Message-ID: <200310212216.RAA03790@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: 2002-08-08-CASES02-ControlC.html updated: 1.5 -> 1.6 --- Log message: Fix author initials and alignment of `='. --- Diffs of the changes: (+7 -7) Index: llvm-www/pubs/2002-08-08-CASES02-ControlC.html diff -u llvm-www/pubs/2002-08-08-CASES02-ControlC.html:1.5 llvm-www/pubs/2002-08-08-CASES02-ControlC.html:1.6 --- llvm-www/pubs/2002-08-08-CASES02-ControlC.html:1.5 Wed May 21 12:09:18 2003 +++ llvm-www/pubs/2002-08-08-CASES02-ControlC.html Tue Oct 21 17:16:16 2003 @@ -56,14 +56,14 @@

    Bibtex Entry:

    -  @inproceedings{DKAL:LCTES03,
    -    Author = {Sumant Kowshik, Dinakar Dhurjati and Vikram Adve},
    -    Title = {{E}nsuring {C}ode {S}afety {W}ithout {R}untime {C}hecks for {R}eal-{T}ime {C}ontrol {S}ystems},
    +  @inproceedings{KDA:LCTES03,
    +    Author    = {Sumant Kowshik, Dinakar Dhurjati and Vikram Adve},
    +    Title     = {{E}nsuring {C}ode {S}afety {W}ithout {R}untime {C}hecks for {R}eal-{T}ime {C}ontrol {S}ystems},
         Booktitle = {Proc. Int'l Conf. on Compilers Architecture and Synthesis for Embedded Systems, 2002},
    -    Address = {Grenoble, France},
    -    Month = {Oct},
    -    Year = {2002},
    -    URL = {http://llvm.cs.uiuc.edu/pubs/2003-08-08-CASES02-ControlC.html}
    +    Address   = {Grenoble, France},
    +    Month     = {Oct},
    +    Year      = {2002},
    +    URL       = {http://llvm.cs.uiuc.edu/pubs/2003-08-08-CASES02-ControlC.html}
       }
     
    From brukman at cs.uiuc.edu Tue Oct 21 17:31:02 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Tue Oct 21 17:31:02 2003 Subject: [llvm-commits] CVS: llvm-www/llvm.css Message-ID: <200310212230.RAA09254@zion.cs.uiuc.edu> Changes in directory llvm-www: llvm.css added (r1.1) --- Log message: It's about time we use stylesheets, I hate duplicated formatting HTML code. --- Diffs of the changes: (+10 -0) Index: llvm-www/llvm.css diff -c /dev/null llvm-www/llvm.css:1.1 *** /dev/null Tue Oct 21 17:30:10 2003 --- llvm-www/llvm.css Tue Oct 21 17:30:00 2003 *************** *** 0 **** --- 1,10 ---- + /* + * LLVM website style sheet + */ + + .body { text: black; background: white } + + /* Publications */ + .pub_title { font-family: "Georgia,Palatino,Times,Roman"; font-size: 24pt; + text-align: center } + .pub_author { font-size: 14pt; text-align: center } From brukman at cs.uiuc.edu Tue Oct 21 17:32:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Tue Oct 21 17:32:01 2003 Subject: [llvm-commits] CVS: llvm-www/pubs/2002-08-08-CASES02-ControlC.html Message-ID: <200310212231.RAA13979@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: 2002-08-08-CASES02-ControlC.html updated: 1.6 -> 1.7 --- Log message: * Use a stylesheet => use
    instead of tags * Use UTF-8 instead of iso-8859-1, not only does it save a few bytes, it's international * Wrap lines (that we can) at 80 chars * Using
      for indentation is a hack at best --- Diffs of the changes: (+27 -19) Index: llvm-www/pubs/2002-08-08-CASES02-ControlC.html diff -u llvm-www/pubs/2002-08-08-CASES02-ControlC.html:1.6 llvm-www/pubs/2002-08-08-CASES02-ControlC.html:1.7 --- llvm-www/pubs/2002-08-08-CASES02-ControlC.html:1.6 Tue Oct 21 17:16:16 2003 +++ llvm-www/pubs/2002-08-08-CASES02-ControlC.html Tue Oct 21 17:31:42 2003 @@ -1,16 +1,20 @@ - - -Ensuring Code Safety Without Runtime Checks for Real-Time Control Systems + + + + + Ensuring Code Safety Without Runtime Checks for Real-Time Control Systems - + -


      Ensuring Code Safety Without Runtime Checks for Real-Time Control Systems
      - Sumant Kowshik, Dinakar Dhurjati and - Vikram Adve -

      +
      +Ensuring Code Safety Without Runtime Checks for Real-Time Control Systems +
      +
      +Sumant Kowshik, Dinakar Dhurjati and +Vikram Adve +

      Abstract:

      @@ -40,18 +44,21 @@

      Published:

      -
        - "Ensuring Code Safety Without Runtime Checks for Real-Time Control Systems", Sumant Kowshik, Dinakar Dhurjati & - Vikram Adve,
        - CASES 2002 - , Grenoble, France, Oct 2002.
        -
      +
      + "Ensuring Code Safety Without Runtime Checks for Real-Time Control Systems", + Sumant Kowshik, Dinakar Dhurjati & Vikram Adve,
      + CASES + 2002, Grenoble, France, Oct 2002.
      +

      Download:

      Bibtex Entry:

      @@ -67,4 +74,5 @@ } - + + From brukman at cs.uiuc.edu Tue Oct 21 17:44:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Tue Oct 21 17:44:01 2003 Subject: [llvm-commits] CVS: llvm-www/pubs/2002-06-AutomaticPoolAllocation.html 2002-08-09-LLVMCompilationStrategy.html 2002-12-LattnerMSThesis.html 2003-04-29-DataStructureAnalysisTR.html 2003-05-01-GCCSummit2003.html 2003-05-05-LCTES03-CodeSafety.html 2003-09-30-LifelongOptimizationTR.html 2003-10-01-LLVA.html Message-ID: <200310212243.RAA19590@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: 2002-06-AutomaticPoolAllocation.html updated: 1.3 -> 1.4 2002-08-09-LLVMCompilationStrategy.html updated: 1.4 -> 1.5 2002-12-LattnerMSThesis.html updated: 1.2 -> 1.3 2003-04-29-DataStructureAnalysisTR.html updated: 1.2 -> 1.3 2003-05-01-GCCSummit2003.html updated: 1.6 -> 1.7 2003-05-05-LCTES03-CodeSafety.html updated: 1.3 -> 1.4 2003-09-30-LifelongOptimizationTR.html updated: 1.1 -> 1.2 2003-10-01-LLVA.html updated: 1.2 -> 1.3 --- Log message: * Line up , , tags * Use a style sheet, this cleans up the <body> tag * Use UTF-8 instead of ISO-8859-1 charset --- Diffs of the changes: (+52 -35) Index: llvm-www/pubs/2002-06-AutomaticPoolAllocation.html diff -u llvm-www/pubs/2002-06-AutomaticPoolAllocation.html:1.3 llvm-www/pubs/2002-06-AutomaticPoolAllocation.html:1.4 --- llvm-www/pubs/2002-06-AutomaticPoolAllocation.html:1.3 Tue May 20 15:00:53 2003 +++ llvm-www/pubs/2002-06-AutomaticPoolAllocation.html Tue Oct 21 17:43:15 2003 @@ -1,10 +1,12 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<html><head> -<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> -<title>Automatic Pool Allocation for Disjoint Data Structures + + + + + Automatic Pool Allocation for Disjoint Data Structures - +


      Automatic Pool Allocation for Disjoint Data @@ -60,4 +62,5 @@ } - + + Index: llvm-www/pubs/2002-08-09-LLVMCompilationStrategy.html diff -u llvm-www/pubs/2002-08-09-LLVMCompilationStrategy.html:1.4 llvm-www/pubs/2002-08-09-LLVMCompilationStrategy.html:1.5 --- llvm-www/pubs/2002-08-09-LLVMCompilationStrategy.html:1.4 Thu Sep 11 15:44:40 2003 +++ llvm-www/pubs/2002-08-09-LLVMCompilationStrategy.html Tue Oct 21 17:43:15 2003 @@ -1,9 +1,11 @@ - - -The LLVM Instruction Set and Compilation Strategy + + + + + The LLVM Instruction Set and Compilation Strategy - +


      Index: llvm-www/pubs/2002-12-LattnerMSThesis.html diff -u llvm-www/pubs/2002-12-LattnerMSThesis.html:1.2 llvm-www/pubs/2002-12-LattnerMSThesis.html:1.3 --- llvm-www/pubs/2002-12-LattnerMSThesis.html:1.2 Fri May 9 13:25:21 2003 +++ llvm-www/pubs/2002-12-LattnerMSThesis.html Tue Oct 21 17:43:15 2003 @@ -1,9 +1,11 @@ - - -LLVM: An Infrastructure for Multi-Stage Optimization + + + + + LLVM: An Infrastructure for Multi-Stage Optimization - +


      Index: llvm-www/pubs/2003-04-29-DataStructureAnalysisTR.html diff -u llvm-www/pubs/2003-04-29-DataStructureAnalysisTR.html:1.2 llvm-www/pubs/2003-04-29-DataStructureAnalysisTR.html:1.3 --- llvm-www/pubs/2003-04-29-DataStructureAnalysisTR.html:1.2 Mon Sep 15 17:20:56 2003 +++ llvm-www/pubs/2003-04-29-DataStructureAnalysisTR.html Tue Oct 21 17:43:15 2003 @@ -1,9 +1,12 @@ - - -Data Structure Analysis: An Efficient Context-Sensitive Heap Analysis + + + + + Data Structure Analysis: An Efficient Context-Sensitive Heap + Analysis - +


      Index: llvm-www/pubs/2003-05-01-GCCSummit2003.html diff -u llvm-www/pubs/2003-05-01-GCCSummit2003.html:1.6 llvm-www/pubs/2003-05-01-GCCSummit2003.html:1.7 --- llvm-www/pubs/2003-05-01-GCCSummit2003.html:1.6 Mon May 26 13:39:42 2003 +++ llvm-www/pubs/2003-05-01-GCCSummit2003.html Tue Oct 21 17:43:15 2003 @@ -1,10 +1,11 @@ - - -Architecture for a Next-Generation GCC + + + + + Architecture for a Next-Generation GCC - - +


      Architecture for a Next-Generation Index: llvm-www/pubs/2003-05-05-LCTES03-CodeSafety.html diff -u llvm-www/pubs/2003-05-05-LCTES03-CodeSafety.html:1.3 llvm-www/pubs/2003-05-05-LCTES03-CodeSafety.html:1.4 --- llvm-www/pubs/2003-05-05-LCTES03-CodeSafety.html:1.3 Mon Jun 23 07:13:36 2003 +++ llvm-www/pubs/2003-05-05-LCTES03-CodeSafety.html Tue Oct 21 17:43:15 2003 @@ -1,10 +1,11 @@ - - -Memory Safety Without Runtime Checks or Garbage Collection + + + + + Memory Safety Without Runtime Checks or Garbage Collection - - +


      Memory Safety Without Runtime Checks or Garbage Collection
      Index: llvm-www/pubs/2003-09-30-LifelongOptimizationTR.html diff -u llvm-www/pubs/2003-09-30-LifelongOptimizationTR.html:1.1 llvm-www/pubs/2003-09-30-LifelongOptimizationTR.html:1.2 --- llvm-www/pubs/2003-09-30-LifelongOptimizationTR.html:1.1 Wed Oct 1 15:46:36 2003 +++ llvm-www/pubs/2003-09-30-LifelongOptimizationTR.html Tue Oct 21 17:43:15 2003 @@ -1,9 +1,12 @@ - - -LLVM: A Compilation Framework for Lifelong Program Analysis & Transformation + + + + + LLVM: A Compilation Framework for Lifelong Program Analysis & + Transformation - +


      Index: llvm-www/pubs/2003-10-01-LLVA.html diff -u llvm-www/pubs/2003-10-01-LLVA.html:1.2 llvm-www/pubs/2003-10-01-LLVA.html:1.3 --- llvm-www/pubs/2003-10-01-LLVA.html:1.2 Wed Oct 1 15:57:28 2003 +++ llvm-www/pubs/2003-10-01-LLVA.html Tue Oct 21 17:43:15 2003 @@ -1,9 +1,11 @@ - - -LLVA: A Low-level Virtual Instruction Set Architecture + + + + + LLVA: A Low-level Virtual Instruction Set Architecture - +


      From lattner at cs.uiuc.edu Tue Oct 21 17:47:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 21 17:47:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/Linker.cpp Message-ID: <200310212246.RAA20248@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: Linker.cpp updated: 1.58 -> 1.59 --- Log message: Fix bug: Linker/2003-10-21-ConflictingTypesTolerance.ll --- Diffs of the changes: (+10 -13) Index: llvm/lib/Transforms/Utils/Linker.cpp diff -u llvm/lib/Transforms/Utils/Linker.cpp:1.58 llvm/lib/Transforms/Utils/Linker.cpp:1.59 --- llvm/lib/Transforms/Utils/Linker.cpp:1.58 Tue Oct 21 16:52:20 2003 +++ llvm/lib/Transforms/Utils/Linker.cpp Tue Oct 21 17:46:38 2003 @@ -215,20 +215,17 @@ } // If we STILL cannot resolve the types, then there is something wrong. - // Report the error. + // Report the warning and delete one of the names. if (DelayedTypesToResolve.size() == OldSize) { - // Build up an error message of all of the mismatched types. - std::string ErrorMessage; - for (unsigned i = 0, e = DelayedTypesToResolve.size(); i != e; ++i) { - const std::string &Name = DelayedTypesToResolve[i]; - const Type *T1 = cast(VM.find(Name)->second); - const Type *T2 = cast(DestST->lookup(Type::TypeTy, Name)); - ErrorMessage += " Type named '" + Name + - "' conflicts.\n Src='" + T1->getDescription() + - "'.\n Dest='" + T2->getDescription() + "'\n"; - } - return Error(Err, "Type conflict between types in modules:\n" + - ErrorMessage); + const std::string &Name = DelayedTypesToResolve.back(); + + const Type *T1 = cast(VM.find(Name)->second); + const Type *T2 = cast(DestST->lookup(Type::TypeTy, Name)); + std::cerr << "WARNING: Type conflict between types named '" << Name + << "'.\n Src='" << *T1 << "'.\n Dest='" << *T2 << "'\n"; + + // Remove the symbol name from the destination. + DelayedTypesToResolve.pop_back(); } } } From lattner at cs.uiuc.edu Tue Oct 21 17:47:10 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 21 17:47:10 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Linker/2003-10-21-ConflictingTypesTolerance.ll Message-ID: <200310212246.RAA20053@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Linker: 2003-10-21-ConflictingTypesTolerance.ll added (r1.1) --- Log message: New testcase. The linker should not consider it an error if two types disagree. It should grumble, then go ahead and do it. --- Diffs of the changes: (+7 -0) Index: llvm/test/Regression/Linker/2003-10-21-ConflictingTypesTolerance.ll diff -c /dev/null llvm/test/Regression/Linker/2003-10-21-ConflictingTypesTolerance.ll:1.1 *** /dev/null Tue Oct 21 17:46:32 2003 --- llvm/test/Regression/Linker/2003-10-21-ConflictingTypesTolerance.ll Tue Oct 21 17:46:22 2003 *************** *** 0 **** --- 1,7 ---- + ; RUN: llvm-as < %s > %t.out1.bc + ; RUN: echo "%S = type [8 x int] external global %S " | llvm-as > %t.out2.bc + ; RUN: llvm-link %t.out[12].bc | llvm-dis | grep %S | grep '{' + + %S = type { int } + + From criswell at cs.uiuc.edu Tue Oct 21 17:57:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Tue Oct 21 17:57:01 2003 Subject: [llvm-commits] CVS: llvm/test/QMTest/expectations.qmr llvm.py Message-ID: <200310212256.RAA12487@choi.cs.uiuc.edu> Changes in directory llvm/test/QMTest: expectations.qmr updated: 1.1 -> 1.2 llvm.py updated: 1.20 -> 1.21 --- Log message: Updated the expectations to better match the results on Solaris. Modified the LLI Tests so that they use distinct output filenames. --- Diffs of the changes: (+2 -2) Index: llvm/test/QMTest/expectations.qmr diff -u llvm/test/QMTest/expectations.qmr:1.1 llvm/test/QMTest/expectations.qmr:1.2 --- llvm/test/QMTest/expectations.qmr:1.1 Tue Oct 7 16:30:22 2003 +++ llvm/test/QMTest/expectations.qmr Tue Oct 21 17:56:07 2003 @@ -3,13 +3,13 @@ qoq}q(U _Result__kindqUtestqU_Result__outcomeqUPASSqU_Result__annotationsq}U _Result__idq U0Regression.Assembler.2002-08-16-ConstExprInlinedq U_Result__contextq (cqm.test.context Context -q o}q (U_Context__propertiesq}U_Context__temporariesq}ubub.(hoq}q(hhhhh}h U%Regression.Transforms.InstCombine.addqh (h o}q(h}h}ubub.(hoq}q(hhhhh}h U/Regression.CBackend.2002-08-19-HardConstantExprqh (h o}q(h}h}ubub.(hoq}q(hhhhh}h URegression.Jello.test-shiftqh (h o}q(h}h}ubub.(hoq}q(hhhUFAILqh}h U.Regression.Transforms.CorrelatedExprs.looptestqh (h o}q (h}h}ubub.(hoq!}q"(hhhhh}h U-Regression.Linker.2003-08-23-GlobalVarLinkingq#h (h o}q$(h}h}ubub.(hoq%}q&(hhhhh}h U?Regression.Transforms.Inline.2003-09-22-PHINodesInExceptionDestq'h (h o}q((h}h}ubub.(hoq)}q*(hhhhh}h U,Regression.CFrontend.2003-02-12-NonlocalGotoq+h (h o}q,(h}h}ubub.(hoq-}q.(hhhhh}h U2Regression.Transforms.FunctionResolve.retmismatch1q/h (h o}q0(h}h}ubub.(hoq1}q2(hhhhh}h U>Regression.Transforms.LevelRaise.2002-05-02-BadCastEliminationq3h (h o}q4(h}h}ubub.(hoq5}q6(hhhhh}h U8Regression.Transforms.ADCE.2003-01-22-Pre! decessorProblemq7h (h o}q8(h}h}ubub.(hoq9}q:(hhhhh}h U=Regression.Transforms.LevelRaise.2002-10-08-VarArgCallInfLoopq;h (h o}q<(h}h}ubub.(hoq=}q>(hhhhh}h U5Regression.CFrontend.2003-07-22-ArrayAccessTypeSafetyq?h (h o}q@(h}h}ubub.(hoqA}qB(hhhhh}h U8Regression.C++Frontend.2003-09-29-ArgumentNumberMismatchqCh (h o}qD(h}h}ubub.(hoqE}qF(hhhhh}h U+Regression.CFrontend.2002-09-19-StarInLabelqGh (h o}qH(h}h}ubub.(hoqI}qJ(hhhhh}h U.Regression.CFrontend.2003-08-23-LocalUnionTestqKh (h o}qL(h}h}ubub.(hoqM}qN(hhhhh}h U/Regression.Linker.2003-04-26-NullPtrLinkProblemqOh (h o}qP(h}h}ubub.(hoqQ}qR(hhhhh}h U)Regression.Transforms.Reassociate.subtestqSh (h o}qT(h}h}ubub.(hoqU}qV(hhhhh}h U)Regression.Linker.2002-08-20-ConstantExprqWh (h o}qX(h}h}ubub.(hoqY}qZ(hhhhh}h U=Regression.Transforms.Reassociate.2002-05-15-AgressiveSubMoveq[h (h o}q\(h}h}ubub.(hoq]}q^(hhhhh}h UARegression.Transforms.CorrelatedExprs.2002-1! 0-07-DominatorProblemq_h (h o}q`(h}h}ubub.(hoqa}qb(hhhhh}h U3R egression.Transforms.PiNodeInserter.substitutetestqch (h o}qd(h}h}ubub.(hoqe}qf(hhhhh}h U%Regression.Transforms.InstCombine.andqgh (h o}qh(h}h}ubub.(hoqi}qj(hhhhh}h U-Regression.CFrontend.2002-02-18-64bitConstantqkh (h o}ql(h}h}ubub.(hoqm}qn(hhhhh}h U1Regression.Assembler.2002-04-04-PureVirtMethCall2qoh (h o}qp(h}h}ubub.(hoqq}qr(hhhhh}h U(Regression.Reoptimizer.BinInterface.testqsh (h o}qt(h}h}ubub.(hoqu}qv(hhhhh}h URegression.Transforms.CorrelatedExprs.2002-10-08-DominatorTestq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h URegression.Linker.testlink2q?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h URegression.Linker.testlink1q?h (h o}q?(h}h}ubub.(hoq! ?}q?(hhhhh}h U4Regression.C++Frontend.2003-09-30-NestedFunctionDeclq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U=Regression.Transforms.CorrelatedExprs.2002-09-23-PHIUpdateBugq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U7Regression.Transforms.LowerSwitch.2003-05-01-PHIProblemq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U2Regression.Transforms.ADCE.2003-09-15-InfLoopCrashq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U4Regression.Transforms.SimplifyCFG.2002-06-24-PHINodeq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U*Regression.Transforms.DSAnalysis.recursionq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U)Regression.Jello.2003-01-15-AlignmentTestq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U*Regression.CFrontend.2002-04-07-SwitchStmtq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U!Regression.Jello.2003-01-10-FUCOMq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U(Regression.CFrontend.2003-08-21-StmtExprq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h URegression.LLC.badCa! llArgLRLLVMq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U6Regression. Transforms.LevelRaise.2002-02-11-ArrayShapeq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U1Regression.Assembler.2003-03-03-DuplicateConstantq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U.Regression.Transforms.ModuloSched.arith-simpleq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U/Regression.CBackend.2002-09-20-VarArgPrototypesq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U)Regression.Other.2002-08-02-DomSetProblemq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U6Regression.Assembler.2002-07-25-ParserAssertionFailureq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U6Regression.Transforms.LevelRaise.2002-03-20-BadCodegenq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U%Regression.Transforms.ADCE.basictest1q?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U$Regression.Transforms.InstCombine.orq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhUPASSq?h}h U'Regression.Transforms.TailDup.basictestq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U'Regression.Analysis.DSGraph.constantizeq?h (h o}q?(h}h}! ubub.(hoq?}q?(hhhhh}h U6Regression.Transforms.GlobalDCE.2002-08-17-FunctionDGEq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U:Regression.Transforms.LICM.2003-02-26-LoopExitNotDominatedq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U(Regression.Linker.2003-05-15-TypeProblemq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U#Regression.Transforms.SCCP.sccptestq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U2Regression.Transforms.FunctionResolve.retmismatch3q?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U=Regression.Transforms.CorrelatedExprs.2002-10-03-PHIPropogateq?h (h o}q?(h}h}ubub.(hoq?}q?(hhhhh}h U(Regression.Transforms.PruneEH.simpletestr--------- \ No newline at end of file +q o}q (U_Context__propertiesq}U_Context__temporariesq}ubub.(hoq}q(hhhhh}h U(Regression.Transforms.PruneEH.simpletestqh (h o}q(h}h}ubub.(hoq}q(hhhhh}h U/Regression.CBackend.2002-08-19-HardConstantExprqh (h o}q(h}h}ubub.(hoq}q(hhhhh}h URegression.Jello.test-shiftqh (h o}q(h}h}ubub.(hoq}q(hhhUFAILqh}h U.Regression.Transforms.CorrelatedExprs.looptestqh (h o}q (h}h}ubub.(hoq!}q"(hhhhh}h U-Regression.Linker.2003-08-23-GlobalVarLinkingq#h (h o}q$(h}h}ubub.(hoq%}q&(hhhhh}h U?Regression.Transforms.Inline.2003-09-22-PHINodesInExceptionDestq'h (h o}q((h}h}ubub.(hoq)}q*(hhhhh}h U,Regression.CFrontend.2003-02-12-NonlocalGotoq+h (h o}q,(h}h}ubub.(hoq-}q.(hhhhh}h U2Regression.Transforms.FunctionResolve.retmismatch1q/h (h o}q0(h}h}ubub.(hoq1}q2(hhhhh}h U8Regression.Transforms.ADCE.2003-01-22-PredecessorProblemq3h (h o}q4(h}h}ubub.(hoq5}q6(hhhhh}h U=Regression.Transforms.LevelRaise.2002-10-08-! VarArgCallInfLoopq7h (h o}q8(h}h}ubub.(hoq9}q:(hhhhh}h U5Regression.CFrontend.2003-07-22-ArrayAccessTypeSafetyq;h (h o}q<(h}h}ubub.(hoq=}q>(hhhhh}h U8Regression.C++Frontend.2003-09-29-ArgumentNumberMismatchq?h (h o}q@(h}h}ubub.(hoqA}qB(hhhhh}h U+Regression.CFrontend.2002-09-19-StarInLabelqCh (h o}qD(h}h}ubub.(hoqE}qF(hhhhh}h U.Regression.CFrontend.2003-08-23-LocalUnionTestqGh (h o}qH(h}h}ubub.(hoqI}qJ(hhhhh}h U"Regression.Jello.2003-06-05-PHIBugqKh (h o}qL(h}h}ubub.(hoqM}qN(hhhhh}h U/Regression.Linker.2003-04-26-NullPtrLinkProblemqOh (h o}qP(h}h}ubub.(hoqQ}qR(hhhhh}h U)Regression.Transforms.Reassociate.subtestqSh (h o}qT(h}h}ubub.(hoqU}qV(hhhhh}h U)Regression.Linker.2002-08-20-ConstantExprqWh (h o}qX(h}h}ubub.(hoqY}qZ(hhhhh}h U=Regression.Transforms.Reassociate.2002-05-15-AgressiveSubMoveq[h (h o}q\(h}h}ubub.(hoq]}q^(hhhhh}h UARegression.Transforms.CorrelatedExprs.2002-10-07-DominatorProblemq_h ! (h o}q`(h}h}ubub.(hoqa}qb(hhhhh}h U3Regression.Transforms.PiNo deInserter.substitutetestqch (h o}qd(h}h}ubub.(hoqe}qf(hhhhh}h U4Regression.Transforms.SCCP.2003-08-26-InvokeHandlingqgh (h o}qh(h}h}ubub.(hoqi}qj(hhhhh}h U$Regression.Jello.2003-01-04-LoopTestqkh (h o}ql(h}h}ubub.(hoqm}qn(hhhhh}h U1Regression.Assembler.2002-04-04-PureVirtMethCall2qoh (h o}qp(h}h}ubub.(hoqq}qr(hhhhh}h U)Regression.CFrontend.2002-07-14-MiscTestsqsh (h o}qt(h}h}ubub.(hoqu}qv(hhhhh}h U Changes in directory llvm/test/Regression/Transforms/FunctionResolve: 2003-10-21-GlobalTypeDifference.ll added (r1.1) --- Log message: New testcase: globals should be linked if they are the wrong type. We should just moan loudly. --- Diffs of the changes: (+10 -0) Index: llvm/test/Regression/Transforms/FunctionResolve/2003-10-21-GlobalTypeDifference.ll diff -c /dev/null llvm/test/Regression/Transforms/FunctionResolve/2003-10-21-GlobalTypeDifference.ll:1.1 *** /dev/null Tue Oct 21 18:17:56 2003 --- llvm/test/Regression/Transforms/FunctionResolve/2003-10-21-GlobalTypeDifference.ll Tue Oct 21 18:17:45 2003 *************** *** 0 **** --- 1,10 ---- + ; RUN: llvm-as < %s | opt -funcresolve -disable-output 2>&1 | grep WARNING + + %X = external global int + %Z = global int* %X + + %X = global float 1.0 + %Y = global float* %X + + implementation + From lattner at cs.uiuc.edu Tue Oct 21 18:19:03 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 21 18:19:03 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/FunctionResolution.cpp Message-ID: <200310212318.SAA26064@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: FunctionResolution.cpp updated: 1.37 -> 1.38 --- Log message: Fix bug: FunctionResolve/2003-10-21-GlobalTypeDifference.ll --- Diffs of the changes: (+19 -55) Index: llvm/lib/Transforms/IPO/FunctionResolution.cpp diff -u llvm/lib/Transforms/IPO/FunctionResolution.cpp:1.37 llvm/lib/Transforms/IPO/FunctionResolution.cpp:1.38 --- llvm/lib/Transforms/IPO/FunctionResolution.cpp:1.37 Mon Oct 20 14:43:18 2003 +++ llvm/lib/Transforms/IPO/FunctionResolution.cpp Tue Oct 21 18:17:56 2003 @@ -109,29 +109,15 @@ std::vector &Globals, GlobalVariable *Concrete) { bool Changed = false; - assert(isa(Concrete->getType()->getElementType()) && - "Concrete version should be an array type!"); - - // Get the type of the things that may be resolved to us... - const ArrayType *CATy =cast(Concrete->getType()->getElementType()); - const Type *AETy = CATy->getElementType(); - Constant *CCPR = ConstantPointerRef::get(Concrete); for (unsigned i = 0; i != Globals.size(); ++i) if (Globals[i] != Concrete) { - GlobalVariable *Old = cast(Globals[i]); - const ArrayType *OATy = cast(Old->getType()->getElementType()); - if (OATy->getElementType() != AETy || OATy->getNumElements() != 0) { - std::cerr << "WARNING: Two global variables exist with the same name " - << "that cannot be resolved!\n"; - return false; - } - - Old->replaceAllUsesWith(ConstantExpr::getCast(CCPR, Old->getType())); + Constant *Cast = ConstantExpr::getCast(CCPR, Globals[i]->getType()); + Globals[i]->replaceAllUsesWith(Cast); // Since there are no uses of Old anymore, remove it from the module. - M.getGlobalList().erase(Old); + M.getGlobalList().erase(cast(Globals[i])); ++NumGlobals; Changed = true; @@ -176,32 +162,15 @@ Concrete = F; } } else { - // For global variables, we have to merge C definitions int A[][4] with - // int[6][4]. A[][4] is represented as A[0][4] by the CFE. GlobalVariable *GV = cast(Globals[i]); - if (!isa(GV->getType()->getElementType())) { - Concrete = 0; - break; // Non array's cannot be compatible with other types. - } else if (Concrete == 0) { - Concrete = GV; - } else { - // Must have different types... allow merging A[0][4] w/ A[6][4] if - // A[0][4] is external. - const ArrayType *NAT = cast(GV->getType()->getElementType()); - const ArrayType *CAT = - cast(Concrete->getType()->getElementType()); - - if (NAT->getElementType() != CAT->getElementType()) { - Concrete = 0; // Non-compatible types - break; - } else if (NAT->getNumElements() == 0 && GV->isExternal()) { - // Concrete remains the same - } else if (CAT->getNumElements() == 0 && Concrete->isExternal()) { - Concrete = GV; // Concrete becomes GV - } else { - Concrete = 0; // Cannot merge these types... - break; + if (!GV->isExternal()) { + if (Concrete) { + std::cerr << "WARNING: Two global variables with external linkage" + << " exist with the same name: '" << GV->getName() + << "'!\n"; + return false; } + Concrete = GV; } } ++i; @@ -225,21 +194,15 @@ return false; // Nothing to do? Must have multiple internal definitions. - // We should find exactly one concrete function definition, which is - // probably the implementation. Change all of the function definitions and - // uses to use it instead. - // - if (!Concrete) { - std::cerr << "WARNING: Found global types that are not compatible:\n"; - for (unsigned i = 0; i < Globals.size(); ++i) { - std::cerr << "\t" << Globals[i]->getType()->getDescription() << " %" - << Globals[i]->getName() << "\n"; - } - std::cerr << " No linkage of globals named '" << Globals[0]->getName() - << "' performed!\n"; - return false; + std::cerr << "WARNING: Found global types that are not compatible:\n"; + for (unsigned i = 0; i < Globals.size(); ++i) { + std::cerr << "\t" << *Globals[i]->getType() << " %" + << Globals[i]->getName() << "\n"; } + if (!Concrete) + Concrete = Globals[0]; + if (isFunction) return ResolveFunctions(M, Globals, cast(Concrete)); else @@ -266,7 +229,8 @@ GlobalValue *GV = cast(PI->second); assert(PI->first == GV->getName() && "Global name and symbol table do not agree!"); - Globals[PI->first].push_back(GV); + if (!GV->hasInternalLinkage()) + Globals[PI->first].push_back(GV); } } From brukman at cs.uiuc.edu Tue Oct 21 19:27:02 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Tue Oct 21 19:27:02 2003 Subject: [llvm-commits] CVS: llvm-www/pubs/2002-06-AutomaticPoolAllocation.html 2002-08-08-CASES02-ControlC.html 2002-08-09-LLVMCompilationStrategy.html 2002-12-LattnerMSThesis.html 2003-04-29-DataStructureAnalysisTR.html 2003-05-01-GCCSummit2003.html 2003-05-05-LCTES03-CodeSafety.html 2003-09-30-LifelongOptimizationTR.html 2003-10-01-LLVA.html Message-ID: <200310220026.TAA00523@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: 2002-06-AutomaticPoolAllocation.html updated: 1.4 -> 1.5 2002-08-08-CASES02-ControlC.html updated: 1.7 -> 1.8 2002-08-09-LLVMCompilationStrategy.html updated: 1.5 -> 1.6 2002-12-LattnerMSThesis.html updated: 1.3 -> 1.4 2003-04-29-DataStructureAnalysisTR.html updated: 1.3 -> 1.4 2003-05-01-GCCSummit2003.html updated: 1.7 -> 1.8 2003-05-05-LCTES03-CodeSafety.html updated: 1.4 -> 1.5 2003-09-30-LifelongOptimizationTR.html updated: 1.2 -> 1.3 2003-10-01-LLVA.html updated: 1.3 -> 1.4 --- Log message: * Use

      s instead of explicit tags * Favor
      over
        for indent * Indent
      • within
          * Delete unnecessary space and {} within BibTeX entry --- Diffs of the changes: (+253 -243) Index: llvm-www/pubs/2002-06-AutomaticPoolAllocation.html diff -u llvm-www/pubs/2002-06-AutomaticPoolAllocation.html:1.4 llvm-www/pubs/2002-06-AutomaticPoolAllocation.html:1.5 --- llvm-www/pubs/2002-06-AutomaticPoolAllocation.html:1.4 Tue Oct 21 17:43:15 2003 +++ llvm-www/pubs/2002-06-AutomaticPoolAllocation.html Tue Oct 21 19:26:00 2003 @@ -8,14 +8,13 @@ -


          Automatic Pool Allocation for Disjoint Data -Structures
          - Chris Lattner and - Vikram Adve - -

          - +
          +Automatic Pool Allocation for Disjoint Data Structures +
          +

          Abstract:

          @@ -36,29 +35,33 @@

          Published:

          - + Chris Lattner & Vikram Adve,
          + ACM SIGPLAN Workshop on Memory + System Performance (MSP), Berlin, Germany, June 2002.
          +

      Download:

      -

      Bibtex Entry:

      +

      BibTeX Entry:

       @InProceedings{LattnerAdve:MSP02,
      -    Author      = {Chris Lattner and Vikram Adve},
      -    Title       = {{A}utomatic {P}ool {A}llocation for {D}isjoint {D}ata {S}tructures},
      -    Booktitle   = {Proc. ACM SIGPLAN Workshop on Memory System Performance},
      -    Address     = {Berlin, Germany},
      -    Month       = {Jun},
      -    Year        = {2002}
      +  Author    = "{Chris Lattner and Vikram Adve}",
      +  Title     = "{Automatic Pool Allocation for Disjoint Data Structures}",
      +  Booktitle = "{Proc. ACM SIGPLAN Workshop on Memory System Performance}",
      +  Address   = "{Berlin, Germany}",
      +  Month     = {Jun},
      +  Year      = {2002}
       }
       
      Index: llvm-www/pubs/2002-08-08-CASES02-ControlC.html diff -u llvm-www/pubs/2002-08-08-CASES02-ControlC.html:1.7 llvm-www/pubs/2002-08-08-CASES02-ControlC.html:1.8 --- llvm-www/pubs/2002-08-08-CASES02-ControlC.html:1.7 Tue Oct 21 17:31:42 2003 +++ llvm-www/pubs/2002-08-08-CASES02-ControlC.html Tue Oct 21 19:26:00 2003 @@ -3,9 +3,9 @@ - Ensuring Code Safety Without Runtime Checks for Real-Time Control Systems + Ensuring Code Safety Without Runtime Checks for Real-Time Control + Systems -
      @@ -61,12 +61,12 @@ Runtime Checks for Real-Time Control Systems - Presentation (PPT)
    -

    Bibtex Entry:

    +

    BibTeX Entry:

       @inproceedings{KDA:LCTES03,
         Author    = {Sumant Kowshik, Dinakar Dhurjati and Vikram Adve},
    -    Title     = {{E}nsuring {C}ode {S}afety {W}ithout {R}untime {C}hecks for {R}eal-{T}ime {C}ontrol {S}ystems},
    -    Booktitle = {Proc. Int'l Conf. on Compilers Architecture and Synthesis for Embedded Systems, 2002},
    +    Title     = "{Ensuring Code Safety Without Runtime Checks for Real-Time Control Systems}",
    +    Booktitle = "{Proc. Int'l Conf. on Compilers Architecture and Synthesis for Embedded Systems, 2002}",
         Address   = {Grenoble, France},
         Month     = {Oct},
         Year      = {2002},
    
    
    Index: llvm-www/pubs/2002-08-09-LLVMCompilationStrategy.html
    diff -u llvm-www/pubs/2002-08-09-LLVMCompilationStrategy.html:1.5 llvm-www/pubs/2002-08-09-LLVMCompilationStrategy.html:1.6
    --- llvm-www/pubs/2002-08-09-LLVMCompilationStrategy.html:1.5	Tue Oct 21 17:43:15 2003
    +++ llvm-www/pubs/2002-08-09-LLVMCompilationStrategy.html	Tue Oct 21 19:26:00 2003
    @@ -7,17 +7,13 @@
     
     
     
    -


    - - +

    The LLVM Instruction Set and Compilation Strategy -
    - - - Chris Lattner and - Vikram Adve -

    - +
    +

    Abstract:

    @@ -31,50 +27,55 @@

    Published:

    -
      +
      "The LLVM Instruction Set and Compilation Strategy", - Chris Lattner & Vikram Adve
      - Technical Report #UIUCDCS-R-2002-2292, Computer Science Dept., Univ. of Illinois, Aug. 2002. -
    + Chris Lattner & Vikram Adve
    + Technical Report #UIUCDCS-R-2002-2292, Computer Science Dept., Univ. of + Illinois, Aug. 2002. +

    Update:

    -
      - Since this document was published, one significant change has been made - to LLVM: the GCC C front-end described in the document has been completely - rewritten from scratch. The new C front-end is based on the mainline GCC CVS - tree (what will become GCC 3.4), and expands type-safe LLVM code from the GCC - AST representation, instead of from the untyped GCC RTL representation.

      - - This change dramatically improved the quality of code generated and the - stability of the system as a whole.

      -

    - - +
    +

    + Since this document was published, one significant change has been + made to LLVM: the GCC C front-end described in the document has been + completely rewritten from scratch. The new C front-end is based on the + mainline GCC CVS tree (what will become GCC 3.4), and expands type-safe LLVM + code from the GCC AST representation, instead of from the untyped GCC RTL + representation. +

    +

    + This change dramatically improved the quality of code generated and the + stability of the system as a whole. +

    +

    Download:

    -

    Bibtex Entry:

    +

    BibTeX Entry:

    NOTE: This document has been superseded by LLVM: An Infrastructure for Multi-Stage -Optimization. If you want to cite a paper about LLVM, please cite it -instead.

    +Optimization. If you want to cite a paper about LLVM, please cite it +instead.

    -  @TechReport{LattnerAdve:LLVM:ISCS,
    -    Author      = {Chris Lattner and Vikram Adve},
    -    Title       = {The {LLVM} Instruction Set and Compilation Strategy},
    -    Institution = {Computer Science Dept.,
    -                   Univ. of Illinois at Urbana-Champaign},
    -    Number      = {UIUCDCS-R-2002-2292},
    -    Type        = {Tech. Report},
    -    Month       = {Aug},
    -    Year        = {2002}
    -  }
    + at TechReport{LattnerAdve:LLVM:ISCS,
    +  Author      = "{Chris Lattner and Vikram Adve}",
    +  Title       = "{The LLVM Instruction Set and Compilation Strategy}",
    +  Institution = "{CS Dept., Univ. of Illinois at Urbana-Champaign}",
    +  Number      = {UIUCDCS-R-2002-2292},
    +  Type        = {Tech. Report},
    +  Month       = {Aug},
    +  Year        = {2002}
    +}
     
    - + + Index: llvm-www/pubs/2002-12-LattnerMSThesis.html diff -u llvm-www/pubs/2002-12-LattnerMSThesis.html:1.3 llvm-www/pubs/2002-12-LattnerMSThesis.html:1.4 --- llvm-www/pubs/2002-12-LattnerMSThesis.html:1.3 Tue Oct 21 17:43:15 2003 +++ llvm-www/pubs/2002-12-LattnerMSThesis.html Tue Oct 21 19:26:00 2003 @@ -7,32 +7,33 @@ -


    - - +

    LLVM: An Infrastructure for Multi-Stage Optimization -
    - - Chris Lattner, M.S. Thesis -

    +
    +
    + Chris Lattner, M.S. Thesis +

    Abstract:

    +

    Modern programming languages and software engineering principles are causing increasing problems for compiler systems. Traditional approaches, which use a simple compile-link-execute model, are unable to provide adequate application performance under the demands of the new conditions. Traditional approaches to interprocedural and profile-driven compilation can provide the application performance needed, but require infeasible amounts of compilation time to build -the application.

    +the application.

    +

    This thesis presents LLVM, a design and implementation of a compiler infrastructure which supports a unique multi-stage optimization system. This system is designed to support extensive interprocedural and profile-driven optimizations, while being efficient enough for use in -commercial compiler systems.

    +commercial compiler systems.

    +

    The LLVM virtual instruction set is the glue that holds the system together. It is a low-level representation, but with high-level type information. This provides the benefits of a low-level representation (compact @@ -40,34 +41,38 @@ providing high-level information to support aggressive interprocedural optimizations at link- and post-link time. In particular, this system is designed to support optimization in the field, both at run-time and during -otherwise unused idle time on the machine.

    +otherwise unused idle time on the machine.

    +

    This thesis also describes an implementation of this compiler design, the LLVM compiler infrastructure, proving that the design is feasible. The LLVM compiler infrastructure is a maturing and efficient system, which we show is a good host for a variety of research. More information about LLVM can be found -on its web site at: http://llvm.cs.uiuc.edu/ +on its web site at: http://llvm.cs.uiuc.edu/

    Published:

    -
      - "LLVM: An Infrastructure for Multi-Stage Optimization", Chris Lattner.
      - Masters Thesis, Computer Science Dept., University of Illinois at - Urbana-Champaign, Dec. 2002. -
    +
    + "LLVM: An Infrastructure for Multi-Stage Optimization", Chris Lattner.
    + Masters Thesis, Computer Science Dept., University of Illinois at + Urbana-Champaign, Dec. 2002. +

    Download:

    -

    Bibtex Entry:

    +

    BibTeX Entry:

       @MastersThesis{Lattner:MSThesis02,
         author  = {Chris Lattner},
    -    title   = {{LLVM}: An Infrastructure for Multi-Stage Optimization},
    -    school  = {Computer Science Dept., University of Illinois at Urbana-Champaign},
    +    title   = "{LLVM: An Infrastructure for Multi-Stage Optimization}",
    +    school  = "{Computer Science Dept., University of Illinois at Urbana-Champaign}",
         year    = {2002},
         address = {Urbana, IL},
         month   = {Dec},
    @@ -75,4 +80,5 @@
       }
     
    - + + Index: llvm-www/pubs/2003-04-29-DataStructureAnalysisTR.html diff -u llvm-www/pubs/2003-04-29-DataStructureAnalysisTR.html:1.3 llvm-www/pubs/2003-04-29-DataStructureAnalysisTR.html:1.4 --- llvm-www/pubs/2003-04-29-DataStructureAnalysisTR.html:1.3 Tue Oct 21 17:43:15 2003 +++ llvm-www/pubs/2003-04-29-DataStructureAnalysisTR.html Tue Oct 21 19:26:00 2003 @@ -8,17 +8,13 @@ -


    - - - Data Structure Analysis:
    An Efficient Context-Sensitive Heap Analysis -

    - - +

    + Data Structure Analysis:
    An Efficient Context-Sensitive Heap Analysis +
    +

    Abstract:

    @@ -33,34 +29,35 @@ efficient and scalable enough for large programs. Measurements for 29 programs show that the algorithm is extremely fast, space-efficient, and scales almost linearly across 3 orders-of-magnitude of code size. -

    Published:

    -
      +
      "Data Structure Analysis: An Efficient Context-Sensitive Heap Analysis", - Chris Lattner & Vikram Adve
      - Technical Report #UIUCDCS-R-2003-2340, Computer Science Dept., Univ. of Illinois, Apr. 2003. -
    + Chris Lattner & Vikram Adve
    + Technical Report #UIUCDCS-R-2003-2340, Computer Science Dept., Univ. of + Illinois, Apr. 2003. +

    Update:

    -
      +
      This document was updated on September 15, 2003 to be more clear and precise. -
    +

    Download:

    -

    Bibtex Entry:

    +

    BibTeX Entry:

       @TechReport{LattnerAdve:DSA,
         Author      = {Chris Lattner and Vikram Adve},
    -    Title       = {Data Structure Analysis: An Efficient Context-Sensitive Heap Analysis},
    -    Institution = {Computer Science Dept.,
    -                   Univ. of Illinois at Urbana-Champaign},
    +    Title       = "{Data Structure Analysis: An Efficient Context-Sensitive Heap Analysis}",
    +    Institution = "{Computer Science Dept., Univ. of Illinois at Urbana-Champaign}",
         Number      = {UIUCDCS-R-2003-2340},
         Type        = {Tech. Report},
         Month       = {Apr},
    @@ -68,4 +65,5 @@
       }
     
    - + + Index: llvm-www/pubs/2003-05-01-GCCSummit2003.html diff -u llvm-www/pubs/2003-05-01-GCCSummit2003.html:1.7 llvm-www/pubs/2003-05-01-GCCSummit2003.html:1.8 --- llvm-www/pubs/2003-05-01-GCCSummit2003.html:1.7 Tue Oct 21 17:43:15 2003 +++ llvm-www/pubs/2003-05-01-GCCSummit2003.html Tue Oct 21 19:26:00 2003 @@ -7,14 +7,13 @@ -


    Architecture for a Next-Generation - GCC
    - Chris Lattner and - Vikram Adve - -

    - +
    + Architecture for a Next-Generation GCC +
    +

    Abstract:

    @@ -34,36 +33,42 @@

    Published:

    - +
    + "Architecture For a Next-Generation GCC", Chris Lattner & + Vikram Adve,
    + First Annual GCC Developers' + Summit, Ottawa, Canada, May 2003.
    +

    Download:

    Presentation: -

    Bibtex Entry:

    +

    BibTeX Entry:

    -  @inproceedings{LattnerAdve:GCCSummit03,
    -    Author = {Chris Lattner and Vikram Adve},
    -    Title = {{A}rchitecture for a {N}ext-{G}eneration {GCC}},
    -    Booktitle = {Proc. First Annual GCC Developers' Summit},
    -    Address = {Ottawa, Canada},
    -    Month = {May},
    -    Year = {2003},
    -    URL = {http://llvm.cs.uiuc.edu/pubs/2003-05-01-GCCSummit2003.html}
    +  @InProceedings{LattnerAdve:GCCSummit03,
    +    Author    = {Chris Lattner and Vikram Adve},
    +    Title     = "{Architecture for a Next-Generation GCC}",
    +    Booktitle = "{Proc. First Annual GCC Developers' Summit}",
    +    Address   = {Ottawa, Canada},
    +    Month     = {May},
    +    Year      = {2003},
    +    URL       = {http://llvm.cs.uiuc.edu/pubs/2003-05-01-GCCSummit2003.html}
       }
     
    - + + Index: llvm-www/pubs/2003-05-05-LCTES03-CodeSafety.html diff -u llvm-www/pubs/2003-05-05-LCTES03-CodeSafety.html:1.4 llvm-www/pubs/2003-05-05-LCTES03-CodeSafety.html:1.5 --- llvm-www/pubs/2003-05-05-LCTES03-CodeSafety.html:1.4 Tue Oct 21 17:43:15 2003 +++ llvm-www/pubs/2003-05-05-LCTES03-CodeSafety.html Tue Oct 21 19:26:00 2003 @@ -7,76 +7,71 @@ -


    Memory Safety Without Runtime Checks or Garbage Collection
    - Dinakar Dhurjati, Sumant Kowshik, - Vikram Adve and - Chris Lattner -

    - +
    + Memory Safety Without Runtime Checks or Garbage Collection +
    +
    + Dinakar Dhurjati, Sumant Kowshik, + Vikram Adve and + Chris Lattner +

    Abstract:

    Traditional approaches to enforcing memory safety of programs rely heavily on -runtime checks of memory accesses and on garbage collection, both of which -are unattractive for embedded applications. -The long-term goal of our work is to -enable 100% static enforcement of memory safety for embedded programs -through advanced compiler techniques and minimal semantic -restrictions on programs. -The key result of this paper is a compiler technique that ensures -memory safety of -dynamically allocated memory without programmer annotations, runtime -checks, or garbage collection, and works for a large subclass of type-safe -C programs. -The technique is based on a fully automatic pool allocation -(i.e., region-inference) -algorithm for C programs we developed previously, and it ensures safety of -dynamically allocated memory while retaining explicit deallocation of -individual objects within regions (to avoid garbage collection). -For a diverse set of embedded C programs -(and using a previous technique to avoid null pointer checks), -we show that we are able to -statically ensure the safety of pointer and dynamic memory usage -in all these programs. -We also describe some improvements over our previous work in static checking -of array accesses. -Overall, we achieve 100% static enforcement of memory safety -without new language syntax for a significant subclass of embedded C -programs, and the subclass is much broader if array bounds checks are ignored. - +runtime checks of memory accesses and on garbage collection, both of which are +unattractive for embedded applications. The long-term goal of our work is to +enable 100% static enforcement of memory safety for embedded programs through +advanced compiler techniques and minimal semantic restrictions on programs. The +key result of this paper is a compiler technique that ensures memory safety of +dynamically allocated memory without programmer annotations, runtime checks, +or garbage collection, and works for a large subclass of type-safe C +programs. The technique is based on a fully automatic pool allocation (i.e., +region-inference) algorithm for C programs we developed previously, and it +ensures safety of dynamically allocated memory while retaining explicit +deallocation of individual objects within regions (to avoid garbage collection). +For a diverse set of embedded C programs (and using a previous technique to +avoid null pointer checks), we show that we are able to statically ensure the +safety of pointer and dynamic memory usage in all these programs. We +also describe some improvements over our previous work in static checking of +array accesses. Overall, we achieve 100% static enforcement of memory safety +without new language syntax for a significant subclass of embedded C programs, +and the subclass is much broader if array bounds checks are ignored.

    Published:

    -
      - "Memory Safety Without Runtime Checks or Garbage Collection", Dinakar Dhurjati, Sumant Kowshik, Vikram Adve & - Chris Lattner,
      - LCTES 2003 - , San Diego, CA, June 2003.
      -
    +
    + "Memory Safety Without Runtime Checks or Garbage Collection", Dinakar + Dhurjati, Sumant Kowshik, Vikram Adve & Chris Lattner,
    + LCTES 2003, San + Diego, CA, June 2003.
    +

    Download:

    -

    Bibtex Entry:

    +

    BibTeX Entry:

    -  @inproceedings{DKAL:LCTES03,
    -    Author = {Dinakar Dhurjati, Sumant Kowshik, Vikram Adve and Chris Lattner},
    -    Title = {{M}emory {S}afety {W}ithout {R}untime {C}hecks or {G}arbage {C}ollection},
    -    Booktitle = {Proc. Languages Compilers and Tools for Embedded Systems 2003},
    -    Address = {San Diego, CA},
    -    Month = {June},
    -    Year = {2003},
    -    URL = {http://llvm.cs.uiuc.edu/pubs/2003-05-05-LCTES03-CodeSafety.html}
    +  @InProceedings{DKAL:LCTES03,
    +    Author    = {Dinakar Dhurjati, Sumant Kowshik, Vikram Adve and Chris Lattner},
    +    Title     = "{Memory Safety Without Runtime Checks or Garbage Collection}",
    +    Booktitle = "{Proc. Languages Compilers and Tools for Embedded Systems 2003}",
    +    Address   = {San Diego, CA},
    +    Month     = {June},
    +    Year      = {2003},
    +    URL       = {http://llvm.cs.uiuc.edu/pubs/2003-05-05-LCTES03-CodeSafety.html}
       }
     
    -

    Links:

    - +

    Links:

    SAFECode project - + + Index: llvm-www/pubs/2003-09-30-LifelongOptimizationTR.html diff -u llvm-www/pubs/2003-09-30-LifelongOptimizationTR.html:1.2 llvm-www/pubs/2003-09-30-LifelongOptimizationTR.html:1.3 --- llvm-www/pubs/2003-09-30-LifelongOptimizationTR.html:1.2 Tue Oct 21 17:43:15 2003 +++ llvm-www/pubs/2003-09-30-LifelongOptimizationTR.html Tue Oct 21 19:26:00 2003 @@ -8,25 +8,22 @@ -


    - - +

    LLVM: A Compilation Framework for
    - Lifelong Program Analysis & Transformation -

    - - - Chris Lattner and - Vikram Adve -

    + Lifelong Program Analysis & Transformation +
    +

    Abstract:

    This paper describes LLVM (Low Level Virtual Machine), a compiler framework designed to support transparent, lifelong program analysis and -transformation for arbitrary programs, by providing high-level information to -compiler transformations at compile-time, link-time, run-time, and offline. +transformation for arbitrary programs, by providing high-level information +to compiler transformations at compile-time, link-time, run-time, and offline. LLVM defines a common, low-level code representation in Static Single Assignment (SSA) form, with several novel features: a simple, language-independent type-system that exposes the primitives commonly used to implement high-level @@ -45,25 +42,28 @@

    Published:

    -
      - "LLVM: A Compilation Framework for Lifelong Program Analysis & Transformation", - Chris Lattner & Vikram Adve
      - Technical Report #UIUCDCS-R-2003-2380, Computer Science Dept., Univ. of Illinois, Sep. 2003. -
    +
    + "LLVM: A Compilation Framework for Lifelong Program Analysis & + Transformation", Chris Lattner & Vikram Adve
    + Technical Report #UIUCDCS-R-2003-2380, Computer Science Dept., Univ. of + Illinois, Sep. 2003. +

    Download:

    -

    Bibtex Entry:

    +

    BibTeX Entry:

       @TechReport{LattnerAdve:LifeLong,
         Author      = {Chris Lattner and Vikram Adve},
    -    Title       = {LLVM: A Compilation Framework for Lifelong Program Analysis & Transformation},
    -    Institution = {Computer Science Dept.,
    -                   Univ. of Illinois at Urbana-Champaign},
    +    Title       = "{LLVM: A Compilation Framework for Lifelong Program Analysis & Transformation}",
    +    Institution = "{Computer Science Dept., Univ. of Illinois at Urbana-Champaign}",
         Number      = {UIUCDCS-R-2003-2380},
         Type        = {Tech. Report},
         Month       = {Sep},
    @@ -71,4 +71,5 @@
       }
     
    - + + Index: llvm-www/pubs/2003-10-01-LLVA.html diff -u llvm-www/pubs/2003-10-01-LLVA.html:1.3 llvm-www/pubs/2003-10-01-LLVA.html:1.4 --- llvm-www/pubs/2003-10-01-LLVA.html:1.3 Tue Oct 21 17:43:15 2003 +++ llvm-www/pubs/2003-10-01-LLVA.html Tue Oct 21 19:26:00 2003 @@ -7,20 +7,16 @@ -


    - - +

    LLVA: A Low-level Virtual Instruction Set Architecture -
    - - +
    +

    Abstract:

    @@ -47,27 +43,32 @@

    Published:

    -
      - "LLVA: A Low-level Virtual Instruction Set Architecture", Vikram Adve, Chris Lattner, Michael Brukman, Anand Shukla, and Brian Gaeke.
      -Proceedings of the 36th annual ACM/IEEE international symposium on Microarchitecture (MICRO-36), San Diego, California, Dec. 2003. -
    +
    + "LLVA: A Low-level Virtual Instruction Set Architecture", Vikram Adve, Chris + Lattner, Michael Brukman, Anand Shukla, and Brian Gaeke.
    + Proceedings of the 36th annual ACM/IEEE international symposium on + Microarchitecture (MICRO-36), San Diego, California, Dec. 2003. +

    Download:

    -

    Bibtex Entry:

    +

    BibTeX Entry:

       @InProceedings{ALBSG:MICRO36,
         author    = {Vikram Adve and Chris Lattner and Michael Brukman and Anand Shukla and Brian Gaeke},
    -    title     = {{LLVA: A Low-level Virtual Instruction Set Architecture}},
    -    booktitle = {Proceedings of the 36th annual ACM/IEEE international symposium on Microarchitecture (MICRO-36)},
    -    address = {San Diego, California},
    -    month   = {Dec},
    -    year    = {2003}
    +    title     = "{LLVA: A Low-level Virtual Instruction Set Architecture}",
    +    booktitle = "{Proceedings of the 36th annual ACM/IEEE international symposium on Microarchitecture (MICRO-36)}",
    +    address   = {San Diego, California},
    +    month     = {Dec},
    +    year      = {2003}
       }
     
    - + + From brukman at cs.uiuc.edu Tue Oct 21 22:11:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Tue Oct 21 22:11:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrBuilder.h Message-ID: <200310220310.WAA02362@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrBuilder.h updated: 1.7 -> 1.8 --- Log message: Converted tabs to spaces. --- Diffs of the changes: (+1 -1) Index: llvm/lib/Target/X86/X86InstrBuilder.h diff -u llvm/lib/Target/X86/X86InstrBuilder.h:1.7 llvm/lib/Target/X86/X86InstrBuilder.h:1.8 --- llvm/lib/Target/X86/X86InstrBuilder.h:1.7 Tue Oct 21 10:17:13 2003 +++ llvm/lib/Target/X86/X86InstrBuilder.h Tue Oct 21 22:10:26 2003 @@ -65,7 +65,7 @@ /// inline const MachineInstrBuilder & addConstantPoolReference(const MachineInstrBuilder &MIB, unsigned CPI, - int Offset = 0) { + int Offset = 0) { return MIB.addConstantPoolIndex(CPI).addZImm(1).addReg(0).addSImm(Offset); } From brukman at cs.uiuc.edu Tue Oct 21 22:28:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Tue Oct 21 22:28:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/PreSelection.cpp Message-ID: <200310220327.WAA04805@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: PreSelection.cpp updated: 1.22 -> 1.23 --- Log message: * Fix order of #includes to follow style guide * It's no longer a BasicBlock pass: update comment on run() method * Fix placement of braces to be consistent * Delete extraneous whitespace --- Diffs of the changes: (+27 -39) Index: llvm/lib/Target/Sparc/PreSelection.cpp diff -u llvm/lib/Target/Sparc/PreSelection.cpp:1.22 llvm/lib/Target/Sparc/PreSelection.cpp:1.23 --- llvm/lib/Target/Sparc/PreSelection.cpp:1.22 Tue Oct 21 12:22:23 2003 +++ llvm/lib/Target/Sparc/PreSelection.cpp Tue Oct 21 22:27:45 2003 @@ -16,17 +16,17 @@ //===----------------------------------------------------------------------===// #include "SparcInternals.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Transforms/Scalar.h" -#include "llvm/Support/InstVisitor.h" -#include "llvm/Module.h" #include "llvm/Constants.h" #include "llvm/iMemory.h" #include "llvm/iPHINode.h" #include "llvm/iOther.h" #include "llvm/DerivedTypes.h" +#include "llvm/Module.h" #include "llvm/Pass.h" +#include "llvm/Support/InstVisitor.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Transforms/Scalar.h" #include namespace { @@ -53,7 +53,7 @@ PreSelection(const TargetMachine &T) : instrInfo(T.getInstrInfo()), TheModule(0) {} - // runOnBasicBlock - apply this pass to each BB + // run - apply this pass to the entire Module bool run(Module &M) { TheModule = &M; @@ -100,8 +100,7 @@ // getGlobalAddr(): Put address of a global into a v. register. -static GetElementPtrInst* getGlobalAddr(Value* ptr, Instruction& insertBefore) -{ +static GetElementPtrInst* getGlobalAddr(Value* ptr, Instruction& insertBefore) { if (isa(ptr)) ptr = cast(ptr)->getValue(); @@ -114,8 +113,7 @@ // Wrapper on Constant::classof to use in find_if :-( -inline static bool nonConstant(const Use& U) -{ +inline static bool nonConstant(const Use& U) { return ! isa(U); } @@ -180,24 +178,22 @@ if (CV == NULL) return; - if (ConstantExpr* CE = dyn_cast(CV)) - { // load-time constant: factor it out so we optimize as best we can - Instruction* computeConst = DecomposeConstantExpr(CE, insertBefore); - I.setOperand(opNum, computeConst); // replace expr operand with result - } - else if (instrInfo.ConstantTypeMustBeLoaded(CV)) - { // load address of constant into a register, then load the constant - GetElementPtrInst* gep = getGlobalAddr(getGlobalForConstant(CV), - insertBefore); - LoadInst* ldI = new LoadInst(gep, "loadConst", &insertBefore); - I.setOperand(opNum, ldI); // replace operand with copy in v.reg. - } - else if (instrInfo.ConstantMayNotFitInImmedField(CV, &I)) - { // put the constant into a virtual register using a cast - CastInst* castI = new CastInst(CV, CV->getType(), "copyConst", - &insertBefore); - I.setOperand(opNum, castI); // replace operand with copy in v.reg. - } + if (ConstantExpr* CE = dyn_cast(CV)) { + // load-time constant: factor it out so we optimize as best we can + Instruction* computeConst = DecomposeConstantExpr(CE, insertBefore); + I.setOperand(opNum, computeConst); // replace expr operand with result + } else if (instrInfo.ConstantTypeMustBeLoaded(CV)) { + // load address of constant into a register, then load the constant + GetElementPtrInst* gep = getGlobalAddr(getGlobalForConstant(CV), + insertBefore); + LoadInst* ldI = new LoadInst(gep, "loadConst", &insertBefore); + I.setOperand(opNum, ldI); // replace operand with copy in v.reg. + } else if (instrInfo.ConstantMayNotFitInImmedField(CV, &I)) { + // put the constant into a virtual register using a cast + CastInst* castI = new CastInst(CV, CV->getType(), "copyConst", + &insertBefore); + I.setOperand(opNum, castI); // replace operand with copy in v.reg. + } } // visitOperands() transforms individual operands of all instructions: @@ -232,17 +228,13 @@ // Common work for *all* instructions. This needs to be called explicitly // by other visit functions. -inline void -PreSelection::visitInstruction(Instruction &I) -{ +inline void PreSelection::visitInstruction(Instruction &I) { visitOperands(I); // Perform operand transformations } // GetElementPtr instructions: check if pointer is a global -void -PreSelection::visitGetElementPtrInst(GetElementPtrInst &I) -{ +void PreSelection::visitGetElementPtrInst(GetElementPtrInst &I) { Instruction* curI = &I; // Decompose multidimensional array references @@ -261,10 +253,7 @@ visitInstruction(*curI); } - -void -PreSelection::visitCallInst(CallInst &I) -{ +void PreSelection::visitCallInst(CallInst &I) { // Tell visitOperands to ignore the function name if this is a direct call. visitOperands(I, (/*firstOp=*/ I.getCalledFunction()? 1 : 0)); } @@ -277,4 +266,3 @@ Pass* createPreSelectionPass(TargetMachine &T) { return new PreSelection(T); } - From lattner at cs.uiuc.edu Tue Oct 21 22:36:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 21 22:36:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/FunctionResolution.cpp Message-ID: <200310220335.WAA09329@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: FunctionResolution.cpp updated: 1.38 -> 1.39 --- Log message: Implement FunctionResolve/2003-10-21-GlobalResolveHack.ll --- Diffs of the changes: (+34 -2) Index: llvm/lib/Transforms/IPO/FunctionResolution.cpp diff -u llvm/lib/Transforms/IPO/FunctionResolution.cpp:1.38 llvm/lib/Transforms/IPO/FunctionResolution.cpp:1.39 --- llvm/lib/Transforms/IPO/FunctionResolution.cpp:1.38 Tue Oct 21 18:17:56 2003 +++ llvm/lib/Transforms/IPO/FunctionResolution.cpp Tue Oct 21 22:35:34 2003 @@ -25,6 +25,7 @@ #include "llvm/Pass.h" #include "llvm/iOther.h" #include "llvm/Constants.h" +#include "llvm/Target/TargetData.h" #include "llvm/Assembly/Writer.h" #include "Support/Statistic.h" #include @@ -34,6 +35,10 @@ Statistic<> NumGlobals("funcresolve", "Number of global variables resolved"); struct FunctionResolvingPass : public Pass { + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + } + bool run(Module &M); }; RegisterOpt X("funcresolve", "Resolve Functions"); @@ -125,7 +130,7 @@ return Changed; } -static bool ProcessGlobalsWithSameName(Module &M, +static bool ProcessGlobalsWithSameName(Module &M, TargetData &TD, std::vector &Globals) { assert(!Globals.empty() && "Globals list shouldn't be empty here!"); @@ -202,6 +207,31 @@ if (!Concrete) Concrete = Globals[0]; + else if (GlobalVariable *GV = dyn_cast(Concrete)) { + // Handle special case hack to change globals if it will make their types + // happier in the long run. The situation we do this is intentionally + // extremely limited. + if (GV->use_empty() && GV->hasInitializer() && + GV->getInitializer()->isNullValue()) { + // Check to see if there is another (external) global with the same size + // and a non-empty use-list. If so, we will make IT be the real + // implementation. + unsigned TS = TD.getTypeSize(Concrete->getType()->getElementType()); + for (unsigned i = 0, e = Globals.size(); i != e; ++i) + if (Globals[i] != Concrete && !Globals[i]->use_empty() && + isa(Globals[i]) && + TD.getTypeSize(Globals[i]->getType()->getElementType()) == TS) { + // At this point we want to replace Concrete with Globals[i]. Make + // concrete external, and Globals[i] have an initializer. + GlobalVariable *NGV = cast(Globals[i]); + const Type *ElTy = NGV->getType()->getElementType(); + NGV->setInitializer(Constant::getNullValue(ElTy)); + cast(Concrete)->setInitializer(0); + Concrete = NGV; + break; + } + } + } if (isFunction) return ResolveFunctions(M, Globals, cast(Concrete)); @@ -236,12 +266,14 @@ bool Changed = false; + TargetData &TD = getAnalysis(); + // Now we have a list of all functions with a particular name. If there is // more than one entry in a list, merge the functions together. // for (std::map >::iterator I = Globals.begin(), E = Globals.end(); I != E; ++I) - Changed |= ProcessGlobalsWithSameName(M, I->second); + Changed |= ProcessGlobalsWithSameName(M, TD, I->second); // Now loop over all of the globals, checking to see if any are trivially // dead. If so, remove them now. From lattner at cs.uiuc.edu Tue Oct 21 22:36:11 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 21 22:36:11 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/FunctionResolve/2003-10-21-GlobalResolveHack.ll Message-ID: <200310220335.WAA09273@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/FunctionResolve: 2003-10-21-GlobalResolveHack.ll added (r1.1) --- Log message: New testcase for fun hack that is absolutely necessary for the C++ stdlib. --- Diffs of the changes: (+14 -0) Index: llvm/test/Regression/Transforms/FunctionResolve/2003-10-21-GlobalResolveHack.ll diff -c /dev/null llvm/test/Regression/Transforms/FunctionResolve/2003-10-21-GlobalResolveHack.ll:1.1 *** /dev/null Tue Oct 21 22:35:28 2003 --- llvm/test/Regression/Transforms/FunctionResolve/2003-10-21-GlobalResolveHack.ll Tue Oct 21 22:35:18 2003 *************** *** 0 **** --- 1,14 ---- + ; This tests a hack put into place specifically for the C++ libstdc++ library. + ; It uses an ugly hack which is cleaned up by the funcresolve pass. + + ; RUN: llvm-as < %s | opt -funcresolve | llvm-dis | grep %X | grep '{' + + %X = external global { int } + %X = global [ 4 x sbyte ] zeroinitializer + + implementation + + int* %test() { + %P = getelementptr {int}* %X, long 0, ubyte 0 + ret int* %P + } From lattner at cs.uiuc.edu Tue Oct 21 22:41:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 21 22:41:02 2003 Subject: [llvm-commits] CVS: llvm/tools/extract/Makefile Message-ID: <200310220340.WAA10554@zion.cs.uiuc.edu> Changes in directory llvm/tools/extract: Makefile updated: 1.3 -> 1.4 --- Log message: New library needed --- Diffs of the changes: (+2 -2) Index: llvm/tools/extract/Makefile diff -u llvm/tools/extract/Makefile:1.3 llvm/tools/extract/Makefile:1.4 --- llvm/tools/extract/Makefile:1.3 Mon Oct 20 17:27:26 2003 +++ llvm/tools/extract/Makefile Tue Oct 21 22:40:33 2003 @@ -9,7 +9,7 @@ LEVEL = ../.. TOOLNAME = extract -USEDLIBS = bcreader bcwriter transforms.a ipo.a analysis.a transformutils.a \ - ipa.a vmcore support.a +USEDLIBS = bcreader bcwriter transforms.a ipo.a target.a analysis.a \ + transformutils.a ipa.a vmcore support.a include $(LEVEL)/Makefile.common From lattner at cs.uiuc.edu Tue Oct 21 23:43:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 21 23:43:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/FunctionResolution.cpp Message-ID: <200310220442.XAA23264@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: FunctionResolution.cpp updated: 1.39 -> 1.40 --- Log message: Loop over the module, not the symbol table. This makes the code handle unused external functions again --- Diffs of the changes: (+18 -21) Index: llvm/lib/Transforms/IPO/FunctionResolution.cpp diff -u llvm/lib/Transforms/IPO/FunctionResolution.cpp:1.39 llvm/lib/Transforms/IPO/FunctionResolution.cpp:1.40 --- llvm/lib/Transforms/IPO/FunctionResolution.cpp:1.39 Tue Oct 21 22:35:34 2003 +++ llvm/lib/Transforms/IPO/FunctionResolution.cpp Tue Oct 21 23:42:20 2003 @@ -20,7 +20,6 @@ #include "llvm/Transforms/IPO.h" #include "llvm/Module.h" -#include "llvm/SymbolTable.h" #include "llvm/DerivedTypes.h" #include "llvm/Pass.h" #include "llvm/iOther.h" @@ -137,9 +136,6 @@ bool isFunction = isa(Globals[0]); // Is this group all functions? GlobalValue *Concrete = 0; // The most concrete implementation to resolve to - assert((isFunction ^ isa(Globals[0])) && - "Should either be function or gvar!"); - for (unsigned i = 0; i != Globals.size(); ) { if (isa(Globals[i]) != isFunction) { std::cerr << "WARNING: Found function and global variable with the " @@ -243,26 +239,27 @@ } bool FunctionResolvingPass::run(Module &M) { - SymbolTable &ST = M.getSymbolTable(); - std::map > Globals; - // Loop over the entries in the symbol table. If an entry is a func pointer, - // then add it to the Functions map. We do a two pass algorithm here to avoid - // problems with iterators getting invalidated if we did a one pass scheme. + // Loop over the globals, adding them to the Globals map. We use a two pass + // algorithm here to avoid problems with iterators getting invalidated if we + // did a one pass scheme. // - for (SymbolTable::iterator I = ST.begin(), E = ST.end(); I != E; ++I) - if (const PointerType *PT = dyn_cast(I->first)) { - SymbolTable::VarMap &Plane = I->second; - for (SymbolTable::type_iterator PI = Plane.begin(), PE = Plane.end(); - PI != PE; ++PI) { - GlobalValue *GV = cast(PI->second); - assert(PI->first == GV->getName() && - "Global name and symbol table do not agree!"); - if (!GV->hasInternalLinkage()) - Globals[PI->first].push_back(GV); - } - } + for (Module::iterator I = M.begin(), E = M.end(); I != E; ) { + Function *F = I++; + if (F->use_empty() && F->isExternal()) + M.getFunctionList().erase(F); + else if (!F->hasInternalLinkage() && !F->getName().empty()) + Globals[F->getName()].push_back(F); + } + + for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ) { + GlobalVariable *GV = I++; + if (GV->use_empty() && GV->isExternal()) + M.getGlobalList().erase(GV); + else if (!GV->hasInternalLinkage() && !GV->getName().empty()) + Globals[GV->getName()].push_back(GV); + } bool Changed = false; From lattner at cs.uiuc.edu Tue Oct 21 23:44:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 21 23:44:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/FunctionResolution.cpp Message-ID: <200310220443.XAA26967@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: FunctionResolution.cpp updated: 1.40 -> 1.41 --- Log message: Update the 'used' flag correctly --- Diffs of the changes: (+7 -6) Index: llvm/lib/Transforms/IPO/FunctionResolution.cpp diff -u llvm/lib/Transforms/IPO/FunctionResolution.cpp:1.40 llvm/lib/Transforms/IPO/FunctionResolution.cpp:1.41 --- llvm/lib/Transforms/IPO/FunctionResolution.cpp:1.40 Tue Oct 21 23:42:20 2003 +++ llvm/lib/Transforms/IPO/FunctionResolution.cpp Tue Oct 21 23:43:18 2003 @@ -245,23 +245,24 @@ // algorithm here to avoid problems with iterators getting invalidated if we // did a one pass scheme. // + bool Changed = false; for (Module::iterator I = M.begin(), E = M.end(); I != E; ) { Function *F = I++; - if (F->use_empty() && F->isExternal()) + if (F->use_empty() && F->isExternal()) { M.getFunctionList().erase(F); - else if (!F->hasInternalLinkage() && !F->getName().empty()) + Changed = true; + } else if (!F->hasInternalLinkage() && !F->getName().empty()) Globals[F->getName()].push_back(F); } for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ) { GlobalVariable *GV = I++; - if (GV->use_empty() && GV->isExternal()) + if (GV->use_empty() && GV->isExternal()) { M.getGlobalList().erase(GV); - else if (!GV->hasInternalLinkage() && !GV->getName().empty()) + Changed = true; + } else if (!GV->hasInternalLinkage() && !GV->getName().empty()) Globals[GV->getName()].push_back(GV); } - - bool Changed = false; TargetData &TD = getAnalysis(); From brukman at cs.uiuc.edu Tue Oct 21 23:52:00 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Tue Oct 21 23:52:00 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/PreSelection.cpp Message-ID: <200310220451.XAA06827@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: PreSelection.cpp updated: 1.23 -> 1.24 --- Log message: No, really, order the #includes correctly. --- Diffs of the changes: (+1 -1) Index: llvm/lib/Target/Sparc/PreSelection.cpp diff -u llvm/lib/Target/Sparc/PreSelection.cpp:1.23 llvm/lib/Target/Sparc/PreSelection.cpp:1.24 --- llvm/lib/Target/Sparc/PreSelection.cpp:1.23 Tue Oct 21 22:27:45 2003 +++ llvm/lib/Target/Sparc/PreSelection.cpp Tue Oct 21 23:51:36 2003 @@ -17,10 +17,10 @@ #include "SparcInternals.h" #include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" #include "llvm/iMemory.h" #include "llvm/iPHINode.h" #include "llvm/iOther.h" -#include "llvm/DerivedTypes.h" #include "llvm/Module.h" #include "llvm/Pass.h" #include "llvm/Support/InstVisitor.h" From brukman at cs.uiuc.edu Tue Oct 21 23:56:00 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Tue Oct 21 23:56:00 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInstrSelection.cpp Message-ID: <200310220455.XAA08238@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcInstrSelection.cpp updated: 1.123 -> 1.124 --- Log message: Removed completely duplicated function comment (an identical one appears later). --- Diffs of the changes: (+0 -19) Index: llvm/lib/Target/Sparc/SparcInstrSelection.cpp diff -u llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.123 llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.124 --- llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.123 Tue Oct 21 07:28:27 2003 +++ llvm/lib/Target/Sparc/SparcInstrSelection.cpp Tue Oct 21 23:55:09 2003 @@ -40,25 +40,6 @@ } - -//--------------------------------------------------------------------------- -// Function: GetMemInstArgs -// -// Purpose: -// Get the pointer value and the index vector for a memory operation -// (GetElementPtr, Load, or Store). If all indices of the given memory -// operation are constant, fold in constant indices in a chain of -// preceding GetElementPtr instructions (if any), and return the -// pointer value of the first instruction in the chain. -// All folded instructions are marked so no code is generated for them. -// -// Return values: -// Returns the pointer Value to use. -// Returns the resulting IndexVector in idxVec. -// Returns true/false in allConstantIndices if all indices are/aren't const. -//--------------------------------------------------------------------------- - - //--------------------------------------------------------------------------- // Function: FoldGetElemChain // From brukman at cs.uiuc.edu Wed Oct 22 00:11:08 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Oct 22 00:11:08 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInstrSelection.cpp Message-ID: <200310220510.AAA14870@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcInstrSelection.cpp updated: 1.124 -> 1.125 --- Log message: * Use instead of * Order #includes according to LLVM coding standards --- Diffs of the changes: (+12 -12) Index: llvm/lib/Target/Sparc/SparcInstrSelection.cpp diff -u llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.124 llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.125 --- llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.124 Tue Oct 21 23:55:09 2003 +++ llvm/lib/Target/Sparc/SparcInstrSelection.cpp Wed Oct 22 00:09:56 2003 @@ -11,26 +11,26 @@ // //===----------------------------------------------------------------------===// -#include "SparcInternals.h" #include "SparcInstrSelectionSupport.h" +#include "SparcInternals.h" #include "SparcRegClassInfo.h" -#include "llvm/CodeGen/InstrSelectionSupport.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineInstrAnnot.h" +#include "llvm/Constants.h" +#include "llvm/ConstantHandling.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Instructions.h" +#include "llvm/Intrinsics.h" +#include "llvm/Module.h" #include "llvm/CodeGen/InstrForest.h" #include "llvm/CodeGen/InstrSelection.h" +#include "llvm/CodeGen/InstrSelectionSupport.h" +#include "llvm/CodeGen/MachineCodeForInstruction.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionInfo.h" -#include "llvm/CodeGen/MachineCodeForInstruction.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Instructions.h" -#include "llvm/Module.h" -#include "llvm/Constants.h" -#include "llvm/ConstantHandling.h" -#include "llvm/Intrinsics.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineInstrAnnot.h" #include "Support/MathExtras.h" -#include #include +#include static inline void Add3OperandInstr(unsigned Opcode, InstructionNode* Node, std::vector& mvec) { From brukman at cs.uiuc.edu Wed Oct 22 00:51:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Oct 22 00:51:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInstrSelectionSupport.h Message-ID: <200310220550.AAA23698@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcInstrSelectionSupport.h updated: 1.11 -> 1.12 --- Log message: Add comments to describe what these functions actually do. --- Diffs of the changes: (+7 -0) Index: llvm/lib/Target/Sparc/SparcInstrSelectionSupport.h diff -u llvm/lib/Target/Sparc/SparcInstrSelectionSupport.h:1.11 llvm/lib/Target/Sparc/SparcInstrSelectionSupport.h:1.12 --- llvm/lib/Target/Sparc/SparcInstrSelectionSupport.h:1.11 Tue Oct 21 10:17:13 2003 +++ llvm/lib/Target/Sparc/SparcInstrSelectionSupport.h Wed Oct 22 00:50:40 2003 @@ -17,6 +17,7 @@ #include "llvm/DerivedTypes.h" #include "SparcInternals.h" +// Choose load instruction opcode based on type of value inline MachineOpCode ChooseLoadInstruction(const Type *DestTy) { @@ -39,6 +40,7 @@ return 0; } +// Choose store instruction opcode based on type of value inline MachineOpCode ChooseStoreInstruction(const Type *DestTy) { @@ -86,6 +88,11 @@ } +// Because the Sparc instruction selector likes to re-write operands to +// instructions, making them change from a Value* (virtual register) to a +// Constant* (making an immediate field), we need to change the opcode from a +// register-based instruction to an immediate-based instruction, hence this +// mapping. static unsigned convertOpcodeFromRegToImm(unsigned Opcode) { switch (Opcode) { From criswell at cs.uiuc.edu Wed Oct 22 10:07:05 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Wed Oct 22 10:07:05 2003 Subject: [llvm-commits] CVS: llvm/docs/HowToSubmitABug.html Message-ID: <200310221506.KAA09379@choi.cs.uiuc.edu> Changes in directory llvm/docs: HowToSubmitABug.html updated: 1.6 -> 1.7 --- Log message: Added information on using Bugzilla. Removed information on using llvm-bugs to report bugs. --- Diffs of the changes: (+18 -4) Index: llvm/docs/HowToSubmitABug.html diff -u llvm/docs/HowToSubmitABug.html:1.6 llvm/docs/HowToSubmitABug.html:1.7 --- llvm/docs/HowToSubmitABug.html:1.6 Tue Oct 14 15:58:07 2003 +++ llvm/docs/HowToSubmitABug.html Wed Oct 22 10:06:11 2003 @@ -49,11 +49,25 @@ down the bug so that the person who fixes it will be able to find the problem more easily.

    -Once you have a reduced test-case, email information about the bug to: llvmbugs at cs.uiuc.edu. This should -include all of the information necessary to reproduce the problem, including -where you got the LLVM tree from (if you're not working out of CVS).

    +Once you have a reduced test-case, go to + +the LLVM Bug Tracking System, + +select the catagory in which the bug falls, and fill out the form with the +necessary details. The bug description should contain the following +information: +

      +
    • + All information necessary to reproduce the problem. +
    • + The reduced test-case that triggers the bug. + +
    • + The location where you obtained LLVM (if not from our CVS repository). +
    + +

    Thanks for helping us make LLVM better!

    From lattner at cs.uiuc.edu Wed Oct 22 11:04:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Oct 22 11:04:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Function.h Message-ID: <200310221603.LAA17837@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Function.h updated: 1.46 -> 1.47 --- Log message: Add two new function stubs for viewing the CFG of a function inside of the debugger --- Diffs of the changes: (+15 -0) Index: llvm/include/llvm/Function.h diff -u llvm/include/llvm/Function.h:1.46 llvm/include/llvm/Function.h:1.47 --- llvm/include/llvm/Function.h:1.46 Mon Oct 20 15:19:14 2003 +++ llvm/include/llvm/Function.h Wed Oct 22 11:03:20 2003 @@ -183,6 +183,21 @@ virtual void print(std::ostream &OS) const; + /// viewCFG - This function is meant for use from the debugger. You can just + /// say 'call F->viewCFG()' and a ghostview window should pop up from the + /// program, displaying the CFG of the current function with the code for each + /// basic block inside. This depends on there being a 'dot' and 'gv' program + /// in your path. + /// + void viewCFG() const; + + /// viewCFGOnly - This function is meant for use from the debugger. It works + /// just like viewCFG, but it does not include the contents of basic blocks + /// into the nodes, just the label. If you are only interested in the CFG t + /// his can make the graph smaller. + /// + void viewCFGOnly() const; + /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Function *) { return true; } static inline bool classof(const Value *V) { From lattner at cs.uiuc.edu Wed Oct 22 11:04:14 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Oct 22 11:04:14 2003 Subject: [llvm-commits] CVS: llvm/tools/analyze/GraphPrinters.cpp Message-ID: <200310221603.LAA17609@zion.cs.uiuc.edu> Changes in directory llvm/tools/analyze: GraphPrinters.cpp updated: 1.4 -> 1.5 --- Log message: Delete the -print-cfg pass from this file --- Diffs of the changes: (+2 -67) Index: llvm/tools/analyze/GraphPrinters.cpp diff -u llvm/tools/analyze/GraphPrinters.cpp:1.4 llvm/tools/analyze/GraphPrinters.cpp:1.5 --- llvm/tools/analyze/GraphPrinters.cpp:1.4 Mon Oct 20 12:55:44 2003 +++ llvm/tools/analyze/GraphPrinters.cpp Wed Oct 22 11:02:58 2003 @@ -16,55 +16,10 @@ #include "Support/GraphWriter.h" #include "llvm/Pass.h" -#include "llvm/iTerminators.h" +#include "llvm/Value.h" #include "llvm/Analysis/CallGraph.h" -#include "llvm/Support/CFG.h" -#include #include -//===----------------------------------------------------------------------===// -// Control Flow Graph Printer -//===----------------------------------------------------------------------===// - -template<> -struct DOTGraphTraits : public DefaultDOTGraphTraits { - static std::string getGraphName(Function *F) { - return "CFG for '" + F->getName() + "' function"; - } - - static std::string getNodeLabel(BasicBlock *Node, Function *Graph) { - std::ostringstream Out; - Out << Node; - std::string OutStr = Out.str(); - if (OutStr[0] == '\n') OutStr.erase(OutStr.begin()); - - // Process string output to make it nicer... - for (unsigned i = 0; i != OutStr.length(); ++i) - if (OutStr[i] == '\n') { // Left justify - OutStr[i] = '\\'; - OutStr.insert(OutStr.begin()+i+1, 'l'); - } else if (OutStr[i] == ';') { // Delete comments! - unsigned Idx = OutStr.find('\n', i+1); // Find end of line - OutStr.erase(OutStr.begin()+i, OutStr.begin()+Idx); - --i; - } - - return OutStr; - } - - static std::string getNodeAttributes(BasicBlock *N) { - return "fontname=Courier"; - } - - static std::string getEdgeSourceLabel(BasicBlock *Node, succ_iterator I) { - // Label source of conditional branches with "T" or "F" - if (BranchInst *BI = dyn_cast(Node->getTerminator())) - if (BI->isConditional()) - return (I == succ_begin(Node)) ? "T" : "F"; - return ""; - } -}; - template static void WriteGraphToFile(std::ostream &O, const std::string &GraphName, const GraphType >) { @@ -80,26 +35,6 @@ } -namespace { - struct CFGPrinter : public FunctionPass { - virtual bool runOnFunction(Function &Func) { - WriteGraphToFile(std::cerr, "cfg."+Func.getName(), &Func); - return false; - } - - void print(std::ostream &OS) const {} - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - } - }; - - RegisterAnalysis P1("print-cfg", - "Print CFG of function to 'dot' file"); -}; - - - //===----------------------------------------------------------------------===// // Call Graph Printer //===----------------------------------------------------------------------===// @@ -112,7 +47,7 @@ static std::string getNodeLabel(CallGraphNode *Node, CallGraph *Graph) { if (Node->getFunction()) - return Node->getFunction()->getName(); + return ((Value*)Node->getFunction())->getName(); else return "Indirect call node"; } From lattner at cs.uiuc.edu Wed Oct 22 11:05:06 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Oct 22 11:05:06 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/CFGPrinter.cpp Message-ID: <200310221603.LAA18434@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: CFGPrinter.cpp added (r1.1) --- Log message: Implement the Function::viewCFG* methods, for use in a debugger. Also, the -print-cfg pass now lives here. --- Diffs of the changes: (+144 -0) Index: llvm/lib/Analysis/CFGPrinter.cpp diff -c /dev/null llvm/lib/Analysis/CFGPrinter.cpp:1.1 *** /dev/null Wed Oct 22 11:03:59 2003 --- llvm/lib/Analysis/CFGPrinter.cpp Wed Oct 22 11:03:49 2003 *************** *** 0 **** --- 1,144 ---- + //===- CFGPrinter.cpp - DOT printer for the control flow graph ------------===// + // + // 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 defines a '-print-cfg' analysis pass, which emits the + // cfg..dot file for each function in the program, with a graph of the + // CFG for that function. + // + // The other main feature of this file is that it implements the + // Function::viewCFG method, which is useful for debugging passes which operate + // on the CFG. + // + //===----------------------------------------------------------------------===// + + #include "Support/GraphWriter.h" + #include "llvm/Pass.h" + #include "llvm/Function.h" + #include "llvm/iTerminators.h" + #include "llvm/Support/CFG.h" + #include + #include + + /// CFGOnly flag - This is used to control whether or not the CFG graph printer + /// prints out the contents of basic blocks or not. This is acceptable because + /// this code is only really used for debugging purposes. + /// + static bool CFGOnly = false; + + template<> + struct DOTGraphTraits : public DefaultDOTGraphTraits { + static std::string getGraphName(const Function *F) { + return "CFG for '" + F->getName() + "' function"; + } + + static std::string getNodeLabel(const BasicBlock *Node, + const Function *Graph) { + if (CFGOnly) return Node->getName() + ":"; + + std::ostringstream Out; + Out << *Node; + std::string OutStr = Out.str(); + if (OutStr[0] == '\n') OutStr.erase(OutStr.begin()); + + // Process string output to make it nicer... + for (unsigned i = 0; i != OutStr.length(); ++i) + if (OutStr[i] == '\n') { // Left justify + OutStr[i] = '\\'; + OutStr.insert(OutStr.begin()+i+1, 'l'); + } else if (OutStr[i] == ';') { // Delete comments! + unsigned Idx = OutStr.find('\n', i+1); // Find end of line + OutStr.erase(OutStr.begin()+i, OutStr.begin()+Idx); + --i; + } + + return OutStr; + } + + static std::string getNodeAttributes(const BasicBlock *N) { + return "fontname=Courier"; + } + + static std::string getEdgeSourceLabel(const BasicBlock *Node, + succ_const_iterator I) { + // Label source of conditional branches with "T" or "F" + if (const BranchInst *BI = dyn_cast(Node->getTerminator())) + if (BI->isConditional()) + return (I == succ_begin(Node)) ? "T" : "F"; + return ""; + } + }; + + namespace { + struct CFGPrinter : public FunctionPass { + virtual bool runOnFunction(Function &F) { + std::string Filename = "cfg." + F.getName() + ".dot"; + std::cerr << "Writing '" << Filename << "'..."; + std::ofstream File(Filename.c_str()); + + if (File.good()) + WriteGraph(File, (const Function*)&F); + else + std::cerr << " error opening file for writing!"; + std::cerr << "\n"; + return false; + } + + void print(std::ostream &OS) const {} + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + } + }; + + RegisterAnalysis P1("print-cfg", + "Print CFG of function to 'dot' file"); + }; + + + + + /// viewCFG - This function is meant for use from the debugger. You can just + /// say 'call F->viewCFG()' and a ghostview window should pop up from the + /// program, displaying the CFG of the current function. This depends on there + /// being a 'dot' and 'gv' program in your path. + /// + void Function::viewCFG() const { + std::string Filename = "/tmp/cfg." + getName() + ".dot"; + std::cerr << "Writing '" << Filename << "'... "; + std::ofstream F(Filename.c_str()); + + if (!F.good()) { + std::cerr << " error opening file for writing!\n"; + return; + } + + WriteGraph(F, this); + F.close(); + std::cerr << "\n"; + + std::cerr << "Running 'dot' program... " << std::flush; + if (system(("dot -Tps " + Filename + " > /tmp/cfg.tempgraph.ps").c_str())) { + std::cerr << "Error running dot: 'dot' not in path?\n"; + } else { + std::cerr << "\n"; + system("gv /tmp/cfg.tempgraph.ps"); + } + system(("rm " + Filename + " /tmp/cfg.tempgraph.ps").c_str()); + } + + /// viewCFGOnly - This function is meant for use from the debugger. It works + /// just like viewCFG, but it does not include the contents of basic blocks + /// into the nodes, just the label. If you are only interested in the CFG t + /// his can make the graph smaller. + /// + void Function::viewCFGOnly() const { + CFGOnly = true; + viewCFG(); + CFGOnly = false; + } From lattner at cs.uiuc.edu Wed Oct 22 11:23:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Oct 22 11:23:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/CFGPrinter.cpp Message-ID: <200310221622.LAA19942@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: CFGPrinter.cpp updated: 1.1 -> 1.2 --- Log message: If the basic block has no name, make sure to print the % number of it --- Diffs of the changes: (+7 -1) Index: llvm/lib/Analysis/CFGPrinter.cpp diff -u llvm/lib/Analysis/CFGPrinter.cpp:1.1 llvm/lib/Analysis/CFGPrinter.cpp:1.2 --- llvm/lib/Analysis/CFGPrinter.cpp:1.1 Wed Oct 22 11:03:49 2003 +++ llvm/lib/Analysis/CFGPrinter.cpp Wed Oct 22 11:22:42 2003 @@ -21,6 +21,7 @@ #include "llvm/Pass.h" #include "llvm/Function.h" #include "llvm/iTerminators.h" +#include "llvm/Assembly/Writer.h" #include "llvm/Support/CFG.h" #include #include @@ -39,9 +40,14 @@ static std::string getNodeLabel(const BasicBlock *Node, const Function *Graph) { - if (CFGOnly) return Node->getName() + ":"; + if (CFGOnly && !Node->getName().empty()) return Node->getName() + ":"; std::ostringstream Out; + if (CFGOnly) { + WriteAsOperand(Out, Node, false, true); + return Out.str(); + } + Out << *Node; std::string OutStr = Out.str(); if (OutStr[0] == '\n') OutStr.erase(OutStr.begin()); From lattner at cs.uiuc.edu Wed Oct 22 11:32:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Oct 22 11:32:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/CFGPrinter.cpp Message-ID: <200310221631.LAA20832@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: CFGPrinter.cpp updated: 1.2 -> 1.3 --- Log message: Make sure to print labels on nodes without names --- Diffs of the changes: (+7 -1) Index: llvm/lib/Analysis/CFGPrinter.cpp diff -u llvm/lib/Analysis/CFGPrinter.cpp:1.2 llvm/lib/Analysis/CFGPrinter.cpp:1.3 --- llvm/lib/Analysis/CFGPrinter.cpp:1.2 Wed Oct 22 11:22:42 2003 +++ llvm/lib/Analysis/CFGPrinter.cpp Wed Oct 22 11:30:58 2003 @@ -40,12 +40,18 @@ static std::string getNodeLabel(const BasicBlock *Node, const Function *Graph) { - if (CFGOnly && !Node->getName().empty()) return Node->getName() + ":"; + if (CFGOnly && !Node->getName().empty()) + return Node->getName() + ":"; std::ostringstream Out; if (CFGOnly) { WriteAsOperand(Out, Node, false, true); return Out.str(); + } + + if (Node->getName().empty()) { + WriteAsOperand(Out, Node, false, true); + Out << ":"; } Out << *Node; From lattner at cs.uiuc.edu Wed Oct 22 11:42:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Oct 22 11:42:02 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/LoopInfo.cpp Message-ID: <200310221641.LAA22008@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: LoopInfo.cpp updated: 1.43 -> 1.44 --- Log message: Do not add unreachable code to a natural loop! --- Diffs of the changes: (+4 -1) Index: llvm/lib/Analysis/LoopInfo.cpp diff -u llvm/lib/Analysis/LoopInfo.cpp:1.43 llvm/lib/Analysis/LoopInfo.cpp:1.44 --- llvm/lib/Analysis/LoopInfo.cpp:1.43 Mon Oct 20 14:43:04 2003 +++ llvm/lib/Analysis/LoopInfo.cpp Wed Oct 22 11:41:21 2003 @@ -151,11 +151,14 @@ Loop *L = new Loop(BB); BBMap[BB] = L; + BasicBlock *EntryBlock = &BB->getParent()->getEntryBlock(); + while (!TodoStack.empty()) { // Process all the nodes in the loop BasicBlock *X = TodoStack.back(); TodoStack.pop_back(); - if (!L->contains(X)) { // As of yet unprocessed?? + if (!L->contains(X) && // As of yet unprocessed?? + DS.dominates(EntryBlock, X)) { // X is reachable from entry block? // Check to see if this block already belongs to a loop. If this occurs // then we have a case where a loop that is supposed to be a child of the // current loop was processed before the current loop. When this occurs, From brukman at cs.uiuc.edu Wed Oct 22 12:02:02 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Oct 22 12:02:02 2003 Subject: [llvm-commits] CVS: llvm/docs/HowToSubmitABug.html Message-ID: <200310221701.MAA28399@zion.cs.uiuc.edu> Changes in directory llvm/docs: HowToSubmitABug.html updated: 1.7 -> 1.8 --- Log message: * Changed URL referring to zion to use llvm instead * Close

  • tags --- Diffs of the changes: (+5 -9) Index: llvm/docs/HowToSubmitABug.html diff -u llvm/docs/HowToSubmitABug.html:1.7 llvm/docs/HowToSubmitABug.html:1.8 --- llvm/docs/HowToSubmitABug.html:1.7 Wed Oct 22 10:06:11 2003 +++ llvm/docs/HowToSubmitABug.html Wed Oct 22 12:01:44 2003 @@ -50,21 +50,17 @@ more easily.

    Once you have a reduced test-case, go to - + the LLVM Bug Tracking System, select the catagory in which the bug falls, and fill out the form with the necessary details. The bug description should contain the following information:

      -
    • - All information necessary to reproduce the problem. - -
    • - The reduced test-case that triggers the bug. - -
    • - The location where you obtained LLVM (if not from our CVS repository). +
    • All information necessary to reproduce the problem.
    • +
    • The reduced test-case that triggers the bug.
    • +
    • The location where you obtained LLVM (if not from our CVS + repository).

    From gaeke at cs.uiuc.edu Wed Oct 22 12:27:01 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed Oct 22 12:27:01 2003 Subject: [llvm-commits] CVS: reopt/test/Regression/README.txt Message-ID: <200310221726.MAA21426@gally.cs.uiuc.edu> Changes in directory reopt/test/Regression: README.txt added (r1.1) --- Log message: Add plaintive cry for help :-) --- Diffs of the changes: (+8 -0) Index: reopt/test/Regression/README.txt diff -c /dev/null reopt/test/Regression/README.txt:1.1 *** /dev/null Wed Oct 22 12:26:33 2003 --- reopt/test/Regression/README.txt Wed Oct 22 12:26:22 2003 *************** *** 0 **** --- 1,8 ---- + + Wed Oct 22 12:24:41 CDT 2003 + + This directory contains a bunch of old programs that apparently had something + to do with testing various components of the Reoptimizer. They do not currently + get run or tested by any automated procedure. If you have any idea + what this stuff does, or how to use it, feel free to document it here. + From lattner at cs.uiuc.edu Wed Oct 22 12:28:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Oct 22 12:28:02 2003 Subject: [llvm-commits] CVS: llvm/test/QMTest/llvmdb.py Message-ID: <200310221727.MAA09791@neo.cs.uiuc.edu> Changes in directory llvm/test/QMTest: llvmdb.py updated: 1.8 -> 1.9 --- Log message: Reoptimizer tests are no more --- Diffs of the changes: (+0 -1) Index: llvm/test/QMTest/llvmdb.py diff -u llvm/test/QMTest/llvmdb.py:1.8 llvm/test/QMTest/llvmdb.py:1.9 --- llvm/test/QMTest/llvmdb.py:1.8 Tue Oct 21 09:36:46 2003 +++ llvm/test/QMTest/llvmdb.py Wed Oct 22 12:27:40 2003 @@ -43,7 +43,6 @@ 'Other':'llvm.TestRunner', 'TableGen':'llvm.TestRunner', 'Transforms':'llvm.TestRunner', - 'Reoptimizer':'llvm.TestRunner', 'Verifier':'llvm.VerifierTest'} class llvmdb (qm.test.database.Database): From lattner at cs.uiuc.edu Wed Oct 22 12:34:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Oct 22 12:34:01 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/SingleSource/UnitTests/2003-10-13-SwitchTest.c Message-ID: <200310221733.MAA31050@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/SingleSource/UnitTests: 2003-10-13-SwitchTest.c updated: 1.1 -> 1.2 --- Log message: Fix a stupid warning --- Diffs of the changes: (+1 -1) Index: llvm/test/Programs/SingleSource/UnitTests/2003-10-13-SwitchTest.c diff -u llvm/test/Programs/SingleSource/UnitTests/2003-10-13-SwitchTest.c:1.1 llvm/test/Programs/SingleSource/UnitTests/2003-10-13-SwitchTest.c:1.2 --- llvm/test/Programs/SingleSource/UnitTests/2003-10-13-SwitchTest.c:1.1 Mon Oct 13 15:31:28 2003 +++ llvm/test/Programs/SingleSource/UnitTests/2003-10-13-SwitchTest.c Wed Oct 22 12:33:41 2003 @@ -1,6 +1,6 @@ #include -int main(int argc) { +int main(int argc, const char **argv) { switch (argc) { default: printf("GOOD\n"); From gaeke at cs.uiuc.edu Wed Oct 22 12:52:01 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed Oct 22 12:52:01 2003 Subject: [llvm-commits] CVS: llvm/include/Config/strings.h Message-ID: <200310221751.MAA06627@zion.cs.uiuc.edu> Changes in directory llvm/include/Config: strings.h (r1.3) removed --- Log message: I think this file is not included by anything. --- Diffs of the changes: (+0 -0) From gaeke at cs.uiuc.edu Wed Oct 22 12:54:01 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed Oct 22 12:54:01 2003 Subject: [llvm-commits] CVS: llvm/autoconf/configure.ac Message-ID: <200310221753.MAA06651@zion.cs.uiuc.edu> Changes in directory llvm/autoconf: configure.ac updated: 1.44 -> 1.45 --- Log message: Do not check for strings.h. This is an old, old, old pre-C89 header that absolutely nothing should be using (and it looks like nothing IS using it). --- Diffs of the changes: (+1 -1) Index: llvm/autoconf/configure.ac diff -u llvm/autoconf/configure.ac:1.44 llvm/autoconf/configure.ac:1.45 --- llvm/autoconf/configure.ac:1.44 Thu Oct 16 11:12:04 2003 +++ llvm/autoconf/configure.ac Wed Oct 22 12:52:56 2003 @@ -430,7 +430,7 @@ AC_CHECK_HEADERS(assert.h fcntl.h limits.h sys/time.h unistd.h errno.h signal.h math.h) dnl Check for system specific header files -AC_CHECK_HEADERS(malloc.h strings.h sys/mman.h sys/resource.h) +AC_CHECK_HEADERS(malloc.h sys/mman.h sys/resource.h) dnl Check for header files associated with dlopen and friends AC_CHECK_HEADERS(dlfcn.h link.h) From lattner at cs.uiuc.edu Wed Oct 22 13:10:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Oct 22 13:10:02 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/SingleSource/UnitTests/2003-05-26-Shorts.c Message-ID: <200310221809.NAA06531@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/SingleSource/UnitTests: 2003-05-26-Shorts.c updated: 1.4 -> 1.5 --- Log message: Make code fit in 80 columns --- Diffs of the changes: (+6 -6) Index: llvm/test/Programs/SingleSource/UnitTests/2003-05-26-Shorts.c diff -u llvm/test/Programs/SingleSource/UnitTests/2003-05-26-Shorts.c:1.4 llvm/test/Programs/SingleSource/UnitTests/2003-05-26-Shorts.c:1.5 --- llvm/test/Programs/SingleSource/UnitTests/2003-05-26-Shorts.c:1.4 Thu Jul 10 14:08:43 2003 +++ llvm/test/Programs/SingleSource/UnitTests/2003-05-26-Shorts.c Wed Oct 22 13:09:26 2003 @@ -27,10 +27,10 @@ unsigned short us = (unsigned short) UL; /* 0xb8a3 = 47267 */ short s = (short) UL; /* 0xb8a3 = -18269 */ - unsigned char ub = (unsigned char) UL; /* 0xa3 = 163 */ - signed char b = ( signed char) UL; /* 0xa3 = -93 */ + unsigned char ub = (unsigned char) UL; /* 0xa3 = 163 */ + signed char b = ( signed char) UL; /* 0xa3 = -93 */ - printf(" ui = %u (0x%x)\t\tUL-ui = %lld (0x%llx)\n", ui, ui, UL-ui, UL-ui); + printf(" ui = %u (0x%x)\t\tUL-ui = %lld (0x%llx)\n", ui, ui, UL-ui, UL-ui); printf("ui*ui = %u (0x%x)\t UL/ui = %lld (0x%llx)\n\n", (unsigned int) ui*ui, (unsigned int) ui*ui, UL/ui, UL/ui); @@ -38,7 +38,7 @@ printf(" i* i = %d (0x%x)\tL/ i = %lld (0x%llx)\n\n", (int) i*i, (int) i*i, L/i, L/i); - printf("us = %u (0x%x)\t\tUL-us = %lld (0x%llx)\n", us, us, UL-us, UL-us); + printf("us = %u (0x%x)\t\tUL-us = %lld (0x%llx)\n", us, us, UL-us, UL-us); printf("us*us = %u (0x%x)\t UL/us = %lld (0x%llx)\n\n", (unsigned short) us*us, (unsigned short) us*us, UL/us, UL/us); @@ -46,11 +46,11 @@ printf(" s* s = %d (0x%x)\tL/ s = %lld (0x%llx)\n\n", (short) s*s, (short) s*s, L/s, L/s); - printf("ub = %u (0x%x)\t\tUL-ub = %lld (0x%llx)\n", ub, ub, UL-ub, UL-ub); + printf("ub = %u (0x%x)\t\tUL-ub = %lld (0x%llx)\n", ub, ub, UL-ub, UL-ub); printf("ub*ub = %u (0x%x)\t\tUL/ub = %lld (0x%llx)\n\n", (unsigned char) ub*ub, (unsigned char) ub*ub, UL/ub, UL/ub); - printf(" b = %d (0x%x)\t\tL-b = %lld (0x%llx)\n", b, b, L-b, L-b); + printf(" b = %d (0x%x)\t\tL-b = %lld (0x%llx)\n", b, b, L-b, L-b); printf(" b* b = %d (0x%x)\t\t\tL/b = %lld (0x%llx)\n\n", (signed char) b*b, (signed char) b*b, L/b, L/b); From gaeke at cs.uiuc.edu Wed Oct 22 13:20:01 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed Oct 22 13:20:01 2003 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200310221819.NAA11314@zion.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.10 -> 1.11 --- Log message: Clarify our testing experience. --- Diffs of the changes: (+2 -1) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.10 llvm/docs/ReleaseNotes.html:1.11 --- llvm/docs/ReleaseNotes.html:1.10 Mon Oct 20 14:05:03 2003 +++ llvm/docs/ReleaseNotes.html Wed Oct 22 13:19:08 2003 @@ -113,7 +113,8 @@

      -LLVM has only been extensively tested on ia32-linux and sparc-solaris machines. +LLVM has only been extensively tested on Intel and AMD machines running Red +Hat Linux, and Sun UltraSPARC workstations running Solaris 8. The core LLVM infrastructure uses "autoconf" for portability, so hopefully we work on more platforms than that. However, it is extremely likely that we missed something. We welcome portability patches and error messages.

      From lattner at cs.uiuc.edu Wed Oct 22 13:54:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Oct 22 13:54:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/CallGraph.cpp Message-ID: <200310221853.NAA02662@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: CallGraph.cpp updated: 1.27 -> 1.28 --- Log message: This is a disgusting hack that improves code substantially, by making callgraphSCC passes more effective. --- Diffs of the changes: (+122 -2) Index: llvm/lib/Analysis/IPA/CallGraph.cpp diff -u llvm/lib/Analysis/IPA/CallGraph.cpp:1.27 llvm/lib/Analysis/IPA/CallGraph.cpp:1.28 --- llvm/lib/Analysis/IPA/CallGraph.cpp:1.27 Mon Oct 20 14:43:07 2003 +++ llvm/lib/Analysis/IPA/CallGraph.cpp Wed Oct 22 13:53:31 2003 @@ -50,10 +50,129 @@ #include "llvm/iOther.h" #include "llvm/iTerminators.h" #include "Support/STLExtras.h" -#include static RegisterAnalysis X("callgraph", "Call Graph Construction"); +static const char * const KnownExternalFunctions[] = { + // Low-level system calls + "open", + "read", + "write", + "writev", + "lseek", + "poll", + "ioctl", + + // Low-level stdc library functions + "abort", + "getenv", + "putenv", + + // Standard IO functions + "printf", + "sprintf", + "fopen", + "freopen", + "fclose", + "fwrite", + "puts", + "fputs", + "getc", + "ungetc", + "putc", + "putchar", + "fread", + "fileno", + "ftell", + "fflush", + "fseek", + "fileno", + "ferror", + "feof", + "fdopen", + "__fxstat", + "setbuf", + "setbuffer", + "etlinebuf", + "setvbuf", + + // Memory functions + "malloc", + "free", + "realloc", + "calloc", + "memalign", + + // String functions + "atoi", + "memmove", + "memset", + "memchr", + "memcmp", + "strchr", + "strncpy", + "strncmp", + "strcmp", + "__strcoll_l", + "__strxfrm_l", + "__strftime_l", + "__strtol_l", + "__strtoul_l", + "__strtoll_l", + "__strtoull_l", + "__strtof_l", + "__strtod_l", + "__strtold_l", + + // Locale functions + "__uselocale", + "__newlocale", + "__freelocale", + "__duplocale", + "__nl_langinfo_l", + + // gettext functions used by libstdc++ + "gettext", + "dgettext", + "dcgettext", + "textdomain", + "bindtextdomain", + + // Random stuff + "__assert_fail", + "__errno_location", +}; + + +/// ExternalFunctionDoesntCallIntoProgram - This hack is used to indicate to the +/// call graph that the specified external function is _KNOWN_ to not call back +/// into the program. This is important, because otherwise functions which call +/// "printf" for example, end up in a great big SCC that goes from the function +/// through main. +/// +static bool ExternalFunctionDoesntCallIntoProgram(const std::string &Name) { + static std::vector Funcs; + + // First time this is called? + if (Funcs.empty()) { + // Add a whole bunch of functions which are often used... + Funcs.insert(Funcs.end(), KnownExternalFunctions, + KnownExternalFunctions+ + sizeof(KnownExternalFunctions)/sizeof(KnownExternalFunctions[0])); + // Sort the list for efficient access + std::sort(Funcs.begin(), Funcs.end()); + } + + // Binary search for the function name... + std::vector::iterator I = + std::lower_bound(Funcs.begin(), Funcs.end(), Name); + + // Found it? + return I != Funcs.end() && *I == Name; +} + + + // getNodeFor - Return the node for the specified function or create one if it // does not already exist. // @@ -86,7 +205,8 @@ // If this function is not defined in this translation unit, it could call // anything. - if (F->isExternal()) + if (F->isExternal() && !F->getIntrinsicID() && + !ExternalFunctionDoesntCallIntoProgram(F->getName())) Node->addCalledFunction(ExternalNode); // Loop over all of the users of the function... looking for callers... From gaeke at cs.uiuc.edu Wed Oct 22 15:24:01 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed Oct 22 15:24:01 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp Message-ID: <200310222023.PAA32416@gally.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/RegAlloc: PhyRegAlloc.cpp updated: 1.119 -> 1.120 --- Log message: Doxygenify method comments. Try to improve method comments a little. Get rid of some excess whitespace; put braces on previous line when possible. Add stub for method to verify the work of saveState(). --- Diffs of the changes: (+154 -207) Index: llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp diff -u llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.119 llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.120 --- llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.119 Mon Oct 20 14:43:16 2003 +++ llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp Wed Oct 22 15:22:53 2003 @@ -73,18 +73,13 @@ } - -//---------------------------------------------------------------------------- -// This method initially creates interference graphs (one in each reg class) -// and IGNodeList (one in each IG). The actual nodes will be pushed later. -//---------------------------------------------------------------------------- +/// Initialize interference graphs (one in each reg class) and IGNodeLists +/// (one in each IG). The actual nodes will be pushed later. +/// void PhyRegAlloc::createIGNodeListsAndIGs() { if (DEBUG_RA >= RA_DEBUG_LiveRanges) std::cerr << "Creating LR lists ...\n"; - // hash map iterator LiveRangeMapType::const_iterator HMI = LRI->getLiveRangeMap()->begin(); - - // hash map end LiveRangeMapType::const_iterator HMIEnd = LRI->getLiveRangeMap()->end(); for (; HMI != HMIEnd ; ++HMI ) { @@ -114,15 +109,12 @@ } -//---------------------------------------------------------------------------- -// This method will add all interferences at for a given instruction. -// Interference occurs only if the LR of Def (Inst or Arg) is of the same reg -// class as that of live var. The live var passed to this function is the -// LVset AFTER the instruction -//---------------------------------------------------------------------------- - -void PhyRegAlloc::addInterference(const Value *Def, - const ValueSet *LVSet, +/// Add all interferences for a given instruction. Interference occurs only +/// if the LR of Def (Inst or Arg) is of the same reg class as that of live +/// var. The live var passed to this function is the LVset AFTER the +/// instruction. +/// +void PhyRegAlloc::addInterference(const Value *Def, const ValueSet *LVSet, bool isCallInst) { ValueSet::const_iterator LIt = LVSet->begin(); @@ -153,13 +145,11 @@ } -//---------------------------------------------------------------------------- -// For a call instruction, this method sets the CallInterference flag in -// the LR of each variable live int the Live Variable Set live after the -// call instruction (except the return value of the call instruction - since -// the return value does not interfere with that call itself). -//---------------------------------------------------------------------------- - +/// For a call instruction, this method sets the CallInterference flag in +/// the LR of each variable live in the Live Variable Set live after the +/// call instruction (except the return value of the call instruction - since +/// the return value does not interfere with that call itself). +/// void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst, const ValueSet *LVSetAft) { if (DEBUG_RA >= RA_DEBUG_Interference) @@ -211,14 +201,11 @@ } -//---------------------------------------------------------------------------- -// This method will walk thru code and create interferences in the IG of -// each RegClass. Also, this method calculates the spill cost of each -// Live Range (it is done in this method to save another pass over the code). -//---------------------------------------------------------------------------- - -void PhyRegAlloc::buildInterferenceGraphs() -{ +/// Create interferences in the IG of each RegClass, and calculate the spill +/// cost of each Live Range (it is done in this method to save another pass +/// over the code). +/// +void PhyRegAlloc::buildInterferenceGraphs() { if (DEBUG_RA >= RA_DEBUG_Interference) std::cerr << "Creating interference graphs ...\n"; @@ -242,7 +229,7 @@ const ValueSet &LVSetAI = LVI->getLiveVarSetAfterMInst(MInst, BB); bool isCallInst = TM.getInstrInfo().isCall(MInst->getOpCode()); - if (isCallInst ) { + if (isCallInst) { // set the isCallInterference flag of each live range which extends // across this call instruction. This information is used by graph // coloring algorithm to avoid allocating volatile colors to live ranges @@ -261,7 +248,10 @@ if (LR) LR->addSpillCost(BBLoopDepthCost); } - // if there are multiple defs in this instruction e.g. in SETX + // Mark all operands of pseudo-instructions as interfering with one + // another. This must be done because pseudo-instructions may be + // expanded to multiple instructions by the assembler, so all the + // operands must get distinct registers. if (TM.getInstrInfo().isPseudoInstr(MInst->getOpCode())) addInterf4PseudoInstr(MInst); @@ -285,13 +275,9 @@ } -//-------------------------------------------------------------------------- -// Pseudo-instructions may be expanded to multiple instructions by the -// assembler. Consequently, all the operands must get distinct registers. -// Therefore, we mark all operands of a pseudo-instruction as interfering -// with one another. -//-------------------------------------------------------------------------- - +/// Mark all operands of the given MachineInstr as interfering with one +/// another. +/// void PhyRegAlloc::addInterf4PseudoInstr(const MachineInstr *MInst) { bool setInterf = false; @@ -325,10 +311,8 @@ } -//---------------------------------------------------------------------------- -// This method adds interferences for incoming arguments to a function. -//---------------------------------------------------------------------------- - +/// Add interferences for incoming arguments to a function. +/// void PhyRegAlloc::addInterferencesForArgs() { // get the InSet of root BB const ValueSet &InSet = LVI->getInSetOfBB(&Fn->front()); @@ -338,68 +322,51 @@ addInterference(AI, &InSet, false); if (DEBUG_RA >= RA_DEBUG_Interference) - std::cerr << " - %% adding interference for argument " << RAV(AI) << "\n"; + std::cerr << " - %% adding interference for argument " << RAV(AI) << "\n"; } } -//---------------------------------------------------------------------------- -// This method is called after register allocation is complete to set the -// allocated registers in the machine code. This code will add register numbers -// to MachineOperands that contain a Value. Also it calls target specific -// methods to produce caller saving instructions. At the end, it adds all -// additional instructions produced by the register allocator to the -// instruction stream. -//---------------------------------------------------------------------------- - -//----------------------------- -// Utility functions used below -//----------------------------- -inline void -InsertBefore(MachineInstr* newMI, - MachineBasicBlock& MBB, - MachineBasicBlock::iterator& MII) -{ +/// The following are utility functions used solely by updateMachineCode and +/// the functions that it calls. They should probably be folded back into +/// updateMachineCode at some point. +/// + +// used by: updateMachineCode (1 time), PrependInstructions (1 time) +inline void InsertBefore(MachineInstr* newMI, MachineBasicBlock& MBB, + MachineBasicBlock::iterator& MII) { MII = MBB.insert(MII, newMI); ++MII; } -inline void -InsertAfter(MachineInstr* newMI, - MachineBasicBlock& MBB, - MachineBasicBlock::iterator& MII) -{ +// used by: AppendInstructions (1 time) +inline void InsertAfter(MachineInstr* newMI, MachineBasicBlock& MBB, + MachineBasicBlock::iterator& MII) { ++MII; // insert before the next instruction MII = MBB.insert(MII, newMI); } -inline void -DeleteInstruction(MachineBasicBlock& MBB, - MachineBasicBlock::iterator& MII) -{ +// used by: updateMachineCode (1 time) +inline void DeleteInstruction(MachineBasicBlock& MBB, + MachineBasicBlock::iterator& MII) { MII = MBB.erase(MII); } -inline void -SubstituteInPlace(MachineInstr* newMI, - MachineBasicBlock& MBB, - MachineBasicBlock::iterator MII) -{ +// used by: updateMachineCode (1 time) +inline void SubstituteInPlace(MachineInstr* newMI, MachineBasicBlock& MBB, + MachineBasicBlock::iterator MII) { *MII = newMI; } -inline void -PrependInstructions(std::vector &IBef, - MachineBasicBlock& MBB, - MachineBasicBlock::iterator& MII, - const std::string& msg) -{ - if (!IBef.empty()) - { +// used by: updateMachineCode (2 times) +inline void PrependInstructions(std::vector &IBef, + MachineBasicBlock& MBB, + MachineBasicBlock::iterator& MII, + const std::string& msg) { + if (!IBef.empty()) { MachineInstr* OrigMI = *MII; std::vector::iterator AdIt; - for (AdIt = IBef.begin(); AdIt != IBef.end() ; ++AdIt) - { + for (AdIt = IBef.begin(); AdIt != IBef.end() ; ++AdIt) { if (DEBUG_RA) { if (OrigMI) std::cerr << "For MInst:\n " << *OrigMI; std::cerr << msg << "PREPENDed instr:\n " << **AdIt << "\n"; @@ -409,18 +376,15 @@ } } -inline void -AppendInstructions(std::vector &IAft, - MachineBasicBlock& MBB, - MachineBasicBlock::iterator& MII, - const std::string& msg) -{ - if (!IAft.empty()) - { +// used by: updateMachineCode (1 time) +inline void AppendInstructions(std::vector &IAft, + MachineBasicBlock& MBB, + MachineBasicBlock::iterator& MII, + const std::string& msg) { + if (!IAft.empty()) { MachineInstr* OrigMI = *MII; std::vector::iterator AdIt; - for ( AdIt = IAft.begin(); AdIt != IAft.end() ; ++AdIt ) - { + for ( AdIt = IAft.begin(); AdIt != IAft.end() ; ++AdIt ) { if (DEBUG_RA) { if (OrigMI) std::cerr << "For MInst:\n " << *OrigMI; std::cerr << msg << "APPENDed instr:\n " << **AdIt << "\n"; @@ -430,6 +394,10 @@ } } +/// Set the registers for operands in the given MachineInstr, if a register was +/// successfully allocated. Return true if any of its operands has been marked +/// for spill. +/// bool PhyRegAlloc::markAllocatedRegs(MachineInstr* MInst) { bool instrNeedsSpills = false; @@ -437,12 +405,10 @@ // First, set the registers for operands in the machine instruction // if a register was successfully allocated. Do this first because we // will need to know which registers are already used by this instr'n. - for (unsigned OpNum=0; OpNum < MInst->getNumOperands(); ++OpNum) - { + for (unsigned OpNum=0; OpNum < MInst->getNumOperands(); ++OpNum) { MachineOperand& Op = MInst->getOperand(OpNum); if (Op.getType() == MachineOperand::MO_VirtualRegister || - Op.getType() == MachineOperand::MO_CCRegister) - { + Op.getType() == MachineOperand::MO_CCRegister) { const Value *const Val = Op.getVRegValue(); if (const LiveRange* LR = LRI->getLiveRangeForValue(Val)) { // Remember if any operand needs spilling @@ -460,9 +426,13 @@ return instrNeedsSpills; } +/// Mark allocated registers (using markAllocatedRegs()) on the instruction +/// that MII points to. Then, if it's a call instruction, insert caller-saving +/// code before and after it. Finally, insert spill code before and after it, +/// using insertCode4SpilledLR(). +/// void PhyRegAlloc::updateInstruction(MachineBasicBlock::iterator& MII, - MachineBasicBlock &MBB) -{ + MachineBasicBlock &MBB) { MachineInstr* MInst = *MII; unsigned Opcode = MInst->getOpCode(); @@ -493,12 +463,10 @@ // registers. This must be done even for call return instructions // since those are not handled by the special code above. if (instrNeedsSpills) - for (unsigned OpNum=0; OpNum < MInst->getNumOperands(); ++OpNum) - { + for (unsigned OpNum=0; OpNum < MInst->getNumOperands(); ++OpNum) { MachineOperand& Op = MInst->getOperand(OpNum); if (Op.getType() == MachineOperand::MO_VirtualRegister || - Op.getType() == MachineOperand::MO_CCRegister) - { + Op.getType() == MachineOperand::MO_CCRegister) { const Value* Val = Op.getVRegValue(); if (const LiveRange *LR = LRI->getLiveRangeForValue(Val)) if (LR->isMarkedForSpill()) @@ -507,6 +475,10 @@ } // for each operand } +/// Iterate over all the MachineBasicBlocks in the current function and set +/// the allocated registers for each instruction (using updateInstruction()), +/// after register allocation is complete. Then move code out of delay slots. +/// void PhyRegAlloc::updateMachineCode() { // Insert any instructions needed at method entry @@ -519,7 +491,6 @@ for (MachineFunction::iterator BBI = MF->begin(), BBE = MF->end(); BBI != BBE; ++BBI) { - MachineBasicBlock &MBB = *BBI; // Iterate over all machine instructions in BB and mark operands with @@ -546,8 +517,7 @@ for (MachineBasicBlock::iterator MII = MBB.begin(); MII != MBB.end(); ++MII) if (unsigned delaySlots = - TM.getInstrInfo().getNumDelaySlots((*MII)->getOpCode())) - { + TM.getInstrInfo().getNumDelaySlots((*MII)->getOpCode())) { MachineInstr *MInst = *MII, *DelaySlotMI = *(MII+1); // Check the 2 conditions above: @@ -562,8 +532,7 @@ (AddedInstrMap[DelaySlotMI].InstrnsBefore.size() > 0 || AddedInstrMap[DelaySlotMI].InstrnsAfter.size() > 0)); - if (cond1 || cond2) - { + if (cond1 || cond2) { assert((MInst->getOpCodeFlags() & AnnulFlag) == 0 && "FIXME: Moving an annulled delay slot instruction!"); assert(delaySlots==1 && @@ -646,15 +615,13 @@ } -//---------------------------------------------------------------------------- -// This method inserts spill code for AN operand whose LR was spilled. -// This method may be called several times for a single machine instruction -// if it contains many spilled operands. Each time it is called, it finds -// a register which is not live at that instruction and also which is not -// used by other spilled operands of the same instruction. Then it uses -// this register temporarily to accommodate the spilled value. -//---------------------------------------------------------------------------- - +/// Insert spill code for AN operand whose LR was spilled. May be called +/// repeatedly for a single MachineInstr if it has many spilled operands. On +/// each call, it finds a register which is not live at that instruction and +/// also which is not used by other spilled operands of the same +/// instruction. Then it uses this register temporarily to accommodate the +/// spilled value. +/// void PhyRegAlloc::insertCode4SpilledLR(const LiveRange *LR, MachineBasicBlock::iterator& MII, MachineBasicBlock &MBB, @@ -690,7 +657,7 @@ } #endif - MF->getInfo()->pushTempValue(MRI.getSpilledRegSize(RegType) ); + MF->getInfo()->pushTempValue(MRI.getSpilledRegSize(RegType)); std::vector MIBef, MIAft; std::vector AdIMid; @@ -716,8 +683,7 @@ // for the copy and not used across MInst. int scratchRegType = -1; int scratchReg = -1; - if (MRI.regTypeNeedsScratchReg(RegType, scratchRegType)) - { + if (MRI.regTypeNeedsScratchReg(RegType, scratchRegType)) { scratchReg = getUsableUniRegAtMI(scratchRegType, &LVSetBef, MInst, MIBef, MIAft); assert(scratchReg != MRI.getInvalidRegNum()); @@ -761,23 +727,15 @@ } -//---------------------------------------------------------------------------- -// This method inserts caller saving/restoring instructions before/after -// a call machine instruction. The caller saving/restoring instructions are -// inserted like: -// ** caller saving instructions -// other instructions inserted for the call by ColorCallArg -// CALL instruction -// other instructions inserted for the call ColorCallArg -// ** caller restoring instructions -//---------------------------------------------------------------------------- - +/// Insert caller saving/restoring instructions before/after a call machine +/// instruction (before or after any other instructions that were inserted for +/// the call). +/// void PhyRegAlloc::insertCallerSavingCode(std::vector &instrnsBefore, std::vector &instrnsAfter, MachineInstr *CallMI, - const BasicBlock *BB) -{ + const BasicBlock *BB) { assert(TM.getInstrInfo().isCall(CallMI->getOpCode())); // hash set to record which registers were saved/restored @@ -827,8 +785,8 @@ // LR can be null if it is a const since a const // doesn't have a dominating def - see Assumptions above - if( LR ) { - if(! LR->isMarkedForSpill()) { + if (LR) { + if (! LR->isMarkedForSpill()) { assert(LR->hasColor() && "LR is neither spilled nor colored?"); unsigned RCID = LR->getRegClassID(); unsigned Color = LR->getColor(); @@ -933,15 +891,11 @@ } -//---------------------------------------------------------------------------- -// We can use the following method to get a temporary register to be used -// BEFORE any given machine instruction. If there is a register available, -// this method will simply return that register and set MIBef = MIAft = NULL. -// Otherwise, it will return a register and MIAft and MIBef will contain -// two instructions used to free up this returned register. -// Returned register number is the UNIFIED register number -//---------------------------------------------------------------------------- - +/// Returns the unified register number of a temporary register to be used +/// BEFORE MInst. If no register is available, it will pick one and modify +/// MIBef and MIAft to contain instructions used to free up this returned +/// register. +/// int PhyRegAlloc::getUsableUniRegAtMI(const int RegType, const ValueSet *LVSetBef, MachineInstr *MInst, @@ -949,7 +903,7 @@ std::vector& MIAft) { RegClass* RC = getRegClassByID(MRI.getRegClassIDOfRegType(RegType)); - int RegU = getUnusedUniRegAtMI(RC, RegType, MInst, LVSetBef); + int RegU = getUnusedUniRegAtMI(RC, RegType, MInst, LVSetBef); if (RegU == -1) { // we couldn't find an unused register. Generate code to free up a reg by @@ -961,8 +915,7 @@ // Check if we need a scratch register to copy this register to memory. int scratchRegType = -1; - if (MRI.regTypeNeedsScratchReg(RegType, scratchRegType)) - { + if (MRI.regTypeNeedsScratchReg(RegType, scratchRegType)) { int scratchReg = getUsableUniRegAtMI(scratchRegType, LVSetBef, MInst, MIBef, MIAft); assert(scratchReg != MRI.getInvalidRegNum()); @@ -974,29 +927,23 @@ ScratchRegsUsed.insert(std::make_pair(MInst, scratchReg)); MRI.cpReg2RegMI(MIBef, RegU, scratchReg, RegType); MRI.cpReg2RegMI(MIAft, scratchReg, RegU, RegType); - } - else - { // the register can be copied directly to/from memory so do it. + } else { // the register can be copied directly to/from memory so do it. MRI.cpReg2MemMI(MIBef, RegU, MRI.getFramePointer(), TmpOff, RegType); MRI.cpMem2RegMI(MIAft, MRI.getFramePointer(), TmpOff, RegU, RegType); - } + } } return RegU; } -//---------------------------------------------------------------------------- -// This method is called to get a new unused register that can be used -// to accommodate a temporary value. This method may be called several times -// for a single machine instruction. Each time it is called, it finds a -// register which is not live at that instruction and also which is not used -// by other spilled operands of the same instruction. Return register number -// is relative to the register class, NOT the unified number. -//---------------------------------------------------------------------------- - -int PhyRegAlloc::getUnusedUniRegAtMI(RegClass *RC, - const int RegType, +/// Returns the register-class register number of a new unused register that +/// can be used to accommodate a temporary value. May be called repeatedly +/// for a single MachineInstr. On each call, it finds a register which is not +/// live at that instruction and which is not used by any spilled operands of +/// that instruction. +/// +int PhyRegAlloc::getUnusedUniRegAtMI(RegClass *RC, const int RegType, const MachineInstr *MInst, const ValueSet* LVSetBef) { RC->clearColorsUsed(); // Reset array @@ -1033,11 +980,9 @@ } -//---------------------------------------------------------------------------- -// Get any other register in a register class, other than what is used -// by operands of a machine instruction. Returns the unified reg number. -//---------------------------------------------------------------------------- - +/// Return the unified register number of a register in class RC which is not +/// used by any operands of MInst. +/// int PhyRegAlloc::getUniRegNotUsedByThisInst(RegClass *RC, const int RegType, const MachineInstr *MInst) { @@ -1054,12 +999,10 @@ } -//---------------------------------------------------------------------------- -// This method modifies the IsColorUsedArr of the register class passed to it. -// It sets the bits corresponding to the registers used by this machine -// instructions. Both explicit and implicit operands are set. -//---------------------------------------------------------------------------- - +/// Modify the IsColorUsedArr of register class RC, by setting the bits +/// corresponding to register RegNo. This is a helper method of +/// setRelRegsUsedByThisInst(). +/// static void markRegisterUsed(int RegNo, RegClass *RC, int RegType, const TargetRegInfo &TRI) { unsigned classId = 0; @@ -1069,13 +1012,13 @@ } void PhyRegAlloc::setRelRegsUsedByThisInst(RegClass *RC, int RegType, - const MachineInstr *MI) -{ + const MachineInstr *MI) { assert(OperandsColoredMap[MI] == true && "Illegal to call setRelRegsUsedByThisInst() until colored operands " "are marked for an instruction."); - // Add the registers already marked as used by the instruction. + // Add the registers already marked as used by the instruction. Both + // explicit and implicit operands are set. for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) if (MI->getOperand(i).hasAllocatedReg()) markRegisterUsed(MI->getOperand(i).getAllocatedRegNum(), RC, RegType,MRI); @@ -1103,13 +1046,11 @@ } -//---------------------------------------------------------------------------- -// If there are delay slots for an instruction, the instructions -// added after it must really go after the delayed instruction(s). -// So, we move the InstrAfter of that instruction to the -// corresponding delayed instruction using the following method. -//---------------------------------------------------------------------------- - +/// If there are delay slots for an instruction, the instructions added after +/// it must really go after the delayed instruction(s). So, we Move the +/// InstrAfter of that instruction to the corresponding delayed instruction +/// using the following method. +/// void PhyRegAlloc::move2DelayedInstr(const MachineInstr *OrigMI, const MachineInstr *DelayedMI) { @@ -1141,13 +1082,11 @@ } -//---------------------------------------------------------------------------- -// This method determines whether the suggested color of each live range -// is really usable, and then calls its setSuggestedColorUsable() method to -// record the answer. A suggested color is NOT usable when the suggested color -// is volatile AND when there are call interferences. -//---------------------------------------------------------------------------- - +/// Determine whether the suggested color of each live range is really usable, +/// and then call its setSuggestedColorUsable() method to record the answer. A +/// suggested color is NOT usable when the suggested color is volatile AND +/// when there are call interferences. +/// void PhyRegAlloc::markUnusableSugColors() { LiveRangeMapType::const_iterator HMI = (LRI->getLiveRangeMap())->begin(); @@ -1165,13 +1104,10 @@ } -//---------------------------------------------------------------------------- -// The following method will set the stack offsets of the live ranges that -// are decided to be spilled. This must be called just after coloring the -// LRs using the graph coloring algo. For each live range that is spilled, -// this method allocate a new spill position on the stack. -//---------------------------------------------------------------------------- - +/// For each live range that is spilled, allocates a new spill position on the +/// stack, and set the stack offsets of the live range that will be spilled to +/// that position. This must be called just after coloring the LRs. +/// void PhyRegAlloc::allocateStackSpace4SpilledLRs() { if (DEBUG_RA) std::cerr << "\nSetting LR stack offsets for spills...\n"; @@ -1235,8 +1171,11 @@ }; } -void PhyRegAlloc::saveState () -{ +/// Save the global register allocation decisions made by the register +/// allocator so that they can be accessed later (sort of like "poor man's +/// debug info"). +/// +void PhyRegAlloc::saveState () { std::vector state; unsigned Insn = 0; LiveRangeMapType::const_iterator HMIEnd = LRI->getLiveRangeMap ()->end (); @@ -1284,6 +1223,12 @@ FnAllocState[Fn] = S; } +/// Check the saved state filled in by saveState(), and abort if it looks +/// wrong. Only used when debugging. +/// +void PhyRegAlloc::verifySavedState () { + /// not yet implemented +} bool PhyRegAlloc::doFinalization (Module &M) { if (!SaveRegAllocState) @@ -1332,10 +1277,9 @@ } -//---------------------------------------------------------------------------- -// The entry point to Register Allocation -//---------------------------------------------------------------------------- - +/// Allocate registers for the machine code previously generated for F using +/// the graph-coloring algorithm. +/// bool PhyRegAlloc::runOnFunction (Function &F) { if (DEBUG_RA) std::cerr << "\n********* Function "<< F.getName () << " ***********\n"; @@ -1406,6 +1350,9 @@ // Save register allocation state for this function in a Constant. if (SaveRegAllocState) saveState(); + if (DEBUG_RA) { // Check our work. + verifySavedState (); + } // Now update the machine code with register names and add any // additional code inserted by the register allocator to the instruction From gaeke at cs.uiuc.edu Wed Oct 22 15:24:13 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed Oct 22 15:24:13 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.h Message-ID: <200310222023.PAA32399@gally.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/RegAlloc: PhyRegAlloc.h updated: 1.55 -> 1.56 --- Log message: Add prototype for verifySavedState(). --- Diffs of the changes: (+1 -0) Index: llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.h diff -u llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.h:1.55 llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.h:1.56 --- llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.h:1.55 Tue Oct 21 10:17:13 2003 +++ llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.h Wed Oct 22 15:23:13 2003 @@ -121,6 +121,7 @@ void createIGNodeListsAndIGs(); void buildInterferenceGraphs(); void saveState(); + void verifySavedState(); void setCallInterferences(const MachineInstr *MI, const ValueSet *LVSetAft); From gaeke at cs.uiuc.edu Wed Oct 22 15:45:01 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed Oct 22 15:45:01 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.h Message-ID: <200310222044.PAA26504@trinity.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/RegAlloc: PhyRegAlloc.h updated: 1.56 -> 1.57 --- Log message: Change the type of FnAllocState. --- Diffs of the changes: (+1 -1) Index: llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.h diff -u llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.h:1.56 llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.h:1.57 --- llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.h:1.56 Wed Oct 22 15:23:13 2003 +++ llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.h Wed Oct 22 15:44:29 2003 @@ -85,7 +85,7 @@ AddedInstrns AddedInstrAtEntry; // to store instrns added at entry const LoopInfo *LoopDepthCalc; // to calculate loop depths - std::map FnAllocState; + std::map > FnAllocState; PhyRegAlloc(const PhyRegAlloc&); // DO NOT IMPLEMENT void operator=(const PhyRegAlloc&); // DO NOT IMPLEMENT From gaeke at cs.uiuc.edu Wed Oct 22 15:45:12 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed Oct 22 15:45:12 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp Message-ID: <200310222044.PAA26488@trinity.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/RegAlloc: PhyRegAlloc.cpp updated: 1.120 -> 1.121 --- Log message: Don't worry about converting each function's reg. alloc. state into One Big Constant early on, because we can do it in doFinalization. Tighten up a comment. --- Diffs of the changes: (+21 -20) Index: llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp diff -u llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.120 llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.121 --- llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.120 Wed Oct 22 15:22:53 2003 +++ llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp Wed Oct 22 15:44:23 2003 @@ -1176,7 +1176,7 @@ /// debug info"). /// void PhyRegAlloc::saveState () { - std::vector state; + std::vector &state = FnAllocState[Fn]; unsigned Insn = 0; LiveRangeMapType::const_iterator HMIEnd = LRI->getLiveRangeMap ()->end (); for (const_inst_iterator II=inst_begin (Fn), IE=inst_end (Fn); II != IE; ++II) @@ -1207,20 +1207,6 @@ state.push_back (AllocInfo (Insn, i, AllocState, Placement).toConstant ()); } - // Convert state into an LLVM ConstantArray, and put it in a - // ConstantStruct (named S) along with its size. - unsigned Size = state.size (); - ArrayType *AT = ArrayType::get (AllocInfo::getConstantType (), Size); - std::vector TV; - TV.push_back (Type::UIntTy); - TV.push_back (AT); - StructType *ST = StructType::get (TV); - std::vector CV; - CV.push_back (ConstantUInt::get (Type::UIntTy, Size)); - CV.push_back (ConstantArray::get (AT, state)); - Constant *S = ConstantStruct::get (ST, CV); - // Save S in the map containing register allocator state for this module. - FnAllocState[Fn] = S; } /// Check the saved state filled in by saveState(), and abort if it looks @@ -1248,10 +1234,26 @@ if (FnAllocState.find (F) == FnAllocState.end ()) { allstate.push_back (ConstantPointerNull::get (PT)); } else { + std::vector &state = FnAllocState[F]; + + // Convert state into an LLVM ConstantArray, and put it in a + // ConstantStruct (named S) along with its size. + unsigned Size = state.size (); + ArrayType *AT = ArrayType::get (AllocInfo::getConstantType (), Size); + std::vector TV; + TV.push_back (Type::UIntTy); + TV.push_back (AT); + StructType *ST = StructType::get (TV); + std::vector CV; + CV.push_back (ConstantUInt::get (Type::UIntTy, Size)); + CV.push_back (ConstantArray::get (AT, state)); + Constant *S = ConstantStruct::get (ST, CV); + GlobalVariable *GV = - new GlobalVariable (FnAllocState[F]->getType (), true, - GlobalValue::InternalLinkage, FnAllocState[F], + new GlobalVariable (ST, true, + GlobalValue::InternalLinkage, S, F->getName () + ".regAllocState", &M); + // Have: { uint, [Size x { uint, uint, uint, int }] } * // Cast it to: { uint, [0 x { uint, uint, uint, int }] } * Constant *CE = ConstantExpr::getCast (ConstantPointerRef::get (GV), PT); @@ -1354,9 +1356,8 @@ verifySavedState (); } - // Now update the machine code with register names and add any - // additional code inserted by the register allocator to the instruction - // stream + // Now update the machine code with register names and add any additional + // code inserted by the register allocator to the instruction stream. updateMachineCode(); if (DEBUG_RA) { From criswell at cs.uiuc.edu Wed Oct 22 16:53:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Wed Oct 22 16:53:01 2003 Subject: [llvm-commits] CVS: llvm/test/QMTest/expectations.qmr Message-ID: <200310222152.QAA26150@choi.cs.uiuc.edu> Changes in directory llvm/test/QMTest: expectations.qmr updated: 1.2 -> 1.3 --- Log message: Updated for current list of QMTest failures on x86 and Sparc. --- Diffs of the changes: (+1 -1) Index: llvm/test/QMTest/expectations.qmr diff -u llvm/test/QMTest/expectations.qmr:1.2 llvm/test/QMTest/expectations.qmr:1.3 --- llvm/test/QMTest/expectations.qmr:1.2 Tue Oct 21 17:56:07 2003 +++ llvm/test/QMTest/expectations.qmr Wed Oct 22 16:52:03 2003 @@ -3,13 +3,13 @@ qoq}q(U _Result__kindqUtestqU_Result__outcomeqUPASSqU_Result__annotationsq}U _Result__idq U0Regression.Assembler.2002-08-16-ConstExprInlinedq U_Result__contextq (cqm.test.context Context -q o}q (U_Context__propertiesq}U_Context__temporariesq}ubub.(hoq}q(hhhhh}h U(Regression.Transforms.PruneEH.simpletestqh (h o}q(h}h}ubub.(hoq}q(hhhhh}h U/Regression.CBackend.2002-08-19-HardConstantExprqh (h o}q(h}h}ubub.(hoq}q(hhhhh}h URegression.Jello.test-shiftqh (h o}q(h}h}ubub.(hoq}q(hhhUFAILqh}h U.Regression.Transforms.CorrelatedExprs.looptestqh (h o}q (h}h}ubub.(hoq!}q"(hhhhh}h U-Regression.Linker.2003-08-23-GlobalVarLinkingq#h (h o}q$(h}h}ubub.(hoq%}q&(hhhhh}h U?Regression.Transforms.Inline.2003-09-22-PHINodesInExceptionDestq'h (h o}q((h}h}ubub.(hoq)}q*(hhhhh}h U,Regression.CFrontend.2003-02-12-NonlocalGotoq+h (h o}q,(h}h}ubub.(hoq-}q.(hhhhh}h U2Regression.Transforms.FunctionResolve.retmismatch1q/h (h o}q0(h}h}ubub.(hoq1}q2(hhhhh}h U8Regression.Transforms.ADCE.2003-01-22-PredecessorProblemq3h (h o}q4(h}h}ubub.(hoq5}q6(hhhhh}h U=Regression.Transforms.LevelRaise.2002-10-08-! VarArgCallInfLoopq7h (h o}q8(h}h}ubub.(hoq9}q:(hhhhh}h U5Regression.CFrontend.2003-07-22-ArrayAccessTypeSafetyq;h (h o}q<(h}h}ubub.(hoq=}q>(hhhhh}h U8Regression.C++Frontend.2003-09-29-ArgumentNumberMismatchq?h (h o}q@(h}h}ubub.(hoqA}qB(hhhhh}h U+Regression.CFrontend.2002-09-19-StarInLabelqCh (h o}qD(h}h}ubub.(hoqE}qF(hhhhh}h U.Regression.CFrontend.2003-08-23-LocalUnionTestqGh (h o}qH(h}h}ubub.(hoqI}qJ(hhhhh}h U"Regression.Jello.2003-06-05-PHIBugqKh (h o}qL(h}h}ubub.(hoqM}qN(hhhhh}h U/Regression.Linker.2003-04-26-NullPtrLinkProblemqOh (h o}qP(h}h}ubub.(hoqQ}qR(hhhhh}h U)Regression.Transforms.Reassociate.subtestqSh (h o}qT(h}h}ubub.(hoqU}qV(hhhhh}h U)Regression.Linker.2002-08-20-ConstantExprqWh (h o}qX(h}h}ubub.(hoqY}qZ(hhhhh}h U=Regression.Transforms.Reassociate.2002-05-15-AgressiveSubMoveq[h (h o}q\(h}h}ubub.(hoq]}q^(hhhhh}h UARegression.Transforms.CorrelatedExprs.2002-10-07-DominatorProblemq_h ! (h o}q`(h}h}ubub.(hoqa}qb(hhhhh}h U3Regression.Transforms.PiNo deInserter.substitutetestqch (h o}qd(h}h}ubub.(hoqe}qf(hhhhh}h U4Regression.Transforms.SCCP.2003-08-26-InvokeHandlingqgh (h o}qh(h}h}ubub.(hoqi}qj(hhhhh}h U$Regression.Jello.2003-01-04-LoopTestqkh (h o}ql(h}h}ubub.(hoqm}qn(hhhhh}h U1Regression.Assembler.2002-04-04-PureVirtMethCall2qoh (h o}qp(h}h}ubub.(hoqq}qr(hhhhh}h U)Regression.CFrontend.2002-07-14-MiscTestsqsh (h o}qt(h}h}ubub.(hoqu}qv(hhhhh}h U(hhhhh}h U=Regression.Transforms.LevelRaise.2002-10-08-VarArgCallInfLoopq?h (h o}q@(h}h}ubub.(hoqA}qB(hhhhh}h U Regression.Reoptimizer.ticm.ticmqCh (h o}qD(h}h}ubub.(hoqE}qF(hhhhh}h U8Regression.C++Frontend.2003-09-29-ArgumentNumberMismatchqGh (h o}qH(h}h}ubub.(hoqI}qJ(hhhhh}h U+Regression.CFrontend.2002-09-19-StarInLabelqKh (h o}qL(h}h}ubub.(hoqM}qN(hhhhh}h U.Regression.CFrontend.2003-08-23-LocalUnionTestqOh (h o}qP(h}h}ubub.(hoqQ}qR(hhhhh}h U/Regression.Linker.2003-04-26-NullPtrLinkProblemqSh (h o}qT(h}h}ubub.(hoqU}qV(hhhhh}h U)Regression.Transforms.Reassociate.subtestqWh (h o}qX(h}h}ubub.(hoqY}qZ(hhhhh}h U)Regression.Linker.2002-08-20-ConstantExprq[h (h o}q\(h}h}ubub.(hoq]}q^(hhhhh}h U=Regression.Transforms.Reassociate.2002-05-15-AgressiveSubMoveq_h (h o}q`(h}h}ubub.! (hoqa}qb(hhhhh}h UARegression.Transforms.CorrelatedExprs.2002-10 -07-DominatorProblemqch (h o}qd(h}h}ubub.(hoqe}qf(hhhhh}h U3Regression.Transforms.PiNodeInserter.substitutetestqgh (h o}qh(h}h}ubub.(hoqi}qj(hhhhh}h U4Regression.Transforms.SCCP.2003-08-26-InvokeHandlingqkh (h o}ql(h}h}ubub.(hoqm}qn(hhhhh}h U-Regression.CFrontend.2002-02-18-64bitConstantqoh (h o}qp(h}h}ubub.(hoqq}qr(hhhhh}h U1Regression.Assembler.2002-04-04-PureVirtMethCall2qsh (h o}qt(h}h}ubub.(hoqu}qv(hhhhh}h U(Regression.Reoptimizer.BinInterface.testqwh (h o}qx(h}h}ubub.(hoqy}qz(hhhhh}h U Changes in directory llvm/test/Regression/Transforms/DeadArgElim: deadretval.ll added (r1.1) deadretval2.ll added (r1.1) --- Log message: New testcase for the deadreturnvalue deletion extension to -deadargelim --- Diffs of the changes: (+55 -0) Index: llvm/test/Regression/Transforms/DeadArgElim/deadretval.ll diff -c /dev/null llvm/test/Regression/Transforms/DeadArgElim/deadretval.ll:1.1 *** /dev/null Wed Oct 22 17:34:10 2003 --- llvm/test/Regression/Transforms/DeadArgElim/deadretval.ll Wed Oct 22 17:33:59 2003 *************** *** 0 **** --- 1,19 ---- + ; RUN: llvm-as < %s | opt -deadargelim | llvm-dis | not grep DEAD + + implementation + + internal int %test(int %DEADARG) { ; Dead arg only used by dead retval + ret int %DEADARG + } + + int %test2(int %A) { + %DEAD = call int %test(int %A) + ret int 123 + } + + int %test3() { + %X = call int %test2(int 3232) + %Y = add int %X, -123 + ret int %Y + } + Index: llvm/test/Regression/Transforms/DeadArgElim/deadretval2.ll diff -c /dev/null llvm/test/Regression/Transforms/DeadArgElim/deadretval2.ll:1.1 *** /dev/null Wed Oct 22 17:34:10 2003 --- llvm/test/Regression/Transforms/DeadArgElim/deadretval2.ll Wed Oct 22 17:33:59 2003 *************** *** 0 **** --- 1,36 ---- + ; RUN: llvm-as < %s | opt -deadargelim -die | llvm-dis | not grep DEAD + + %P = external global int + + implementation + + + internal int %test(int %DEADARG) { ; Dead arg only used by dead retval + ret int %DEADARG + } + + internal int %test2(int %DEADARG) { + %DEADRETVAL = call int %test(int %DEADARG) + ret int %DEADRETVAL + } + + void %test3(int %X) { + %DEADRETVAL = call int %test2(int %X) + ret void + } + + internal int %foo() { + %DEAD = load int* %P + ret int %DEAD + } + + internal int %id(int %X) { + ret int %X + } + + void %test4() { + %DEAD = call int %foo() + %DEAD2 = call int %id(int %DEAD) + ret void + } + From lattner at cs.uiuc.edu Wed Oct 22 18:04:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Oct 22 18:04:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/FunctionResolution.cpp Message-ID: <200310222303.SAA06849@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: FunctionResolution.cpp updated: 1.41 -> 1.42 --- Log message: This important patch fixes two warnings in the linker which can occur from linking valid pieces of code --- Diffs of the changes: (+33 -4) Index: llvm/lib/Transforms/IPO/FunctionResolution.cpp diff -u llvm/lib/Transforms/IPO/FunctionResolution.cpp:1.41 llvm/lib/Transforms/IPO/FunctionResolution.cpp:1.42 --- llvm/lib/Transforms/IPO/FunctionResolution.cpp:1.41 Tue Oct 21 23:43:18 2003 +++ llvm/lib/Transforms/IPO/FunctionResolution.cpp Wed Oct 22 18:03:38 2003 @@ -194,11 +194,40 @@ if (!HasExternal && NumInstancesWithExternalLinkage <= 1) return false; // Nothing to do? Must have multiple internal definitions. + // There are a couple of special cases we don't want to print the warning + // for, check them now. + bool DontPrintWarning = false; + if (Concrete && Globals.size() == 2) { + GlobalValue *Other = Globals[Globals[0] == Concrete]; + // If the non-concrete global is a function which takes (...) arguments, + // and the return values match, do not warn. + if (Function *ConcreteF = dyn_cast(Concrete)) + if (Function *OtherF = dyn_cast(Other)) + if (ConcreteF->getReturnType() == OtherF->getReturnType() && + OtherF->getFunctionType()->isVarArg() && + OtherF->getFunctionType()->getParamTypes().empty()) + DontPrintWarning = true; + + // Otherwise, if the non-concrete global is a global array variable with a + // size of 0, and the concrete global is an array with a real size, don't + // warn. This occurs due to declaring 'extern int A[];'. + if (GlobalVariable *ConcreteGV = dyn_cast(Concrete)) + if (GlobalVariable *OtherGV = dyn_cast(Other)) + if (const ArrayType *OtherAT = + dyn_cast(OtherGV->getType()->getElementType())) + if (const ArrayType *ConcreteAT = + dyn_cast(ConcreteGV->getType()->getElementType())) + if (OtherAT->getElementType() == ConcreteAT->getElementType() && + OtherAT->getNumElements() == 0) + DontPrintWarning = true; + } - std::cerr << "WARNING: Found global types that are not compatible:\n"; - for (unsigned i = 0; i < Globals.size(); ++i) { - std::cerr << "\t" << *Globals[i]->getType() << " %" - << Globals[i]->getName() << "\n"; + if (!DontPrintWarning) { + std::cerr << "WARNING: Found global types that are not compatible:\n"; + for (unsigned i = 0; i < Globals.size(); ++i) { + std::cerr << "\t" << *Globals[i]->getType() << " %" + << Globals[i]->getName() << "\n"; + } } if (!Concrete) From brukman at cs.uiuc.edu Wed Oct 22 18:24:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Oct 22 18:24:01 2003 Subject: [llvm-commits] CVS: llvm/docs/llvm.css Message-ID: <200310222323.SAA17681@zion.cs.uiuc.edu> Changes in directory llvm/docs: llvm.css added (r1.1) --- Log message: We will distributed this stylesheet with the documentation, as well as use it (via import) in the online version. * Added styles for documentation headers, sections, etc. --- Diffs of the changes: (+27 -0) Index: llvm/docs/llvm.css diff -c /dev/null llvm/docs/llvm.css:1.1 *** /dev/null Wed Oct 22 18:23:59 2003 --- llvm/docs/llvm.css Wed Oct 22 18:23:49 2003 *************** *** 0 **** --- 1,27 ---- + /* + * LLVM website style sheet + */ + + /* Common styles */ + .body { text: black; background: white; margin: 0 0 0 0 } + + /* + * Documentation + */ + /* Common for title and header */ + .doc_title, .doc_section, .doc_subsection { + color: #eeeeff; background: #330077; + font-family: "Georgia,Palatino,Times,Roman"; font-weight: bold; + padding-left: 8pt + } + + .doc_title { text-align: left; font-size: 25pt } + .doc_section { text-align: center; font-size: 22pt } + .doc_subsection { background: #441188; width: 50%; + text-align: left; font-size: 12pt; padding: 4 4 4 22 } + .doc_text { text-align: left; padding-left: 20pt } + + /* Publications */ + .pub_title { font-family: "Georgia,Palatino,Times,Roman"; font-size: 24pt; + text-align: center } + .pub_author { font-size: 14pt; text-align: center } From brukman at cs.uiuc.edu Wed Oct 22 18:25:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Oct 22 18:25:01 2003 Subject: [llvm-commits] CVS: llvm-www/llvm.css Message-ID: <200310222324.SAA22393@zion.cs.uiuc.edu> Changes in directory llvm-www: llvm.css updated: 1.1 -> 1.2 --- Log message: Import the styles from docs/llvm.css so we don't maintain 2 versions. --- Diffs of the changes: (+9 -7) Index: llvm-www/llvm.css diff -u llvm-www/llvm.css:1.1 llvm-www/llvm.css:1.2 --- llvm-www/llvm.css:1.1 Tue Oct 21 17:30:00 2003 +++ llvm-www/llvm.css Wed Oct 22 18:24:28 2003 @@ -1,10 +1,12 @@ /* - * LLVM website style sheet + * WHEREAS, we ship source code with the docs/ directory, we need to provide + * users with a style sheet in that directory so that the files they download + * look like the ones they see online; + * + * WHEREAS, it is quite silly to maintain two identical stylesheets in CVS; + * + * BE IT RESOLVED THAT we shall maintain one, and the other one will slurp the + * content. */ -.body { text: black; background: white } - -/* Publications */ -.pub_title { font-family: "Georgia,Palatino,Times,Roman"; font-size: 24pt; - text-align: center } -.pub_author { font-size: 14pt; text-align: center } + at import url("docs/llvm.css"); From brukman at cs.uiuc.edu Wed Oct 22 18:28:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Oct 22 18:28:01 2003 Subject: [llvm-commits] CVS: llvm/docs/AliasAnalysis.html Message-ID: <200310222327.SAA27126@zion.cs.uiuc.edu> Changes in directory llvm/docs: AliasAnalysis.html updated: 1.3 -> 1.4 --- Log message: * Use UTF-8 instead of soon-to-be-extinct ISO-8859-1 ;) * Use stylesheets instead of explicit tags * Stop using

        for spacing layout * Close and

        tags --- Diffs of the changes: (+234 -179) Index: llvm/docs/AliasAnalysis.html diff -u llvm/docs/AliasAnalysis.html:1.3 llvm/docs/AliasAnalysis.html:1.4 --- llvm/docs/AliasAnalysis.html:1.3 Mon Aug 18 09:41:19 2003 +++ llvm/docs/AliasAnalysis.html Wed Oct 22 18:27:16 2003 @@ -1,11 +1,16 @@ -Alias Analysis Infrastructure in LLVM - - - - - -
          Alias Analysis Infrastructure in LLVM
        + + + + + Alias Analysis Infrastructure in LLVM + + + + +

        + Alias Analysis Infrastructure in LLVM +
        1. Introduction @@ -45,70 +50,80 @@

        - - -
        -Introduction -

          + +
          +

          Alias Analysis (or Pointer Analysis) is a technique which attempts to determine whether or not two pointers ever can point to the same object in memory. Traditionally, Alias Analyses respond to a query with either a Must, May, or No alias response, indicating that two pointers do point to the same object, might point to the same object, or are -known not to point to the same object.

          - +known not to point to the same object. +

          +

          The AliasAnalysis class is the centerpiece of the LLVM Alias Analysis related infrastructure. This class is the common interface between clients of alias analysis information and the implementations providing it. In addition to simple alias analysis information, this class exposes Mod/Ref information from those implementations which can provide it, allowing for powerful analyses and transformations to work well -together.

          - +together. +

          +

          This document contains information necessary to successfully implement this interface, use it, and to test both sides. It also explains some of the finer points about what exactly results mean. If you feel that something is unclear -or should be added, please let me know.

          - +or should be added, please let me +know. +

          +
          -
        -
        -AliasAnalysis Overview -
          + +
          +

          The AliasAnalysis class defines the interface that Alias Analysis implementations should support. This class exports two important enums: AliasResult and ModRefResult which represent the result of an alias query or a mod/ref query, -respectively.

          - +respectively. +

          +

          The AliasAnalysis interface exposes information about memory, represented in several different ways. In particular, memory objects are represented as a starting address and size, and function calls are represented as the actual call or invoke instructions that performs the call. The AliasAnalysis interface also exposes some helper methods which allow you to get -mod/ref information for arbitrary instructions.

          +mod/ref information for arbitrary instructions. +

          +
          -
        -
           - -Representation of Pointers -
          + +
          +

          Most importantly, the AliasAnalysis class provides several methods which are used to query whether or not pointers alias, whether function calls can modify -or read memory, etc.

          - +or read memory, etc. +

          +

          Representing memory objects as a starting address and a size is critically important for precise Alias Analyses. For example, consider this (silly) C -code:

          - +code: +

          +

             int i;
             char C[2];
          @@ -119,13 +134,15 @@
               C[1] = A[9-i];        /* One byte store */
             }
           
          - +

          +

          In this case, the basicaa pass will disambiguate the stores to C[0] and C[1] because they are accesses to two distinct locations one byte apart, and the accesses are each one byte. In this case, the LICM pass can use store motion to remove the stores from the loop. In -constrast, the following code:

          - +constrast, the following code: +

          +

             int i;
             char C[2];
          @@ -136,113 +153,126 @@
               C[1] = A[9-i];          /* One byte store */
             }
           
          - +

          +

          In this case, the two stores to C do alias each other, because the access to the &C[0] element is a two byte access. If size information wasn't available in the query, even the first case would have to conservatively assume -that the accesses alias.

          - +that the accesses alias. +

          +
          -
        -
           - -Must, May, and No Alias Responses -
          + +
          +

          An Alias Analysis implementation can return one of three responses: MustAlias, MayAlias, and NoAlias. The No and May alias results are obvious: if the two pointers may never equal each other, return NoAlias, if they might, return -MayAlias.

          - +MayAlias. +

          +

          The Must Alias response is trickier though. In LLVM, the Must Alias response may only be returned if the two memory objects are guaranteed to always start at exactly the same location. If two memory objects overlap, but do not start at -the same location, MayAlias must be returned.

          - +the same location, MayAlias must be returned. +

          +
          -
        -
           - -The getModRefInfo methods -
          + +
          +

          The getModRefInfo methods return information about whether the execution of an instruction can read or modify a memory location. Mod/Ref information is always conservative: if an action may read a location, Ref -is returned.

          - - +is returned. +

          +
          -
        -
        -Writing a new AliasAnalysis Implementation -
          + +
          +

          Writing a new alias analysis implementation for LLVM is quite straight-forward. There are already several implementations that you can use for examples, and the following information should help fill in any details. For a minimal example, take a look at the no-aa -implementation.

          - +implementation. +

          +
          -
        -
           - -Different Pass styles -
          + +
          +

          The first step to determining what type of LLVM pass you need to use for your Alias Analysis. As is the case with most other analyses and transformations, the answer should be fairly obvious from -what type of problem you are trying to solve:

          - +what type of problem you are trying to solve: +

          +

            -
          1. If you require interprocedural analysis, it should be a Pass. -
          2. If you are a global analysis, subclass FunctionPass. -
          3. If you are a local pass, subclass BasicBlockPass. -
          4. If you don't need to look at the program at all, subclass - ImmutablePass. -

          - +

        • If you require interprocedural analysis, it should be a + Pass.
        • +
        • If you are a global analysis, subclass FunctionPass.
        • +
        • If you are a local pass, subclass BasicBlockPass.
        • +
        • If you don't need to look at the program at all, subclass + ImmutablePass.
        • + +

          +

          In addition to the pass that you subclass, you should also inherit from the AliasAnalysis interface, of course, and use the RegisterAnalysisGroup template to register as an implementation of -AliasAnalysis.

          - +AliasAnalysis. +

          +
          -
        -
           - -Required initialization calls -
          + +
          +

          Your subclass of AliasAnalysis is required to invoke two methods on the AliasAnalysis base class: getAnalysisUsage and InitializeAliasAnalysis. In particular, your implementation of getAnalysisUsage should explicitly call into the AliasAnalysis::getAnalysisUsage method in addition to doing any declaring any pass dependencies your pass has. Thus you should have something -like this:

          - +like this: +

          +

               void getAnalysisUsage(AnalysisUsage &AU) const {
                 AliasAnalysis::getAnalysisUsage(AU);
                 // declare your dependencies here.
               }
           
          - +

          +

          Additionally, your must invoke the InitializeAliasAnalysis method from your analysis run method (run for a Pass, runOnFunction for a FunctionPass, runOnBasicBlock for a BasicBlockPass, or InitializeAliasAnalysis for an -ImmutablePass). For example (as part of a Pass):

          - +ImmutablePass). For example (as part of a Pass): +

          +

               bool run(Module &M) {
                 InitializeAliasAnalysis(this);
          @@ -250,197 +280,219 @@
                 return false;
               }
           
          - +

          +
          -
        -
           - -Interfaces which may be specified -
          + +
          +

          All of the AliasAnalysis virtual methods default to providing conservatively correct information (returning "May" Alias and "Mod/Ref" for alias and mod/ref queries respectively). Depending on the capabilities of the analysis you are implementing, you just override the interfaces you can improve. - +

          +
          -
        -
           - -The AliasAnalysis chaining behavior -
          + +
          +

          With only two special exceptions (the basicaa and no-aa passes) every alias analysis pass should chain to another alias analysis implementation (for example, you could specify "-basic-aa -ds-aa -andersens-aa -licm" to get the maximum benefit from the three alias analyses). To do this, simply "Require" AliasAnalysis in your getAnalysisUsage method, and if you need to return a conservative -MayAlias or Mod/Ref result, simply chain to a lower analysis.

          - +MayAlias or Mod/Ref result, simply chain to a lower analysis. +

          +
          -
        -
           - -Efficiency Issues -
          + +
          +

          From the LLVM perspective, the only thing you need to do to provide an efficient alias analysis is to make sure that alias analysis queries are serviced quickly. The actual calculation of the alias analysis results (the "run" method) is only performed once, but many (perhaps duplicate) queries may be performed. Because of this, try to move as much computation to the run method -as possible (within reason).

          - +as possible (within reason). +

          +
          -
        -
        -Using AliasAnalysis results -
          + +
          +

          There are several different ways to use alias analysis results. In order of -preference, these are...

          +preference, these are... +

          +
          -
        -
           - -Using the -load-vn Pass -
          + +
          +

          The load-vn pass uses alias analysis to provide value numbering information for load instructions. If your analysis or transformation can be modelled in a form that uses value numbering information, you don't have to do anything special to handle load instructions: just use the -load-vn pass, which uses alias analysis.

          - +load-vn pass, which uses alias analysis. +

          +
          -
        -
           - -Using the AliasSetTracker class -
          + +
          +

          Many transformations need information about alias sets that are active in some scope, rather than information about pairwise aliasing. The AliasSetTracker class is used to efficiently build these Alias Sets from the pairwise alias analysis -information provided by the AliasAnalysis interface.

          - +information provided by the AliasAnalysis interface. +

          +

          First you initialize the AliasSetTracker by use the "add" methods to add information about various potentially aliasing instructions in the scope you are interested in. Once all of the alias sets are completed, your pass should simply iterate through the constructed alias sets, using the AliasSetTracker -begin()/end() methods.

          - +begin()/end() methods. +

          +

          The AliasSets formed by the AliasSetTracker are guaranteed to be disjoint, calculate mod/ref information for the set, and keep track of whether or not all of the pointers in the set are Must aliases. The AliasSetTracker also makes sure that sets are properly folded due to call -instructions, and can provide a list of pointers in each set.

          - +instructions, and can provide a list of pointers in each set. +

          +

          As an example user of this, the Loop Invariant Code Motion pass uses AliasSetTrackers to build alias information about each loop nest. If an AliasSet in a loop is not modified, then all load instructions from that set may be hoisted out of the loop. If any alias sets are stored and are must alias sets, then the stores may be sunk to outside of the loop. Both of these transformations obviously only apply if the -pointer argument is loop-invariant.

          - +pointer argument is loop-invariant. +

          +
          -
        -
           - -Using the AliasAnalysis interface directly -
          + +
          +

          As a last resort, your pass could use the AliasAnalysis interface directly to service your pass. If you find the need to do this, please let me know so I can see if something new -needs to be added to LLVM.

          - +needs to be added to LLVM. +

          +
          -
        -
        -Helpful alias analysis related tools -
          + +
          +

          If you're going to be working with the AliasAnalysis infrastructure, there are -several nice tools that may be useful for you and are worth knowing about...

          +several nice tools that may be useful for you and are worth knowing about... +

          +
          -
        -
           - -The -no-aa pass -
          + +
          +

          The -no-aa analysis is just like what it sounds: an alias analysis that never returns any useful information. This pass can be useful if you think that alias analysis is doing something wrong and are trying to narrow down a problem. If you don't specify an alias analysis, the default will be to use the -basicaa pass which does quite a bit of disambiguation on its own.

          +basicaa pass which does quite a bit of disambiguation on its own. +

          +
          -
        -
           - -The -print-alias-sets pass -
          + +
          +

          The -print-alias-sets pass is exposed as part of the analyze tool to print out the Alias Sets formed by the AliasSetTracker class. This is useful if you're using -the AliasSetTracker.

          - +the AliasSetTracker. +

          +
          -
        -
           - -The -count-aa pass -
          + +
          +

          The -count-aa pass is useful to see how many queries a particular pass is making and what kinds of responses are returned by the alias analysis. An -example usage is:

          - +example usage is: +

          +

             $ opt -basicaa -count-aa -ds-aa -count-aa -licm
           
          - +

          +

          Which will print out how many queries (and what responses are returned) by the -licm pass (of the -ds-aa pass) and how many queries are made of the -basicaa pass by the -ds-aa pass. This can be useful -when evaluating an alias analysis for precision.

          +when evaluating an alias analysis for precision. +

          +
          -
        -
           - -The -aa-eval pass -
          + +
          +

          The -aa-eval pass simply iterates through all pairs of pointers in a function and asks an alias analysis whether or not the pointers alias. This gives an indication of the precision of the alias analysis. Statistics are -printed.

          - +printed. +

          +
          -
        -
        Chris Lattner
        @@ -448,4 +500,7 @@ Last modified: Tue Mar 4 13:36:53 CST 2003 -
        +
        + + + From brukman at cs.uiuc.edu Wed Oct 22 20:49:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Oct 22 20:49:01 2003 Subject: [llvm-commits] CVS: llvm/docs/CFEBuildInstrs.html Message-ID: <200310230148.UAA15892@zion.cs.uiuc.edu> Changes in directory llvm/docs: CFEBuildInstrs.html updated: 1.1 -> 1.2 --- Log message: * Use UTF-8 instead of ISO-8859-1 * Use stylesheet instead of explicit formatting * Stop using
          for layout * Close
        • tags --- Diffs of the changes: (+48 -39) Index: llvm/docs/CFEBuildInstrs.html diff -u llvm/docs/CFEBuildInstrs.html:1.1 llvm/docs/CFEBuildInstrs.html:1.2 --- llvm/docs/CFEBuildInstrs.html:1.1 Tue Oct 21 16:58:38 2003 +++ llvm/docs/CFEBuildInstrs.html Wed Oct 22 20:48:33 2003 @@ -1,17 +1,15 @@ -Bootstrapping the C/C++ Front-End - - -

          Bootstrapping the C/C++ Front-End

          - -

          - - - -
          -Instructions -
            - + + + + + Bootstrapping the C/C++ Front-End + + + +
            + Bootstrapping the C/C++ Front-End +

            This document is intended to explain the process of building the LLVM C/C++ front-end, based on GCC 3.4, from source.

            @@ -23,6 +21,14 @@

            We welcome patches to help make this process simpler.

            + + + + +
            +

            1. Configure and build the LLVM libraries and tools using:

              @@ -33,17 +39,17 @@
                   

              The use of the non-default target "tools-only" means that the LLVM tools and libraries will build, and the binaries will be deposited in llvm/tools/Debug, but the runtime (bytecode) - libraries will not build.

              + libraries will not build.

            2. Add the directory containing the tools to your PATH.

              - % set path = ( `cd llvm/tools/Debug && pwd` $path )
              -
              + % set path = ( `cd llvm/tools/Debug && pwd` $path ) +
  • -
  • Unpack the C/C++ front-end source into cfrontend/src.

    +
  • Unpack the C/C++ front-end source into cfrontend/src.

  • Edit src/configure. Change the first line (starting w/ #!) to - contain the correct full pathname of sh.

    + contain the correct full pathname of sh.

  • Make "build" and "install" directories as siblings of the "src" tree.

    @@ -53,7 +59,7 @@ % cd .. % mkdir build install % set CFEINSTALL = `pwd`/install - +
  • Configure, build and install the C front-end:

    @@ -73,34 +79,36 @@
       
  • Fix 1: If you have system header files that include inline assembly, you may have to modify them to remove the inline assembly, and install the modified versions in - $CFEINSTALL/target-triplet/sys-include.

    + $CFEINSTALL/target-triplet/sys-include.

  • Fix 2: If you are building the C++ front-end on a CPU we haven't tried yet, you will probably have to edit the appropriate version of atomicity.h under src/libstdc++-v3/config/cpu/name-of-cpu/atomicity.h - and apply a patch so that it does not use inline assembly.

    + and apply a patch so that it does not use inline assembly.

  • Common Problem 2: FIXME: Chris should add a section about common problems porting to a new architecture, including changes you - might have to make to the gcc/gcc/config/name-of-cpu + might have to make to the gcc/gcc/config/name-of-cpu directory. For example (expand these):

      -
    • Munge linker flags so they are compatible with gccld. +
    • Munge linker flags so they are compatible with gccld.
    • Change the target so it doesn't have long double; just use double - instead. -
    • No inline assembly for position independent code. -
    • We handle init and fini differently. -
    • Do not include inline assembly map things for SPARC, or profile things. + instead.
    • +
    • No inline assembly for position independent code.
    • +
    • We handle init and fini differently.
    • +
    • Do not include inline assembly map things for SPARC, or profile + things.
    +
  • Go back into the LLVM source tree proper. Edit Makefile.config to redefine LLVMGCCDIR to the full pathname of the $CFEINSTALL directory, which is the directory you just installed the C front-end into. (The ./configure script is likely to -have set this to a directory which does not exist on your system.)

    +have set this to a directory which does not exist on your system.)

  • If you edited header files during the C/C++ front-end build as described in "Fix 1" above, you must now copy those header files from @@ -108,7 +116,7 @@ $CFEINSTALL/lib/gcc/target-triplet/3.4-llvm/include. (This should be the "include" directory in the same directory as the libgcc.a library, which you can find by running -$CFEINSTALL/bin/gcc --print-libgcc-file-name.)

    +$CFEINSTALL/bin/gcc --print-libgcc-file-name.)

  • Build and install the runtime (bytecode) libraries by running:

    @@ -116,25 +124,26 @@
      % mkdir $CFEINSTALL/bytecode-libs
      % gmake -C runtime install
      % setenv LLVM_LIB_SEARCH_PATH $CFEINSTALL/bytecode-libs
    -
    +
  • Test the newly-installed C frontend by one or more of the following means:

      -
    • compiling and running a "hello, world" program in C or C++. +
    • compiling and running a "hello, world" program in C or C++.
    • running the tests under test/Programs using gmake -C - test/Programs; + test/Programs
    - -

    +

    +
  • +
    - - -
    +
    Brian Gaeke
    -Last modified: $Date: 2003/10/21 21:58:38 $ -
    +Last modified: $Date: 2003/10/23 01:48:33 $ +
    + + From brukman at cs.uiuc.edu Wed Oct 22 20:50:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Oct 22 20:50:01 2003 Subject: [llvm-commits] CVS: llvm/docs/AliasAnalysis.html Message-ID: <200310230149.UAA20609@zion.cs.uiuc.edu> Changes in directory llvm/docs: AliasAnalysis.html updated: 1.4 -> 1.5 --- Log message: * Quote a value in tag. * Let CVS figure out the last-modified-date for us --- Diffs of the changes: (+2 -2) Index: llvm/docs/AliasAnalysis.html diff -u llvm/docs/AliasAnalysis.html:1.4 llvm/docs/AliasAnalysis.html:1.5 --- llvm/docs/AliasAnalysis.html:1.4 Wed Oct 22 18:27:16 2003 +++ llvm/docs/AliasAnalysis.html Wed Oct 22 20:49:47 2003 @@ -494,11 +494,11 @@ -
    +
    Chris Lattner
    -Last modified: Tue Mar 4 13:36:53 CST 2003 +Last modified: $Date: 2003/10/23 01:49:47 $
    From brukman at cs.uiuc.edu Wed Oct 22 20:51:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Oct 22 20:51:01 2003 Subject: [llvm-commits] CVS: llvm/docs/AliasAnalysis.html Message-ID: <200310230150.UAA25330@zion.cs.uiuc.edu> Changes in directory llvm/docs: AliasAnalysis.html updated: 1.5 -> 1.6 --- Log message: Remove extraneous comments. --- Diffs of the changes: (+1 -4) Index: llvm/docs/AliasAnalysis.html diff -u llvm/docs/AliasAnalysis.html:1.5 llvm/docs/AliasAnalysis.html:1.6 --- llvm/docs/AliasAnalysis.html:1.5 Wed Oct 22 20:49:47 2003 +++ llvm/docs/AliasAnalysis.html Wed Oct 22 20:50:39 2003 @@ -496,10 +496,7 @@
    Chris Lattner
    - - -Last modified: $Date: 2003/10/23 01:49:47 $ - +Last modified: $Date: 2003/10/23 01:50:39 $
    From brukman at cs.uiuc.edu Wed Oct 22 21:30:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Oct 22 21:30:01 2003 Subject: [llvm-commits] CVS: llvm/docs/AliasAnalysis.html Message-ID: <200310230229.VAA30158@zion.cs.uiuc.edu> Changes in directory llvm/docs: AliasAnalysis.html updated: 1.6 -> 1.7 --- Log message: Really close the
  • tags. --- Diffs of the changes: (+23 -23) Index: llvm/docs/AliasAnalysis.html diff -u llvm/docs/AliasAnalysis.html:1.6 llvm/docs/AliasAnalysis.html:1.7 --- llvm/docs/AliasAnalysis.html:1.6 Wed Oct 22 20:50:39 2003 +++ llvm/docs/AliasAnalysis.html Wed Oct 22 21:29:42 2003 @@ -13,41 +13,41 @@
      -
    1. Introduction +
    2. Introduction
    3. -
    4. AliasAnalysis Overview +
    5. AliasAnalysis Overview
    6. -
    7. Writing a new AliasAnalysis Implementation +
    8. Writing a new AliasAnalysis Implementation
    9. -
    10. Using AliasAnalysis results +
    11. Using AliasAnalysis results
    12. -
    13. Helpful alias analysis related tools +
    14. Helpful alias analysis related tools
    15. -

      Written by Chris Lattner

      -

    +

    Written by Chris Lattner

    + @@ -496,7 +496,7 @@
    Chris Lattner
    -Last modified: $Date: 2003/10/23 01:50:39 $ +Last modified: $Date: 2003/10/23 02:29:42 $
    From lattner at cs.uiuc.edu Wed Oct 22 22:32:50 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Oct 22 22:32:50 2003 Subject: [llvm-commits] CVS: llvm/docs/ChrisNotes.txt Message-ID: <200310230331.WAA32016@zion.cs.uiuc.edu> Changes in directory llvm/docs: ChrisNotes.txt (r1.29) removed --- Log message: To say this file is obsolete to understate the obvious --- Diffs of the changes: (+0 -0) From lattner at cs.uiuc.edu Wed Oct 22 22:49:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Oct 22 22:49:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp Message-ID: <200310230348.WAA00607@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: DeadArgumentElimination.cpp updated: 1.7 -> 1.8 --- Log message: Make this pass substantially stronger by having it delete dead return values as well as arguments. Now it can delete arguments and return values which are only passed into other arguments or are returned, if they are dead. This causes it to delete several hundred extra args/retvals from the C++ hello world program, shrinking it by about 2K. --- Diffs of the changes: (+353 -126) Index: llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp diff -u llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp:1.7 llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp:1.8 --- llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp:1.7 Mon Oct 20 14:43:18 2003 +++ llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp Wed Oct 22 22:48:17 2003 @@ -9,7 +9,8 @@ // // This pass deletes dead arguments from internal functions. Dead argument // elimination removes arguments which are directly dead, as well as arguments -// only passed into function calls as dead arguments of other functions. +// only passed into function calls as dead arguments of other functions. This +// pass also deletes dead arguments in a similar way. // // This pass is often useful as a cleanup pass to run after aggressive // interprocedural passes, which add possibly-dead arguments. @@ -30,17 +31,68 @@ #include namespace { - Statistic<> NumArgumentsEliminated("deadargelim", "Number of args removed"); + Statistic<> NumArgumentsEliminated("deadargelim", + "Number of unread args removed"); + Statistic<> NumRetValsEliminated("deadargelim", + "Number of unused return values removed"); + + /// DAE - The dead argument elimination pass. + /// + class DAE : public Pass { + /// DeleteFromExternalFunctions - Bugpoint sets this flag to indicate that + /// it is safe to hack apart functions without internal linkage. + bool DeleteFromExternalFunctions; + + /// Liveness enum - During our initial pass over the program, we determine + /// that things are either definately alive, definately dead, or in need of + /// interprocedural analysis (MaybeLive). + /// + enum Liveness { Live, MaybeLive, Dead }; + + /// LiveArguments, MaybeLiveArguments, DeadArguments - These sets contain + /// all of the arguments in the program. The Dead set contains arguments + /// which are completely dead (never used in the function). The MaybeLive + /// set contains arguments which are only passed into other function calls, + /// thus may be live and may be dead. The Live set contains arguments which + /// are known to be alive. + /// + std::set DeadArguments, MaybeLiveArguments, LiveArguments; + + /// DeadRetVal, MaybeLiveRetVal, LifeRetVal - These sets contain all of the + /// functions in the program. The Dead set contains functions whose return + /// value is known to be dead. The MaybeLive set contains functions whose + /// return values are only used by return instructions, and the Live set + /// contains functions whose return values are used, functions that are + /// external, and functions that already return void. + /// + std::set DeadRetVal, MaybeLiveRetVal, LiveRetVal; + + /// InstructionsToInspect - As we mark arguments and return values + /// MaybeLive, we keep track of which instructions could make the values + /// live here. Once the entire program has had the return value and + /// arguments analyzed, this set is scanned to promote the MaybeLive objects + /// to be Live if they really are used. + std::vector InstructionsToInspect; + + /// CallSites - Keep track of the call sites of functions that have + /// MaybeLive arguments or return values. + std::multimap CallSites; - struct DAE : public Pass { + public: DAE(bool DFEF = false) : DeleteFromExternalFunctions(DFEF) {} bool run(Module &M); private: - bool DeleteFromExternalFunctions; - bool FunctionArgumentsIntrinsicallyAlive(const Function &F); - void RemoveDeadArgumentsFromFunction(Function *F, - std::set &DeadArguments); + Liveness getArgumentLiveness(const Argument &A); + bool isMaybeLiveArgumentNowLive(Argument *Arg); + + void SurveyFunction(Function &Fn); + + void MarkArgumentLive(Argument *Arg); + void MarkRetValLive(Function *F); + void MarkReturnInstArgumentLive(ReturnInst *RI); + + void RemoveDeadArgumentsFromFunction(Function *F); }; RegisterOpt X("deadargelim", "Dead Argument Elimination"); } @@ -55,70 +107,172 @@ return new DAE(DeleteFromExternalFunctions); } - -// FunctionArgumentsIntrinsicallyAlive - Return true if the arguments of the -// specified function are intrinsically alive. -// -// We consider arguments of non-internal functions to be intrinsically alive as -// well as arguments to functions which have their "address taken". -// -bool DAE::FunctionArgumentsIntrinsicallyAlive(const Function &F) { - if (!F.hasInternalLinkage() && !DeleteFromExternalFunctions) return true; - - for (Value::use_const_iterator I = F.use_begin(), E = F.use_end(); I!=E; ++I){ - // If this use is anything other than a call site, the function is alive. - CallSite CS = CallSite::get(const_cast(*I)); - if (!CS.getInstruction()) return true; // Not a valid call site? - - // If the function is PASSED IN as an argument, its address has been taken - for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end(); AI != E; - ++AI) - if (AI->get() == &F) return true; - } +static inline bool CallPassesValueThoughVararg(Instruction *Call, + const Value *Arg) { + CallSite CS = CallSite::get(Call); + const Type *CalledValueTy = CS.getCalledValue()->getType(); + const Type *FTy = cast(CalledValueTy)->getElementType(); + unsigned NumFixedArgs = cast(FTy)->getNumParams(); + for (CallSite::arg_iterator AI = CS.arg_begin()+NumFixedArgs; + AI != CS.arg_end(); ++AI) + if (AI->get() == Arg) + return true; return false; } -namespace { - enum ArgumentLiveness { Alive, MaybeLive, Dead }; -} - -// getArgumentLiveness - Inspect an argument, determining if is known Alive +// getArgumentLiveness - Inspect an argument, determining if is known Live // (used in a computation), MaybeLive (only passed as an argument to a call), or // Dead (not used). -static ArgumentLiveness getArgumentLiveness(const Argument &A) { +DAE::Liveness DAE::getArgumentLiveness(const Argument &A) { if (A.use_empty()) return Dead; // First check, directly dead? // Scan through all of the uses, looking for non-argument passing uses. for (Value::use_const_iterator I = A.use_begin(), E = A.use_end(); I!=E;++I) { + // Return instructions do not immediately effect liveness. + if (isa(*I)) + continue; + CallSite CS = CallSite::get(const_cast(*I)); if (!CS.getInstruction()) { // If its used by something that is not a call or invoke, it's alive! - return Alive; + return Live; } // If it's an indirect call, mark it alive... Function *Callee = CS.getCalledFunction(); - if (!Callee) return Alive; + if (!Callee) return Live; // Check to see if it's passed through a va_arg area: if so, we cannot // remove it. - unsigned NumFixedArgs = Callee->getFunctionType()->getNumParams(); - for (CallSite::arg_iterator AI = CS.arg_begin()+NumFixedArgs; - AI != CS.arg_end(); ++AI) - if (AI->get() == &A) // If passed through va_arg area, we cannot remove it - return Alive; + if (CallPassesValueThoughVararg(CS.getInstruction(), &A)) + return Live; // If passed through va_arg area, we cannot remove it } return MaybeLive; // It must be used, but only as argument to a function } -// isMaybeLiveArgumentNowAlive - Check to see if Arg is alive. At this point, -// we know that the only uses of Arg are to be passed in as an argument to a -// function call. Check to see if the formal argument passed in is in the -// LiveArguments set. If so, return true. + +// SurveyFunction - This performs the initial survey of the specified function, +// checking out whether or not it uses any of its incoming arguments or whether +// any callers use the return value. This fills in the +// (Dead|MaybeLive|Live)(Arguments|RetVal) sets. +// +// We consider arguments of non-internal functions to be intrinsically alive as +// well as arguments to functions which have their "address taken". +// +void DAE::SurveyFunction(Function &F) { + bool FunctionIntrinsicallyLive = false; + Liveness RetValLiveness = F.getReturnType() == Type::VoidTy ? Live : Dead; + + if (!F.hasInternalLinkage() && !DeleteFromExternalFunctions) + FunctionIntrinsicallyLive = true; + else + for (Value::use_iterator I = F.use_begin(), E = F.use_end(); I != E; ++I) { + // If this use is anything other than a call site, the function is alive. + CallSite CS = CallSite::get(*I); + Instruction *TheCall = CS.getInstruction(); + if (!TheCall) { // Not a direct call site? + FunctionIntrinsicallyLive = true; + break; + } + + // Check to see if the return value is used... + if (RetValLiveness != Live) + for (Value::use_iterator I = TheCall->use_begin(), + E = TheCall->use_end(); I != E; ++I) + if (isa(cast(*I))) { + RetValLiveness = MaybeLive; + } else if (isa(cast(*I)) || + isa(cast(*I))) { + if (CallPassesValueThoughVararg(cast(*I), TheCall) || + !CallSite::get(cast(*I)).getCalledFunction()) { + RetValLiveness = Live; + break; + } else { + RetValLiveness = MaybeLive; + } + } else { + RetValLiveness = Live; + break; + } + + // If the function is PASSED IN as an argument, its address has been taken + for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end(); + AI != E; ++AI) + if (AI->get() == &F) { + FunctionIntrinsicallyLive = true; + break; + } + if (FunctionIntrinsicallyLive) break; + } + + if (FunctionIntrinsicallyLive) { + DEBUG(std::cerr << " Intrinsically live fn: " << F.getName() << "\n"); + for (Function::aiterator AI = F.abegin(), E = F.aend(); AI != E; ++AI) + LiveArguments.insert(AI); + LiveRetVal.insert(&F); + return; + } + + switch (RetValLiveness) { + case Live: LiveRetVal.insert(&F); break; + case MaybeLive: MaybeLiveRetVal.insert(&F); break; + case Dead: DeadRetVal.insert(&F); break; + } + + DEBUG(std::cerr << " Inspecting args for fn: " << F.getName() << "\n"); + + // If it is not intrinsically alive, we know that all users of the + // function are call sites. Mark all of the arguments live which are + // directly used, and keep track of all of the call sites of this function + // if there are any arguments we assume that are dead. + // + bool AnyMaybeLiveArgs = false; + for (Function::aiterator AI = F.abegin(), E = F.aend(); AI != E; ++AI) + switch (getArgumentLiveness(*AI)) { + case Live: + DEBUG(std::cerr << " Arg live by use: " << AI->getName() << "\n"); + LiveArguments.insert(AI); + break; + case Dead: + DEBUG(std::cerr << " Arg definitely dead: " <getName()<<"\n"); + DeadArguments.insert(AI); + break; + case MaybeLive: + DEBUG(std::cerr << " Arg only passed to calls: " + << AI->getName() << "\n"); + AnyMaybeLiveArgs = true; + MaybeLiveArguments.insert(AI); + break; + } + + // If there are any "MaybeLive" arguments, we need to check callees of + // this function when/if they become alive. Record which functions are + // callees... + if (AnyMaybeLiveArgs || RetValLiveness == MaybeLive) + for (Value::use_iterator I = F.use_begin(), E = F.use_end(); + I != E; ++I) { + if (AnyMaybeLiveArgs) + CallSites.insert(std::make_pair(&F, CallSite::get(*I))); + + if (RetValLiveness == MaybeLive) + for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); + UI != E; ++UI) + InstructionsToInspect.push_back(cast(*UI)); + } +} + +// isMaybeLiveArgumentNowLive - Check to see if Arg is alive. At this point, we +// know that the only uses of Arg are to be passed in as an argument to a +// function call or return. Check to see if the formal argument passed in is in +// the LiveArguments set. If so, return true. // -static bool isMaybeLiveArgumentNowAlive(Argument *Arg, - const std::set &LiveArguments) { +bool DAE::isMaybeLiveArgumentNowLive(Argument *Arg) { for (Value::use_iterator I = Arg->use_begin(), E = Arg->use_end(); I!=E; ++I){ + if (isa(*I)) { + if (LiveRetVal.count(Arg->getParent())) return true; + continue; + } + CallSite CS = CallSite::get(*I); // We know that this can only be used for direct calls... @@ -136,18 +290,16 @@ return false; } -// MarkArgumentLive - The MaybeLive argument 'Arg' is now known to be alive. -// Mark it live in the specified sets and recursively mark arguments in callers -// live that are needed to pass in a value. -// -static void MarkArgumentLive(Argument *Arg, - std::set &MaybeLiveArguments, - std::set &LiveArguments, - const std::multimap &CallSites) { +/// MarkArgumentLive - The MaybeLive argument 'Arg' is now known to be alive. +/// Mark it live in the specified sets and recursively mark arguments in callers +/// live that are needed to pass in a value. +/// +void DAE::MarkArgumentLive(Argument *Arg) { + std::set::iterator It = MaybeLiveArguments.lower_bound(Arg); + if (It == MaybeLiveArguments.end() || *It != Arg) return; + DEBUG(std::cerr << " MaybeLive argument now live: " << Arg->getName()<<"\n"); - assert(MaybeLiveArguments.count(Arg) && !LiveArguments.count(Arg) && - "Arg not MaybeLive?"); - MaybeLiveArguments.erase(Arg); + MaybeLiveArguments.erase(It); LiveArguments.insert(Arg); // Loop over all of the call sites of the function, making any arguments @@ -156,14 +308,55 @@ Function *Fn = Arg->getParent(); unsigned ArgNo = std::distance(Fn->abegin(), Function::aiterator(Arg)); - std::multimap::const_iterator I = - CallSites.lower_bound(Fn); + std::multimap::iterator I = CallSites.lower_bound(Fn); for (; I != CallSites.end() && I->first == Fn; ++I) { - const CallSite &CS = I->second; - if (Argument *ActualArg = dyn_cast(*(CS.arg_begin()+ArgNo))) - if (MaybeLiveArguments.count(ActualArg)) - MarkArgumentLive(ActualArg, MaybeLiveArguments, LiveArguments, - CallSites); + CallSite CS = I->second; + Value *ArgVal = *(CS.arg_begin()+ArgNo); + if (Argument *ActualArg = dyn_cast(ArgVal)) { + MarkArgumentLive(ActualArg); + } else { + // If the value passed in at this call site is a return value computed by + // some other call site, make sure to mark the return value at the other + // call site as being needed. + CallSite ArgCS = CallSite::get(ArgVal); + if (ArgCS.getInstruction()) + if (Function *Fn = ArgCS.getCalledFunction()) + MarkRetValLive(Fn); + } + } +} + +/// MarkArgumentLive - The MaybeLive return value for the specified function is +/// now known to be alive. Propagate this fact to the return instructions which +/// produce it. +void DAE::MarkRetValLive(Function *F) { + assert(F && "Shame shame, we can't have null pointers here!"); + + // Check to see if we already knew it was live + std::set::iterator I = MaybeLiveRetVal.lower_bound(F); + if (I == MaybeLiveRetVal.end() || *I != F) return; // It's already alive! + + DEBUG(std::cerr << " MaybeLive retval now live: " << F->getName() << "\n"); + + MaybeLiveRetVal.erase(I); + LiveRetVal.insert(F); // It is now known to be live! + + // Loop over all of the functions, noticing that the return value is now live. + for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) + if (ReturnInst *RI = dyn_cast(BB->getTerminator())) + MarkReturnInstArgumentLive(RI); +} + +void DAE::MarkReturnInstArgumentLive(ReturnInst *RI) { + Value *Op = RI->getOperand(0); + if (Argument *A = dyn_cast(Op)) { + MarkArgumentLive(A); + } else if (CallInst *CI = dyn_cast(Op)) { + if (Function *F = CI->getCalledFunction()) + MarkRetValLive(F); + } else if (InvokeInst *II = dyn_cast(Op)) { + if (Function *F = II->getCalledFunction()) + MarkRetValLive(F); } } @@ -171,8 +364,7 @@ // specified by the DeadArguments list. Transform the function and all of the // callees of the function to not have these arguments. // -void DAE::RemoveDeadArgumentsFromFunction(Function *F, - std::set &DeadArguments){ +void DAE::RemoveDeadArgumentsFromFunction(Function *F) { // Start by computing a new prototype for the function, which is the same as // the old function, but has fewer arguments. const FunctionType *FTy = F->getFunctionType(); @@ -182,9 +374,14 @@ if (!DeadArguments.count(I)) Params.push_back(I->getType()); - FunctionType *NFTy = FunctionType::get(FTy->getReturnType(), Params, - FTy->isVarArg()); - + const Type *RetTy = FTy->getReturnType(); + if (DeadRetVal.count(F)) { + RetTy = Type::VoidTy; + DeadRetVal.erase(F); + } + + FunctionType *NFTy = FunctionType::get(RetTy, Params, FTy->isVarArg()); + // Create the new function body and insert it into the module... Function *NF = new Function(NFTy, F->getLinkage(), F->getName()); F->getParent()->getFunctionList().insert(F, NF); @@ -192,19 +389,40 @@ // Loop over all of the callers of the function, transforming the call sites // to pass in a smaller number of arguments into the new function. // + std::vector Args; while (!F->use_empty()) { CallSite CS = CallSite::get(F->use_back()); Instruction *Call = CS.getInstruction(); - CS.setCalledFunction(NF); // Reduce the uses count of F - + // Loop over the operands, deleting dead ones... CallSite::arg_iterator AI = CS.arg_begin(); - for (Function::aiterator I = F->abegin(), E = F->aend(); I != E; ++I) - if (DeadArguments.count(I)) { // Remove operands for dead arguments - AI = Call->op_erase(AI); - } else { - ++AI; // Leave live operands alone... + for (Function::aiterator I = F->abegin(), E = F->aend(); I != E; ++I, ++AI) + if (!DeadArguments.count(I)) // Remove operands for dead arguments + Args.push_back(*AI); + + Instruction *New; + if (InvokeInst *II = dyn_cast(Call)) { + New = new InvokeInst(NF, II->getNormalDest(), II->getExceptionalDest(), + Args, "", Call); + } else { + New = new CallInst(NF, Args, "", Call); + } + Args.clear(); + + if (!Call->use_empty()) { + if (New->getType() == Type::VoidTy) + Call->replaceAllUsesWith(Constant::getNullValue(Call->getType())); + else { + Call->replaceAllUsesWith(New); + std::string Name = Call->getName(); + Call->setName(""); + New->setName(Name); } + } + + // Finally, remove the old call from the program, reducing the use-count of + // F. + Call->getParent()->getInstList().erase(Call); } // Since we have now created the new function, splice the body of the old @@ -232,6 +450,15 @@ DeadArguments.erase(I); } + // If we change the return value of the function we must rewrite any return + // instructions. Check this now. + if (F->getReturnType() != NF->getReturnType()) + for (Function::iterator BB = NF->begin(), E = NF->end(); BB != E; ++BB) + if (ReturnInst *RI = dyn_cast(BB->getTerminator())) { + new ReturnInst(0, RI); + BB->getInstList().erase(RI); + } + // Now that the old function is dead, delete it. F->getParent()->getFunctionList().erase(F); } @@ -241,52 +468,44 @@ // We assume all arguments are dead unless proven otherwise (allowing us to // determine that dead arguments passed into recursive functions are dead). // - std::set LiveArguments, MaybeLiveArguments, DeadArguments; - std::multimap CallSites; - DEBUG(std::cerr << "DAE - Determining liveness\n"); - for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { - Function &Fn = *I; - // If the function is intrinsically alive, just mark the arguments alive. - if (FunctionArgumentsIntrinsicallyAlive(Fn)) { - for (Function::aiterator AI = Fn.abegin(), E = Fn.aend(); AI != E; ++AI) - LiveArguments.insert(AI); - DEBUG(std::cerr << " Args intrinsically live for fn: " << Fn.getName() - << "\n"); + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) + SurveyFunction(*I); + + // Loop over the instructions to inspect, propagating liveness among arguments + // and return values which are MaybeLive. + + while (!InstructionsToInspect.empty()) { + Instruction *I = InstructionsToInspect.back(); + InstructionsToInspect.pop_back(); + + if (ReturnInst *RI = dyn_cast(I)) { + // For return instructions, we just have to check to see if the return + // value for the current function is known now to be alive. If so, any + // arguments used by it are now alive, and any call instruction return + // value is alive as well. + if (LiveRetVal.count(RI->getParent()->getParent())) + MarkReturnInstArgumentLive(RI); + } else { - DEBUG(std::cerr << " Inspecting args for fn: " << Fn.getName() << "\n"); + CallSite CS = CallSite::get(I); + assert(CS.getInstruction() && "Unknown instruction for the I2I list!"); - // If it is not intrinsically alive, we know that all users of the - // function are call sites. Mark all of the arguments live which are - // directly used, and keep track of all of the call sites of this function - // if there are any arguments we assume that are dead. + Function *Callee = CS.getCalledFunction(); + + // If we found a call or invoke instruction on this list, that means that + // an argument of the function is a call instruction. If the argument is + // live, then the return value of the called instruction is now live. // - bool AnyMaybeLiveArgs = false; - for (Function::aiterator AI = Fn.abegin(), E = Fn.aend(); AI != E; ++AI) - switch (getArgumentLiveness(*AI)) { - case Alive: - DEBUG(std::cerr << " Arg live by use: " << AI->getName() << "\n"); - LiveArguments.insert(AI); - break; - case Dead: - DEBUG(std::cerr << " Arg definitely dead: " <getName()<<"\n"); - DeadArguments.insert(AI); - break; - case MaybeLive: - DEBUG(std::cerr << " Arg only passed to calls: " - << AI->getName() << "\n"); - AnyMaybeLiveArgs = true; - MaybeLiveArguments.insert(AI); - break; - } - - // If there are any "MaybeLive" arguments, we need to check callees of - // this function when/if they become alive. Record which functions are - // callees... - if (AnyMaybeLiveArgs) - for (Value::use_iterator I = Fn.use_begin(), E = Fn.use_end(); - I != E; ++I) - CallSites.insert(std::make_pair(&Fn, CallSite::get(*I))); + CallSite::arg_iterator AI = CS.arg_begin(); // ActualIterator + for (Function::aiterator FI = Callee->abegin(), E = Callee->aend(); + FI != E; ++AI, ++FI) { + // If this argument is another call... + CallSite ArgCS = CallSite::get(*AI); + if (ArgCS.getInstruction() && LiveArguments.count(FI)) + if (Function *Callee = ArgCS.getCalledFunction()) + MarkRetValLive(Callee); + } } } @@ -295,17 +514,16 @@ // passed into requires them to be live. Of course this could make other // arguments live, so process callers recursively. // - // Because elements can be removed from the MaybeLiveArguments list, copy it - // to a temporary vector. + // Because elements can be removed from the MaybeLiveArguments set, copy it to + // a temporary vector. // std::vector TmpArgList(MaybeLiveArguments.begin(), MaybeLiveArguments.end()); for (unsigned i = 0, e = TmpArgList.size(); i != e; ++i) { Argument *MLA = TmpArgList[i]; if (MaybeLiveArguments.count(MLA) && - isMaybeLiveArgumentNowAlive(MLA, LiveArguments)) { - MarkArgumentLive(MLA, MaybeLiveArguments, LiveArguments, CallSites); - } + isMaybeLiveArgumentNowLive(MLA)) + MarkArgumentLive(MLA); } // Recover memory early... @@ -314,17 +532,26 @@ // At this point, we know that all arguments in DeadArguments and // MaybeLiveArguments are dead. If the two sets are empty, there is nothing // to do. - if (MaybeLiveArguments.empty() && DeadArguments.empty()) + if (MaybeLiveArguments.empty() && DeadArguments.empty() && + MaybeLiveRetVal.empty() && DeadRetVal.empty()) return false; // Otherwise, compact into one set, and start eliminating the arguments from // the functions. DeadArguments.insert(MaybeLiveArguments.begin(), MaybeLiveArguments.end()); MaybeLiveArguments.clear(); + DeadRetVal.insert(MaybeLiveRetVal.begin(), MaybeLiveRetVal.end()); + MaybeLiveRetVal.clear(); + + LiveArguments.clear(); + LiveRetVal.clear(); NumArgumentsEliminated += DeadArguments.size(); + NumRetValsEliminated += DeadRetVal.size(); while (!DeadArguments.empty()) - RemoveDeadArgumentsFromFunction((*DeadArguments.begin())->getParent(), - DeadArguments); + RemoveDeadArgumentsFromFunction((*DeadArguments.begin())->getParent()); + + while (!DeadRetVal.empty()) + RemoveDeadArgumentsFromFunction(*DeadRetVal.begin()); return true; } From lattner at cs.uiuc.edu Wed Oct 22 22:56:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Oct 22 22:56:01 2003 Subject: [llvm-commits] CVS: llvm/docs/CFEBuildInstrs.html Message-ID: <200310230355.WAA00676@zion.cs.uiuc.edu> Changes in directory llvm/docs: CFEBuildInstrs.html updated: 1.2 -> 1.3 --- Log message: Minor edits --- Diffs of the changes: (+22 -15) Index: llvm/docs/CFEBuildInstrs.html diff -u llvm/docs/CFEBuildInstrs.html:1.2 llvm/docs/CFEBuildInstrs.html:1.3 --- llvm/docs/CFEBuildInstrs.html:1.2 Wed Oct 22 20:48:33 2003 +++ llvm/docs/CFEBuildInstrs.html Wed Oct 22 22:55:23 2003 @@ -71,7 +71,7 @@ % gmake all; gmake install -

    Common Problem 1: You may get error messages regarding the fact +

    Common Problem: You may get error messages regarding the fact that LLVM does not support inline assembly. Here are two common fixes:

    @@ -88,19 +88,26 @@ and apply a patch so that it does not use inline assembly.

  • -

    Common Problem 2: FIXME: Chris should add a section about - common problems porting to a new architecture, including changes you - might have to make to the gcc/gcc/config/name-of-cpu - directory. For example (expand these):

    +

    Porting to a new architecture: If you are porting the new front-end + to a new architecture, or compiling in a different configuration that we have + previously, there are probably several changes you will have to make to the GCC + target to get it to work correctly. These include:

      -
    • Munge linker flags so they are compatible with gccld.
    • -
    • Change the target so it doesn't have long double; just use double - instead.
    • -
    • No inline assembly for position independent code.
    • -
    • We handle init and fini differently.
    • -
    • Do not include inline assembly map things for SPARC, or profile - things.
    • +
    • Often targets include special or assembler linker flags which + gccas/gccld does not understand. In general, these can + just be removed.
    • +
    • LLVM currently does not support any floating point values other than + 32-bit and 64-bit IEEE floating point. The primary effect of this is + that you may have to map "long double" onto "double".
    • +
    • The profiling hooks in GCC do not apply at all to the LLVM front-end. + These may need to be disabled.
    • +
    • No inline assembly for position independent code. At the LLVM level, + everything is position independent.
    • +
    • We handle .init and .fini differently.
    • +
    • Did we mention that we don't support inline assembly? You'll probably + have to add some fixinclude hacks to disable it in the system + headers.
    @@ -129,8 +136,8 @@
  • Test the newly-installed C frontend by one or more of the following means:

      -
    • compiling and running a "hello, world" program in C or C++.
    • -
    • running the tests under test/Programs using gmake -C +
    • compiling and running a "hello, LLVM" program in C and C++.
    • +
    • running the tests under test/Programs using gmake -C test/Programs

    @@ -142,7 +149,7 @@
    Brian Gaeke
    -Last modified: $Date: 2003/10/23 01:48:33 $ +Last modified: $Date: 2003/10/23 03:55:23 $
    From gaeke at cs.uiuc.edu Wed Oct 22 23:02:01 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed Oct 22 23:02:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/SymbolTable.h Message-ID: <200310230401.XAA00811@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: SymbolTable.h updated: 1.26 -> 1.27 --- Log message: Fix apparent typo in head-of-file comment. --- Diffs of the changes: (+1 -1) Index: llvm/include/llvm/SymbolTable.h diff -u llvm/include/llvm/SymbolTable.h:1.26 llvm/include/llvm/SymbolTable.h:1.27 --- llvm/include/llvm/SymbolTable.h:1.26 Mon Oct 20 15:19:14 2003 +++ llvm/include/llvm/SymbolTable.h Wed Oct 22 23:01:49 2003 @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This file implements a symbol table that has planed broken up by type. +// This file implements a symbol table that has planes broken up by type. // Identical types may have overlapping symbol names as long as they are // distinct. // From lattner at cs.uiuc.edu Wed Oct 22 23:16:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Oct 22 23:16:01 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/External/SPEC/CINT2000/252.eon/Makefile Message-ID: <200310230415.XAA01075@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/External/SPEC/CINT2000/252.eon: Makefile updated: 1.3 -> 1.4 --- Log message: Link in the standard C++ library --- Diffs of the changes: (+3 -3) Index: llvm/test/Programs/External/SPEC/CINT2000/252.eon/Makefile diff -u llvm/test/Programs/External/SPEC/CINT2000/252.eon/Makefile:1.3 llvm/test/Programs/External/SPEC/CINT2000/252.eon/Makefile:1.4 --- llvm/test/Programs/External/SPEC/CINT2000/252.eon/Makefile:1.3 Thu Oct 2 14:45:24 2003 +++ llvm/test/Programs/External/SPEC/CINT2000/252.eon/Makefile Wed Oct 22 23:15:23 2003 @@ -5,9 +5,6 @@ # Yes, we know this is an old crufty C++ benchmark. Don't tell us about it GCC! CPPFLAGS = -Wno-deprecated -Wno-non-template-friend -DHAS_ERRLIST -DSPEC_STDCPP -DNDEBUG -LDFLAGS = -lstdc++ -LIBS = -lsupc++ - Source = $(addprefix $(SPEC_BENCH_DIR)/src/, \ ggCoverageSolidTexture.cc ggPathDielectricMaterial.cc ggBox2.cc \ @@ -53,3 +50,6 @@ mrSolidTexture.cc mrSphere.cc mrSurface.cc mrSurfaceTexture.cc \ mrXYRectangle.cc mrXZRectangle.cc mrYZRectangle.cc myrand.cc) include ../../Makefile.spec +LDFLAGS = -lstdc++ +LIBS = -lstdc++ + From lattner at cs.uiuc.edu Thu Oct 23 00:12:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 00:12:02 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/2003-10-23-InstcombineNullFail.ll Message-ID: <200310230511.AAA08896@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: 2003-10-23-InstcombineNullFail.ll added (r1.1) --- Log message: A new testcase for an instcombine miscompilation! --- Diffs of the changes: (+10 -0) Index: llvm/test/Regression/Transforms/InstCombine/2003-10-23-InstcombineNullFail.ll diff -c /dev/null llvm/test/Regression/Transforms/InstCombine/2003-10-23-InstcombineNullFail.ll:1.1 *** /dev/null Thu Oct 23 00:11:04 2003 --- llvm/test/Regression/Transforms/InstCombine/2003-10-23-InstcombineNullFail.ll Thu Oct 23 00:10:53 2003 *************** *** 0 **** --- 1,10 ---- + ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep false + %X = type { [10 x int], float } + + implementation + + bool %test() { + %A = getelementptr %X* null, long 0, ubyte 0, long 0 + %B = setne int* %A, null + ret bool %B + } From lattner at cs.uiuc.edu Thu Oct 23 00:22:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 00:22:01 2003 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Constants.cpp Message-ID: <200310230521.AAA11110@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Constants.cpp updated: 1.59 -> 1.60 --- Log message: Fix bug: instcombine/2003-10-23-InstcombineNullFail.ll --- Diffs of the changes: (+11 -0) Index: llvm/lib/VMCore/Constants.cpp diff -u llvm/lib/VMCore/Constants.cpp:1.59 llvm/lib/VMCore/Constants.cpp:1.60 --- llvm/lib/VMCore/Constants.cpp:1.59 Tue Oct 21 12:39:59 2003 +++ llvm/lib/VMCore/Constants.cpp Thu Oct 23 00:21:48 2003 @@ -975,6 +975,17 @@ const Type *Ty = GetElementPtrInst::getIndexedType(C->getType(), VIdxList, true); assert(Ty && "GEP indices invalid!"); + + if (C->isNullValue()) { + bool isNull = true; + for (unsigned i = 0, e = IdxList.size(); i != e; ++i) + if (!IdxList[i]->isNullValue()) { + isNull = false; + break; + } + if (isNull) return ConstantPointerNull::get(PointerType::get(Ty)); + } + return getGetElementPtrTy(PointerType::get(Ty), C, IdxList); } From criswell at cs.uiuc.edu Thu Oct 23 09:13:12 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Oct 23 09:13:12 2003 Subject: [llvm-commits] CVS: llvm/test/Makefile Message-ID: <200310231412.JAA08690@choi.cs.uiuc.edu> Changes in directory llvm/test: Makefile updated: 1.46 -> 1.47 --- Log message: Do not report errors if QMTest returns a non-zero value. --- Diffs of the changes: (+2 -2) Index: llvm/test/Makefile diff -u llvm/test/Makefile:1.46 llvm/test/Makefile:1.47 --- llvm/test/Makefile:1.46 Fri Oct 10 19:10:05 2003 +++ llvm/test/Makefile Thu Oct 23 09:11:53 2003 @@ -42,10 +42,10 @@ # Execute the tests # qmtest:: $(LLVM_OBJ_ROOT)/test/tmp register - $(QMTEST) run -O $(LLVM_SRC_ROOT)/test/QMTest/expectations.qmr $(CONTEXT) + -$(QMTEST) run -O $(LLVM_SRC_ROOT)/test/QMTest/expectations.qmr $(CONTEXT) %.t:: $(LLVM_OBJ_ROOT)/test/tmp register - $(QMTEST) run -O $(LLVM_SRC_ROOT)/test/QMTest/expectations.qmr $(CONTEXT) $* + -$(QMTEST) run -O $(LLVM_SRC_ROOT)/test/QMTest/expectations.qmr $(CONTEXT) $* # # Create the temporary directory used by the test suite. From criswell at cs.uiuc.edu Thu Oct 23 10:13:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Oct 23 10:13:01 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/SingleSource/CustomChecked/Makefile Message-ID: <200310231512.KAA13270@choi.cs.uiuc.edu> Changes in directory llvm/test/Programs/SingleSource/CustomChecked: Makefile updated: 1.8 -> 1.9 --- Log message: Added full pathname to programs run with the TestRunner script. --- Diffs of the changes: (+4 -4) Index: llvm/test/Programs/SingleSource/CustomChecked/Makefile diff -u llvm/test/Programs/SingleSource/CustomChecked/Makefile:1.8 llvm/test/Programs/SingleSource/CustomChecked/Makefile:1.9 --- llvm/test/Programs/SingleSource/CustomChecked/Makefile:1.8 Sat Oct 18 01:35:46 2003 +++ llvm/test/Programs/SingleSource/CustomChecked/Makefile Thu Oct 23 10:12:18 2003 @@ -35,19 +35,19 @@ $(PROGRAMS_TO_TEST:%=Output/%.run-lli): \ Output/%.run-lli: Output/%.llvm.bc $(LLI) - -$(TESTRUNR) $(filter $*.%, $(Source)) "$(LLI) $(LLI_OPTS) $<" $@ + -$(TESTRUNR) $(SourceDir)/$(filter $*.%, $(Source)) "$(LLI) $(LLI_OPTS) $<" $@ $(PROGRAMS_TO_TEST:%=Output/%.run-jit): \ Output/%.run-jit: Output/%.llvm.bc $(LLI) - -$(TESTRUNR) $(filter $*.%, $(Source)) "$(LLI) $(JIT_OPTS) $<" $@ + -$(TESTRUNR) $(SourceDir)/$(filter $*.%, $(Source)) "$(LLI) $(JIT_OPTS) $<" $@ $(PROGRAMS_TO_TEST:%=Output/%.run-llc): \ Output/%.run-llc: Output/%.llc - -$(TESTRUNR) $(filter $*.%, $(Source)) "$< $(RUN_OPTIONS)" $@ + -$(TESTRUNR) $(SourceDir)/$(filter $*.%, $(Source)) "$< $(RUN_OPTIONS)" $@ $(PROGRAMS_TO_TEST:%=Output/%.run-cbe): \ Output/%.run-cbe: Output/%.cbe - -$(TESTRUNR) $(filter $*.%, $(Source)) "$< $(RUN_OPTIONS)" $@ + -$(TESTRUNR) $(SourceDir)/$(filter $*.%, $(Source)) "$< $(RUN_OPTIONS)" $@ $(PROGRAMS_TO_TEST:%=Output/%.exe-lli): \ From lattner at cs.uiuc.edu Thu Oct 23 10:44:03 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 10:44:03 2003 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/ExtractFunction.cpp Message-ID: <200310231543.KAA28134@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: ExtractFunction.cpp updated: 1.16 -> 1.17 --- Log message: Fix an assertion failure in Bugpoint --- Diffs of the changes: (+6 -0) Index: llvm/tools/bugpoint/ExtractFunction.cpp diff -u llvm/tools/bugpoint/ExtractFunction.cpp:1.16 llvm/tools/bugpoint/ExtractFunction.cpp:1.17 --- llvm/tools/bugpoint/ExtractFunction.cpp:1.16 Mon Oct 20 12:57:13 2003 +++ llvm/tools/bugpoint/ExtractFunction.cpp Thu Oct 23 10:42:55 2003 @@ -22,6 +22,7 @@ #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/Cloning.h" +#include "llvm/Target/TargetData.h" #include "Support/CommandLine.h" bool DisableSimplifyCFG = false; @@ -72,6 +73,9 @@ // Spiff up the output a little bit. PassManager Passes; + // Make sure that the appropriate target data is always used... + Passes.add(new TargetData("bugpoint", Result)); + if (Simplification > 2 && !NoADCE) Passes.add(createAggressiveDCEPass()); // Remove dead code... //Passes.add(createInstructionCombiningPass()); @@ -104,6 +108,8 @@ I->setLinkage(GlobalValue::ExternalLinkage); PassManager CleanupPasses; + // Make sure that the appropriate target data is always used... + CleanupPasses.add(new TargetData("bugpoint", M)); CleanupPasses.add(createFunctionResolvingPass()); CleanupPasses.add(createGlobalDCEPass()); CleanupPasses.add(createDeadTypeEliminationPass()); From lattner at cs.uiuc.edu Thu Oct 23 10:47:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 10:47:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Analysis/LoopInfo/2003-05-15-NestingProblem.ll Message-ID: <200310231546.KAA28184@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Analysis/LoopInfo: 2003-05-15-NestingProblem.ll updated: 1.1 -> 1.2 --- Log message: Fix buggy test --- Diffs of the changes: (+1 -1) Index: llvm/test/Regression/Analysis/LoopInfo/2003-05-15-NestingProblem.ll diff -u llvm/test/Regression/Analysis/LoopInfo/2003-05-15-NestingProblem.ll:1.1 llvm/test/Regression/Analysis/LoopInfo/2003-05-15-NestingProblem.ll:1.2 --- llvm/test/Regression/Analysis/LoopInfo/2003-05-15-NestingProblem.ll:1.1 Thu May 15 13:03:03 2003 +++ llvm/test/Regression/Analysis/LoopInfo/2003-05-15-NestingProblem.ll Thu Oct 23 10:46:42 2003 @@ -1,7 +1,7 @@ ; This testcase was incorrectly computing that the loopentry.7 loop was ; not a child of the loopentry.6 loop. ; -; RUN: analyze %s -loops | grep "^ Loop Containing: %loopentry.7" +; RUN: analyze %s -loops | grep "^ Loop Containing: %loopentry.7" void %getAndMoveToFrontDecode() { ; No predecessors! br label %endif.2 From lattner at cs.uiuc.edu Thu Oct 23 10:48:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 10:48:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Assembler/2003-04-15-ConstantInitAssertion.llx Message-ID: <200310231547.KAA28222@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Assembler: 2003-04-15-ConstantInitAssertion.llx updated: 1.1 -> 1.2 --- Log message: Fix test --- Diffs of the changes: (+1 -1) Index: llvm/test/Regression/Assembler/2003-04-15-ConstantInitAssertion.llx diff -u llvm/test/Regression/Assembler/2003-04-15-ConstantInitAssertion.llx:1.1 llvm/test/Regression/Assembler/2003-04-15-ConstantInitAssertion.llx:1.2 --- llvm/test/Regression/Assembler/2003-04-15-ConstantInitAssertion.llx:1.1 Tue Apr 15 11:07:05 2003 +++ llvm/test/Regression/Assembler/2003-04-15-ConstantInitAssertion.llx Thu Oct 23 10:47:23 2003 @@ -1,4 +1,4 @@ -; RUN: (as < %s 2>&1) | grep Expected +; RUN: (llvm-as < %s 2>&1) | grep Expected ; Test the case of a misformed constant initializer ; This should cause an assembler error, not an assertion failure! %X = constant {int} { float 1.0 } From lattner at cs.uiuc.edu Thu Oct 23 10:53:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 10:53:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/ADCE/2002-07-29-Segfault.ll Message-ID: <200310231552.KAA28318@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/ADCE: 2002-07-29-Segfault.ll updated: 1.1 -> 1.2 --- Log message: Fix test --- Diffs of the changes: (+1 -1) Index: llvm/test/Regression/Transforms/ADCE/2002-07-29-Segfault.ll diff -u llvm/test/Regression/Transforms/ADCE/2002-07-29-Segfault.ll:1.1 llvm/test/Regression/Transforms/ADCE/2002-07-29-Segfault.ll:1.2 --- llvm/test/Regression/Transforms/ADCE/2002-07-29-Segfault.ll:1.1 Mon Jul 29 14:02:49 2002 +++ llvm/test/Regression/Transforms/ADCE/2002-07-29-Segfault.ll Thu Oct 23 10:51:55 2003 @@ -1,4 +1,4 @@ -; RUN: as < %s | opt -adce +; RUN: llvm-as < %s | opt -adce void "test"() begin From criswell at cs.uiuc.edu Thu Oct 23 10:55:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Oct 23 10:55:01 2003 Subject: [llvm-commits] CVS: llvm/test/QMTest/expectations.qmr Message-ID: <200310231553.KAA14571@choi.cs.uiuc.edu> Changes in directory llvm/test/QMTest: expectations.qmr updated: 1.3 -> 1.4 --- Log message: Bugpoint tests now pass and are now expected to do so. --- Diffs of the changes: (+1 -1) Index: llvm/test/QMTest/expectations.qmr diff -u llvm/test/QMTest/expectations.qmr:1.3 llvm/test/QMTest/expectations.qmr:1.4 --- llvm/test/QMTest/expectations.qmr:1.3 Wed Oct 22 16:52:03 2003 +++ llvm/test/QMTest/expectations.qmr Thu Oct 23 10:53:48 2003 @@ -3,13 +3,13 @@ qoq}q(U _Result__kindqUtestqU_Result__outcomeqUPASSqU_Result__annotationsq}U _Result__idq U0Regression.Assembler.2002-08-16-ConstExprInlinedq U_Result__contextq (cqm.test.context Context -q o}q (U_Context__propertiesq}U_Context__temporariesq}ubub.(hoq}q(hhhhh}h U(Regression.Transforms.PruneEH.simpletestqh (h o}q(h}h}ubub.(hoq}q(hhhhh}h U/Regression.CBackend.2002-08-19-HardConstantExprqh (h o}q(h}h}ubub.(hoq}q(hhhhh}h URegression.Jello.test-shiftqh (h o}q(h}h}ubub.(hoq}q(hhhhh}h U9Regression.Transforms.Mem2Reg.2003-10-05-DeadPHIInsertionqh (h o}q(h}h}ubub.(hoq }q!(hhhUFAILq"h}h U.Regression.Transforms.CorrelatedExprs.looptestq#h (h o}q$(h}h}ubub.(hoq%}q&(hhhhh}h U-Regression.Linker.2003-08-23-GlobalVarLinkingq'h (h o}q((h}h}ubub.(hoq)}q*(hhhhh}h U?Regression.Transforms.Inline.2003-09-22-PHINodesInExceptionDestq+h (h o}q,(h}h}ubub.(hoq-}q.(hhhh"h}h U,Regression.CFrontend.2003-02-12-NonlocalGotoq/h (h o}q0(h}h}ubub.(hoq1}q2(hhhhh}h U2Regression.Transforms.FunctionResolve.retmismatch1q3h (h o}q4(h}h}ubub.(hoq5}q6(hhhhh}h U,Regression.Transforms.DSAnalysis.indcalltes! tq7h (h o}q8(h}h}ubub.(hoq9}q:(hhhhh}h U8Regression.Transforms.ADCE.2003-01-22-PredecessorProblemq;h (h o}q<(h}h}ubub.(hoq=}q>(hhhhh}h U=Regression.Transforms.LevelRaise.2002-10-08-VarArgCallInfLoopq?h (h o}q@(h}h}ubub.(hoqA}qB(hhhhh}h U Regression.Reoptimizer.ticm.ticmqCh (h o}qD(h}h}ubub.(hoqE}qF(hhhhh}h U8Regression.C++Frontend.2003-09-29-ArgumentNumberMismatchqGh (h o}qH(h}h}ubub.(hoqI}qJ(hhhhh}h U+Regression.CFrontend.2002-09-19-StarInLabelqKh (h o}qL(h}h}ubub.(hoqM}qN(hhhhh}h U.Regression.CFrontend.2003-08-23-LocalUnionTestqOh (h o}qP(h}h}ubub.(hoqQ}qR(hhhhh}h U/Regression.Linker.2003-04-26-NullPtrLinkProblemqSh (h o}qT(h}h}ubub.(hoqU}qV(hhhhh}h U)Regression.Transforms.Reassociate.subtestqWh (h o}qX(h}h}ubub.(hoqY}qZ(hhhhh}h U)Regression.Linker.2002-08-20-ConstantExprq[h (h o}q\(h}h}ubub.(hoq]}q^(hhhhh}h U=Regression.Transforms.Reassociate.2002-05-15-AgressiveSubMoveq_h (h o}q`(h}h}ubub.! (hoqa}qb(hhhhh}h UARegression.Transforms.CorrelatedExprs.2002-10 -07-DominatorProblemqch (h o}qd(h}h}ubub.(hoqe}qf(hhhhh}h U3Regression.Transforms.PiNodeInserter.substitutetestqgh (h o}qh(h}h}ubub.(hoqi}qj(hhhhh}h U4Regression.Transforms.SCCP.2003-08-26-InvokeHandlingqkh (h o}ql(h}h}ubub.(hoqm}qn(hhhhh}h U-Regression.CFrontend.2002-02-18-64bitConstantqoh (h o}qp(h}h}ubub.(hoqq}qr(hhhhh}h U1Regression.Assembler.2002-04-04-PureVirtMethCall2qsh (h o}qt(h}h}ubub.(hoqu}qv(hhhhh}h U(Regression.Reoptimizer.BinInterface.testqwh (h o}qx(h}h}ubub.(hoqy}qz(hhhhh}h U(hhhhh}h U8Regression.C++Frontend.2003-09-29-ArgumentNumberMismatchq?h (h o}q@(h}h}ubub.(hoqA}qB(hhhhh}h U+Regression.CFrontend.2002-09-19-StarInLabelqCh (h o}qD(h}h}ubub.(hoqE}qF(hhhhh}h U.Regression.CFrontend.2003-08-23-LocalUnionTestqGh (h o}qH(h}h}ubub.(hoqI}qJ(hhhhh}h U-Regression.C++Frontend.2003-08-28-SaveExprBugqKh (h o}qL(h}h}ubub.(hoqM}qN(hhhhh}h U"Regression.Jello.2003-06-05-PHIBugqOh (h o}qP(h}h}ubub.(hoqQ}qR(hhhhh}h U/Regression.Linker.2003-04-26-NullPtrLinkProblemqSh (h o}qT(h}h}ubub.(hoqU}qV(hhhhh}h U)Regression.Transforms.Reassociate.subtestqWh (h o}qX(h}h}ubub.(hoqY}qZ(hhhhh}h U)Regression.Linker.2002-08-20-ConstantExprq[h (h o}q\(h}h}ubub.(hoq]}q^(hhhhh}h U=Regression.Transforms.Reassociate.2002-05-15-AgressiveSubMoveq_h (h o}q`(h}h}ubub.(! hoqa}qb(hhhhh}h UARegression.Transforms.CorrelatedExprs.2002-10- 07-DominatorProblemqch (h o}qd(h}h}ubub.(hoqe}qf(hhhhh}h U3Regression.Transforms.PiNodeInserter.substitutetestqgh (h o}qh(h}h}ubub.(hoqi}qj(hhhhh}h U4Regression.Transforms.SCCP.2003-08-26-InvokeHandlingqkh (h o}ql(h}h}ubub.(hoqm}qn(hhhhh}h U$Regression.Jello.2003-01-04-LoopTestqoh (h o}qp(h}h}ubub.(hoqq}qr(hhhhh}h U1Regression.Assembler.2002-04-04-PureVirtMethCall2qsh (h o}qt(h}h}ubub.(hoqu}qv(hhhhh}h U)Regression.CFrontend.2002-07-14-MiscTestsqwh (h o}qx(h}h}ubub.(hoqy}qz(hhhhh}h U Changes in directory llvm/test/Regression/Transforms/LowerSetJmp: simpletest.ll updated: 1.2 -> 1.3 --- Log message: fix test --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/LowerSetJmp/simpletest.ll diff -u llvm/test/Regression/Transforms/LowerSetJmp/simpletest.ll:1.2 llvm/test/Regression/Transforms/LowerSetJmp/simpletest.ll:1.3 --- llvm/test/Regression/Transforms/LowerSetJmp/simpletest.ll:1.2 Tue Sep 16 10:29:39 2003 +++ llvm/test/Regression/Transforms/LowerSetJmp/simpletest.ll Thu Oct 23 10:57:45 2003 @@ -8,12 +8,15 @@ declare void %llvm.longjmp(%JmpBuf *%B, int %Val) declare int %llvm.setjmp(%JmpBuf *%B) +declare void %foo() + int %simpletest() { %B = alloca %JmpBuf %Val = call int %llvm.setjmp(%JmpBuf* %B) %V = cast int %Val to bool br bool %V, label %LongJumped, label %Normal Normal: + call void %foo() call void %llvm.longjmp(%JmpBuf* %B, int 42) ret int 0 ;; not reached LongJumped: From criswell at cs.uiuc.edu Thu Oct 23 10:59:03 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Oct 23 10:59:03 2003 Subject: [llvm-commits] CVS: llvm/LICENSE.TXT Message-ID: <200310231558.KAA14598@choi.cs.uiuc.edu> Changes in directory llvm: LICENSE.TXT updated: 1.1 -> 1.2 --- Log message: Added new license information in preparation for LLVM 1.0. --- Diffs of the changes: (+65 -1) Index: llvm/LICENSE.TXT diff -u llvm/LICENSE.TXT:1.1 llvm/LICENSE.TXT:1.2 --- llvm/LICENSE.TXT:1.1 Wed Jun 4 14:46:36 2003 +++ llvm/LICENSE.TXT Thu Oct 23 10:57:59 2003 @@ -1,4 +1,17 @@ -LLVM pre-release license: +NOTICE: +======= +All distributions of LLVM prior to the 1.0 Release will be licensed to you +under the LLVM pre-release license. The 1.0 Release will be announced on the +LLVM Announcements Mailing List. + +After the 1.0 Release of LLVM, the LLVM code will be licensed to you under the +LLVM Release License (aka the Illinois Open Source License). + +The main point is that you cannot re-distribute LLVM until the 1.0 Release. + +============================================================================== +LLVM pre-release license +============================================================================== This is a pre-release distribution of the LLVM software and is provided for evaluation only. This version of the LLVM software or modifications thereof @@ -17,3 +30,54 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. + +============================================================================== +LLVM Release License +============================================================================== +University of Illinois/NCSA +Open Source License + +Copyright ? 2003, University of Illinois at Urbana-Champaign. All rights reserved. + +Developed by: + + LLVM Team + + University of Illinois at Urbana-Champaign + + http://llvm.cs.uiuc.edu + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal with +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimers. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimers in the + documentation and/or other materials provided with the distribution. + + * Neither the names of the LLVM Team, University of Illinois at + Urbana-Champaign, nor the names of its contributors may be used to + endorse or promote products derived from this Software without specific + prior written permission. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE +SOFTWARE. + +============================================================================== +Copyrights and Licenses for Third Party Software Distributed with LLVM: +============================================================================== +The LLVM software contains code written by third parties. Such software will +have its own individual LICENSE.TXT file in the directory in which it appears. +This file will describe the copyrights, license, and restrictions which apply +to that code. From lattner at cs.uiuc.edu Thu Oct 23 11:01:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 11:01:02 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/SingleSource/Regression/C/2003-10-13-PointerIncrementTest.c Message-ID: <200310231600.LAA28468@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/SingleSource/Regression/C: 2003-10-13-PointerIncrementTest.c updated: 1.2 -> 1.3 --- Log message: return zero on success --- Diffs of the changes: (+1 -0) Index: llvm/test/Programs/SingleSource/Regression/C/2003-10-13-PointerIncrementTest.c diff -u llvm/test/Programs/SingleSource/Regression/C/2003-10-13-PointerIncrementTest.c:1.2 llvm/test/Programs/SingleSource/Regression/C/2003-10-13-PointerIncrementTest.c:1.3 --- llvm/test/Programs/SingleSource/Regression/C/2003-10-13-PointerIncrementTest.c:1.2 Mon Oct 13 23:20:04 2003 +++ llvm/test/Programs/SingleSource/Regression/C/2003-10-13-PointerIncrementTest.c Thu Oct 23 11:00:28 2003 @@ -9,4 +9,5 @@ *((int*)Pointer)++; printf("0x%d\n", (int)Pointer-(int)&Array[0]); } + return 0; } From lattner at cs.uiuc.edu Thu Oct 23 11:01:23 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 11:01:23 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/SingleSource/Gizmos/sumarray.c Message-ID: <200310231600.LAA28454@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/SingleSource/Gizmos: sumarray.c updated: 1.1 -> 1.2 --- Log message: Fix test to return 0 on success --- Diffs of the changes: (+3 -1) Index: llvm/test/Programs/SingleSource/Gizmos/sumarray.c diff -u llvm/test/Programs/SingleSource/Gizmos/sumarray.c:1.1 llvm/test/Programs/SingleSource/Gizmos/sumarray.c:1.2 --- llvm/test/Programs/SingleSource/Gizmos/sumarray.c:1.1 Fri Dec 14 10:13:38 2001 +++ llvm/test/Programs/SingleSource/Gizmos/sumarray.c Thu Oct 23 10:59:59 2003 @@ -1,4 +1,5 @@ #include +#include int SumArray(int Array[], int Num) { unsigned i, Result = 0; @@ -19,5 +20,6 @@ for (i = 1; i < 100; i += 2) Array[i] = i*2; - return SumArray(Array, 100); + printf("Produced: %d\n", SumArray(Array, 100)); + return 0; } From lattner at cs.uiuc.edu Thu Oct 23 11:02:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 11:02:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/FunctionResolve/2003-05-31-InternalDecl.ll Message-ID: <200310231601.LAA28506@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/FunctionResolve: 2003-05-31-InternalDecl.ll updated: 1.3 -> 1.4 --- Log message: Update test --- Diffs of the changes: (+1 -1) Index: llvm/test/Regression/Transforms/FunctionResolve/2003-05-31-InternalDecl.ll diff -u llvm/test/Regression/Transforms/FunctionResolve/2003-05-31-InternalDecl.ll:1.3 llvm/test/Regression/Transforms/FunctionResolve/2003-05-31-InternalDecl.ll:1.4 --- llvm/test/Regression/Transforms/FunctionResolve/2003-05-31-InternalDecl.ll:1.3 Tue Sep 16 10:29:26 2003 +++ llvm/test/Regression/Transforms/FunctionResolve/2003-05-31-InternalDecl.ll Thu Oct 23 11:01:03 2003 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | opt -funcresolve | llvm-dis | not grep declare +; RUN: llvm-as < %s | opt -funcresolve | llvm-dis | grep declare declare void %test(...) From lattner at cs.uiuc.edu Thu Oct 23 11:02:13 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 11:02:13 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/CBackend/2002-08-26-IndirectCallTest.ll Message-ID: <200310231601.LAA28499@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CBackend: 2002-08-26-IndirectCallTest.ll updated: 1.1 -> 1.2 --- Log message: Update test --- Diffs of the changes: (+2 -2) Index: llvm/test/Regression/CBackend/2002-08-26-IndirectCallTest.ll diff -u llvm/test/Regression/CBackend/2002-08-26-IndirectCallTest.ll:1.1 llvm/test/Regression/CBackend/2002-08-26-IndirectCallTest.ll:1.2 --- llvm/test/Regression/CBackend/2002-08-26-IndirectCallTest.ll:1.1 Mon Aug 26 15:49:42 2002 +++ llvm/test/Regression/CBackend/2002-08-26-IndirectCallTest.ll Thu Oct 23 11:01:02 2003 @@ -5,8 +5,8 @@ void %test(int %X) { %Y = add int %X, -1 ; :1 [#uses=3] - %cast100 = cast int %Y to uint ; [#uses=1] - %gep100 = getelementptr int** %taskArray, uint %cast100 ; [#uses=1] + %cast100 = cast int %Y to long ; [#uses=1] + %gep100 = getelementptr int** %taskArray, long %cast100 ; [#uses=1] %fooPtr = load int** %gep100 ; [#uses=1] %cast101 = cast int* %fooPtr to void (int)* ; [#uses=1] call void %cast101( int 1000 ) From lattner at cs.uiuc.edu Thu Oct 23 11:02:24 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 11:02:24 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/2003-10-23-InstcombineNullFail.ll Message-ID: <200310231601.LAA28490@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: 2003-10-23-InstcombineNullFail.ll updated: 1.1 -> 1.2 --- Log message: document real source of bug --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/Transforms/InstCombine/2003-10-23-InstcombineNullFail.ll diff -u llvm/test/Regression/Transforms/InstCombine/2003-10-23-InstcombineNullFail.ll:1.1 llvm/test/Regression/Transforms/InstCombine/2003-10-23-InstcombineNullFail.ll:1.2 --- llvm/test/Regression/Transforms/InstCombine/2003-10-23-InstcombineNullFail.ll:1.1 Thu Oct 23 00:10:53 2003 +++ llvm/test/Regression/Transforms/InstCombine/2003-10-23-InstcombineNullFail.ll Thu Oct 23 11:00:59 2003 @@ -1,4 +1,7 @@ ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep false +; +; This actually looks like a constant propagation bug + %X = type { [10 x int], float } implementation From brukman at cs.uiuc.edu Thu Oct 23 11:20:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Oct 23 11:20:01 2003 Subject: [llvm-commits] CVS: llvm/LICENSE.TXT Message-ID: <200310231619.LAA29368@zion.cs.uiuc.edu> Changes in directory llvm: LICENSE.TXT updated: 1.2 -> 1.3 --- Log message: * Stop referring to llvmbugs mailing list, point them to Bugzilla * Use ASCII (c) instead of the special character, which may not display correctly for everyone * Wrap at 80 columns --- Diffs of the changes: (+7 -5) Index: llvm/LICENSE.TXT diff -u llvm/LICENSE.TXT:1.2 llvm/LICENSE.TXT:1.3 --- llvm/LICENSE.TXT:1.2 Thu Oct 23 10:57:59 2003 +++ llvm/LICENSE.TXT Thu Oct 23 11:18:51 2003 @@ -18,10 +18,11 @@ should not be distributed to third parties for any purpose. Any third parties interested in it can request a copy directly by sending e-mail to llvmdev at cs.uiuc.edu. As this is an evaluation release, we would appreciate any -and all feedback, ideas, and reports of bugs that you encounter. These can be -submitted through the llvmbugs at cs.uiuc.edu or llvmdev at cs.uiuc.edu mailing lists -as appropriate. We thank you for your interest in LLVM and look forward to any -comments or feedback you may have. +and all feedback, ideas, and reports of bugs that you encounter. You may +discuss development of LLVM on llvmdev at cs.uiuc.edu, and bugs can be submitted +through the LLVM Bug Tracker at http://llvm.cs.uiuc.edu/bugzilla/ . We thank +you for your interest in LLVM and look forward to any comments or feedback you +may have. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS @@ -37,7 +38,8 @@ University of Illinois/NCSA Open Source License -Copyright ? 2003, University of Illinois at Urbana-Champaign. All rights reserved. +Copyright (c) 2003, University of Illinois at Urbana-Champaign. All rights +reserved. Developed by: From brukman at cs.uiuc.edu Thu Oct 23 11:23:02 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Oct 23 11:23:02 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200310231622.LAA30015@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.136 -> 1.137 --- Log message: * Order includes according to style guide * Convert tabs to spaces * Make code fit within 80 columns --- Diffs of the changes: (+106 -105) Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.136 llvm/lib/Target/X86/InstSelectSimple.cpp:1.137 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.136 Mon Oct 20 14:43:18 2003 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Thu Oct 23 11:22:08 2003 @@ -12,21 +12,21 @@ //===----------------------------------------------------------------------===// #include "X86.h" -#include "X86InstrInfo.h" #include "X86InstrBuilder.h" +#include "X86InstrInfo.h" +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" #include "llvm/Function.h" #include "llvm/Instructions.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Constants.h" -#include "llvm/Pass.h" #include "llvm/Intrinsics.h" +#include "llvm/Pass.h" +#include "llvm/CodeGen/MachineConstantPool.h" +#include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/SSARegMap.h" -#include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/CodeGen/MachineConstantPool.h" -#include "llvm/Target/TargetMachine.h" #include "llvm/Target/MRegisterInfo.h" +#include "llvm/Target/TargetMachine.h" #include "llvm/Support/InstVisitor.h" /// BMI - A special BuildMI variant that takes an iterator to insert the @@ -136,7 +136,7 @@ ValueRecord(Value *V) : Val(V), Reg(0), Ty(V->getType()) {} }; void doCall(const ValueRecord &Ret, MachineInstr *CallMI, - const std::vector &Args); + const std::vector &Args); void visitCallInst(CallInst &I); void visitIntrinsicCall(LLVMIntrinsic::ID ID, CallInst &I); @@ -146,7 +146,7 @@ void visitSub(BinaryOperator &B) { visitSimpleBinary(B, 1); } void doMultiply(MachineBasicBlock *MBB, MachineBasicBlock::iterator &MBBI, unsigned DestReg, const Type *DestTy, - unsigned Op0Reg, unsigned Op1Reg); + unsigned Op0Reg, unsigned Op1Reg); void doMultiplyConst(MachineBasicBlock *MBB, MachineBasicBlock::iterator &MBBI, unsigned DestReg, const Type *DestTy, @@ -244,11 +244,11 @@ const X86RegisterInfo *MRI = static_cast(TM.getRegisterInfo()); if (Ty == Type::LongTy || Ty == Type::ULongTy) { - const TargetRegisterClass *RC = MRI->getRegClassForType(Type::IntTy); - // Create the lower part - F->getSSARegMap()->createVirtualRegister(RC); - // Create the upper part. - return F->getSSARegMap()->createVirtualRegister(RC)-1; + const TargetRegisterClass *RC = MRI->getRegClassForType(Type::IntTy); + // Create the lower part + F->getSSARegMap()->createVirtualRegister(RC); + // Create the upper part. + return F->getSSARegMap()->createVirtualRegister(RC)-1; } // Add the mapping of regnumber => reg class to MachineFunction @@ -464,12 +464,12 @@ case cFP: unsigned Opcode; if (I->getType() == Type::FloatTy) { - Opcode = X86::FLDr32; - FI = MFI->CreateFixedObject(4, ArgOffset); + Opcode = X86::FLDr32; + FI = MFI->CreateFixedObject(4, ArgOffset); } else { - Opcode = X86::FLDr64; - FI = MFI->CreateFixedObject(8, ArgOffset); - ArgOffset += 4; // doubles require 4 additional bytes + Opcode = X86::FLDr64; + FI = MFI->CreateFixedObject(8, ArgOffset); + ArgOffset += 4; // doubles require 4 additional bytes } addFrameReference(BuildMI(BB, Opcode, 4, Reg), FI); break; @@ -510,8 +510,8 @@ MachineInstr *LongPhiMI = 0; if (PN->getType() == Type::LongTy || PN->getType() == Type::ULongTy) { - LongPhiMI = BuildMI(X86::PHI, PN->getNumOperands(), PHIReg+1); - MBB->insert(MBB->begin()+NumPHIs++, LongPhiMI); + LongPhiMI = BuildMI(X86::PHI, PN->getNumOperands(), PHIReg+1); + MBB->insert(MBB->begin()+NumPHIs++, LongPhiMI); } // PHIValues - Map of blocks to incoming virtual registers. We use this @@ -558,12 +558,12 @@ PHIValues.insert(EntryIt, std::make_pair(PredMBB, ValReg)); } - PhiMI->addRegOperand(ValReg); + PhiMI->addRegOperand(ValReg); PhiMI->addMachineBasicBlockOperand(PredMBB); - if (LongPhiMI) { - LongPhiMI->addRegOperand(ValReg+1); - LongPhiMI->addMachineBasicBlockOperand(PredMBB); - } + if (LongPhiMI) { + LongPhiMI->addRegOperand(ValReg+1); + LongPhiMI->addMachineBasicBlockOperand(PredMBB); + } } } } @@ -826,7 +826,8 @@ BuildMI(BB, X86::MOVrr32, 1, X86::EAX).addReg(RetReg); BuildMI(BB, X86::MOVrr32, 1, X86::EDX).addReg(RetReg+1); // Declare that EAX & EDX are live on exit - BuildMI(BB, X86::IMPLICIT_USE, 3).addReg(X86::EAX).addReg(X86::EDX).addReg(X86::ESP); + BuildMI(BB, X86::IMPLICIT_USE, 3).addReg(X86::EAX).addReg(X86::EDX) + .addReg(X86::ESP); break; default: visitInstruction(I); @@ -877,7 +878,7 @@ unsigned OpNum = getSetCCNumber(SCI->getOpcode()); MachineBasicBlock::iterator MII = BB->end(); - OpNum = EmitComparison(OpNum, SCI->getOperand(0), SCI->getOperand(1), BB, MII); + OpNum = EmitComparison(OpNum, SCI->getOperand(0), SCI->getOperand(1), BB,MII); const Type *CompTy = SCI->getOperand(0)->getType(); bool isSigned = CompTy->isSigned() && getClassB(CompTy) != cFP; @@ -920,7 +921,7 @@ /// it inserts the specified CallMI instruction into the stream. /// void ISel::doCall(const ValueRecord &Ret, MachineInstr *CallMI, - const std::vector &Args) { + const std::vector &Args) { // Count how many bytes are to be pushed on the stack... unsigned NumBytes = 0; @@ -929,12 +930,12 @@ for (unsigned i = 0, e = Args.size(); i != e; ++i) switch (getClassB(Args[i].Ty)) { case cByte: case cShort: case cInt: - NumBytes += 4; break; + NumBytes += 4; break; case cLong: - NumBytes += 8; break; + NumBytes += 8; break; case cFP: - NumBytes += Args[i].Ty == Type::FloatTy ? 4 : 8; - break; + NumBytes += Args[i].Ty == Type::FloatTy ? 4 : 8; + break; default: assert(0 && "Unknown class!"); } @@ -948,36 +949,36 @@ switch (getClassB(Args[i].Ty)) { case cByte: case cShort: { - // Promote arg to 32 bits wide into a temporary register... - unsigned R = makeAnotherReg(Type::UIntTy); - promote32(R, Args[i]); - addRegOffset(BuildMI(BB, X86::MOVrm32, 5), - X86::ESP, ArgOffset).addReg(R); - break; + // Promote arg to 32 bits wide into a temporary register... + unsigned R = makeAnotherReg(Type::UIntTy); + promote32(R, Args[i]); + addRegOffset(BuildMI(BB, X86::MOVrm32, 5), + X86::ESP, ArgOffset).addReg(R); + break; } case cInt: - addRegOffset(BuildMI(BB, X86::MOVrm32, 5), - X86::ESP, ArgOffset).addReg(ArgReg); - break; + addRegOffset(BuildMI(BB, X86::MOVrm32, 5), + X86::ESP, ArgOffset).addReg(ArgReg); + break; case cLong: - addRegOffset(BuildMI(BB, X86::MOVrm32, 5), - X86::ESP, ArgOffset).addReg(ArgReg); - addRegOffset(BuildMI(BB, X86::MOVrm32, 5), - X86::ESP, ArgOffset+4).addReg(ArgReg+1); - ArgOffset += 4; // 8 byte entry, not 4. - break; - + addRegOffset(BuildMI(BB, X86::MOVrm32, 5), + X86::ESP, ArgOffset).addReg(ArgReg); + addRegOffset(BuildMI(BB, X86::MOVrm32, 5), + X86::ESP, ArgOffset+4).addReg(ArgReg+1); + ArgOffset += 4; // 8 byte entry, not 4. + break; + case cFP: - if (Args[i].Ty == Type::FloatTy) { - addRegOffset(BuildMI(BB, X86::FSTr32, 5), - X86::ESP, ArgOffset).addReg(ArgReg); - } else { - assert(Args[i].Ty == Type::DoubleTy && "Unknown FP type!"); - addRegOffset(BuildMI(BB, X86::FSTr64, 5), - X86::ESP, ArgOffset).addReg(ArgReg); - ArgOffset += 4; // 8 byte entry, not 4. - } - break; + if (Args[i].Ty == Type::FloatTy) { + addRegOffset(BuildMI(BB, X86::FSTr32, 5), + X86::ESP, ArgOffset).addReg(ArgReg); + } else { + assert(Args[i].Ty == Type::DoubleTy && "Unknown FP type!"); + addRegOffset(BuildMI(BB, X86::FSTr64, 5), + X86::ESP, ArgOffset).addReg(ArgReg); + ArgOffset += 4; // 8 byte entry, not 4. + } + break; default: assert(0 && "Unknown class!"); } @@ -1003,7 +1004,7 @@ // Integral results are in %eax, or the appropriate portion // thereof. static const unsigned regRegMove[] = { - X86::MOVrr8, X86::MOVrr16, X86::MOVrr32 + X86::MOVrr8, X86::MOVrr16, X86::MOVrr32 }; static const unsigned AReg[] = { X86::AL, X86::AX, X86::EAX }; BuildMI(BB, regRegMove[DestClass], 1, Ret.Reg).addReg(AReg[DestClass]); @@ -1045,7 +1046,7 @@ unsigned DestReg = CI.getType() != Type::VoidTy ? getReg(CI) : 0; doCall(ValueRecord(DestReg, CI.getType()), TheCall, Args); -} +} void ISel::visitIntrinsicCall(LLVMIntrinsic::ID ID, CallInst &CI) { @@ -1320,14 +1321,14 @@ unsigned AHBLplusOverflowReg = makeAnotherReg(Type::UIntTy); BuildMI(BB, X86::ADDrr32, 2, // AH*BL+(AL*BL >> 32) - AHBLplusOverflowReg).addReg(AHBLReg).addReg(OverflowReg); + AHBLplusOverflowReg).addReg(AHBLReg).addReg(OverflowReg); MBBI = BB->end(); unsigned ALBHReg = makeAnotherReg(Type::UIntTy); // AL*BH BMI(BB, MBBI, X86::IMULrr32, 2, ALBHReg).addReg(Op0Reg).addReg(Op1Reg+1); BuildMI(BB, X86::ADDrr32, 2, // AL*BH + AH*BL + (AL*BL >> 32) - DestReg+1).addReg(AHBLplusOverflowReg).addReg(ALBHReg); + DestReg+1).addReg(AHBLplusOverflowReg).addReg(ALBHReg); } } @@ -1349,7 +1350,7 @@ BuildMI(BB, X86::FpDIV, 2, ResultReg).addReg(Op0Reg).addReg(Op1Reg); } else { // Floating point remainder... MachineInstr *TheCall = - BuildMI(X86::CALLpcrel32, 1).addExternalSymbol("fmod", true); + BuildMI(X86::CALLpcrel32, 1).addExternalSymbol("fmod", true); std::vector Args; Args.push_back(ValueRecord(I.getOperand(0))); Args.push_back(ValueRecord(I.getOperand(1))); @@ -1451,26 +1452,26 @@ if (ConstantUInt *CUI = dyn_cast(I.getOperand(1))) { unsigned Amount = CUI->getValue(); if (Amount < 32) { - const unsigned *Opc = ConstantOperand[isLeftShift*2+isSigned]; - if (isLeftShift) { - BuildMI(BB, Opc[3], 3, - DestReg+1).addReg(SrcReg+1).addReg(SrcReg).addZImm(Amount); - BuildMI(BB, Opc[2], 2, DestReg).addReg(SrcReg).addZImm(Amount); - } else { - BuildMI(BB, Opc[3], 3, - DestReg).addReg(SrcReg ).addReg(SrcReg+1).addZImm(Amount); - BuildMI(BB, Opc[2], 2, DestReg+1).addReg(SrcReg+1).addZImm(Amount); - } + const unsigned *Opc = ConstantOperand[isLeftShift*2+isSigned]; + if (isLeftShift) { + BuildMI(BB, Opc[3], 3, + DestReg+1).addReg(SrcReg+1).addReg(SrcReg).addZImm(Amount); + BuildMI(BB, Opc[2], 2, DestReg).addReg(SrcReg).addZImm(Amount); + } else { + BuildMI(BB, Opc[3], 3, + DestReg).addReg(SrcReg ).addReg(SrcReg+1).addZImm(Amount); + BuildMI(BB, Opc[2], 2, DestReg+1).addReg(SrcReg+1).addZImm(Amount); + } } else { // Shifting more than 32 bits - Amount -= 32; - if (isLeftShift) { - BuildMI(BB, X86::SHLir32, 2,DestReg+1).addReg(SrcReg).addZImm(Amount); - BuildMI(BB, X86::MOVir32, 1,DestReg ).addZImm(0); - } else { - unsigned Opcode = isSigned ? X86::SARir32 : X86::SHRir32; - BuildMI(BB, Opcode, 2, DestReg).addReg(SrcReg+1).addZImm(Amount); - BuildMI(BB, X86::MOVir32, 1, DestReg+1).addZImm(0); - } + Amount -= 32; + if (isLeftShift) { + BuildMI(BB, X86::SHLir32, 2,DestReg+1).addReg(SrcReg).addZImm(Amount); + BuildMI(BB, X86::MOVir32, 1,DestReg ).addZImm(0); + } else { + unsigned Opcode = isSigned ? X86::SARir32 : X86::SHRir32; + BuildMI(BB, Opcode, 2, DestReg).addReg(SrcReg+1).addZImm(Amount); + BuildMI(BB, X86::MOVir32, 1, DestReg+1).addZImm(0); + } } } else { unsigned TmpReg = makeAnotherReg(Type::IntTy); @@ -1697,17 +1698,17 @@ BMI(BB, IP, RegRegMove[SrcClass], 1, DestReg).addReg(SrcReg); } else if (SrcClass == cFP) { if (SrcTy == Type::FloatTy) { // double -> float - assert(DestTy == Type::DoubleTy && "Unknown cFP member!"); - BMI(BB, IP, X86::FpMOV, 1, DestReg).addReg(SrcReg); + assert(DestTy == Type::DoubleTy && "Unknown cFP member!"); + BMI(BB, IP, X86::FpMOV, 1, DestReg).addReg(SrcReg); } else { // float -> double - assert(SrcTy == Type::DoubleTy && DestTy == Type::FloatTy && - "Unknown cFP member!"); - // Truncate from double to float by storing to memory as short, then - // reading it back. - unsigned FltAlign = TM.getTargetData().getFloatAlignment(); + assert(SrcTy == Type::DoubleTy && DestTy == Type::FloatTy && + "Unknown cFP member!"); + // Truncate from double to float by storing to memory as short, then + // reading it back. + unsigned FltAlign = TM.getTargetData().getFloatAlignment(); int FrameIdx = F->getFrameInfo()->CreateStackObject(4, FltAlign); - addFrameReference(BMI(BB, IP, X86::FSTr32, 5), FrameIdx).addReg(SrcReg); - addFrameReference(BMI(BB, IP, X86::FLDr32, 5, DestReg), FrameIdx); + addFrameReference(BMI(BB, IP, X86::FSTr32, 5), FrameIdx).addReg(SrcReg); + addFrameReference(BMI(BB, IP, X86::FLDr32, 5, DestReg), FrameIdx); } } else if (SrcClass == cLong) { BMI(BB, IP, X86::MOVrr32, 1, DestReg).addReg(SrcReg); @@ -1737,9 +1738,9 @@ if (isLong) { // Handle upper 32 bits as appropriate... if (isUnsigned) // Zero out top bits... - BMI(BB, IP, X86::MOVir32, 1, DestReg+1).addZImm(0); + BMI(BB, IP, X86::MOVir32, 1, DestReg+1).addZImm(0); else // Sign extend bottom half... - BMI(BB, IP, X86::SARir32, 2, DestReg+1).addReg(DestReg).addZImm(31); + BMI(BB, IP, X86::SARir32, 2, DestReg+1).addReg(DestReg).addZImm(31); } return; } @@ -1816,7 +1817,7 @@ if (SrcClass == cLong) { addFrameReference(BMI(BB, IP, X86::MOVrm32, 5), FrameIdx).addReg(SrcReg); addFrameReference(BMI(BB, IP, X86::MOVrm32, 5), - FrameIdx, 4).addReg(SrcReg+1); + FrameIdx, 4).addReg(SrcReg+1); } else { static const unsigned Op1[] = { X86::MOVrm8, X86::MOVrm16, X86::MOVrm32 }; addFrameReference(BMI(BB, IP, Op1[SrcClass], 5), FrameIdx).addReg(SrcReg); @@ -1848,7 +1849,7 @@ // Restore the memory image of control word to original value addFrameReference(BMI(BB, IP, X86::MOVrm8, 5), - CWFrameIdx, 1).addReg(HighPartOfCW); + CWFrameIdx, 1).addReg(HighPartOfCW); // We don't have the facilities for directly storing byte sized data to // memory. Promote it to 16 bits. We also must promote unsigned values to @@ -1973,7 +1974,7 @@ // which names the field. This index must have ubyte type. const ConstantUInt *CUI = cast(idx); assert(CUI->getType() == Type::UByteTy - && "Funny-looking structure index in GEP"); + && "Funny-looking structure index in GEP"); // Use the TargetData structure to pick out what the layout of // the structure is in memory. Since the structure index must // be constant, we can get its value and use it to find the @@ -1982,9 +1983,9 @@ unsigned idxValue = CUI->getValue(); unsigned FieldOff = TD.getStructLayout(StTy)->MemberOffsets[idxValue]; if (FieldOff) { - NextReg = makeAnotherReg(Type::UIntTy); - // Emit an ADD to add FieldOff to the basePtr. - BMI(MBB, IP, X86::ADDri32, 2,NextReg).addReg(BaseReg).addZImm(FieldOff); + NextReg = makeAnotherReg(Type::UIntTy); + // Emit an ADD to add FieldOff to the basePtr. + BMI(MBB, IP, X86::ADDri32, 2,NextReg).addReg(BaseReg).addZImm(FieldOff); } // The next type is the member of the structure selected by the // index. @@ -2014,13 +2015,13 @@ if (ConstantSInt *CSI = dyn_cast(idx)) { if (!CSI->isNullValue()) { unsigned Offset = elementSize*CSI->getValue(); - NextReg = makeAnotherReg(Type::UIntTy); + NextReg = makeAnotherReg(Type::UIntTy); BMI(MBB, IP, X86::ADDri32, 2,NextReg).addReg(BaseReg).addZImm(Offset); } } else if (elementSize == 1) { // If the element size is 1, we don't have to multiply, just add unsigned idxReg = getReg(idx, MBB, IP); - NextReg = makeAnotherReg(Type::UIntTy); + NextReg = makeAnotherReg(Type::UIntTy); BMI(MBB, IP, X86::ADDrr32, 2, NextReg).addReg(BaseReg).addReg(idxReg); } else { unsigned idxReg = getReg(idx, MBB, IP); @@ -2029,7 +2030,7 @@ doMultiplyConst(MBB, IP, OffsetReg, Type::IntTy, idxReg, elementSize); // Emit an ADD to add OffsetReg to the basePtr. - NextReg = makeAnotherReg(Type::UIntTy); + NextReg = makeAnotherReg(Type::UIntTy); BMI(MBB, IP, X86::ADDrr32, 2,NextReg).addReg(BaseReg).addReg(OffsetReg); } } @@ -2116,7 +2117,7 @@ std::vector Args; Args.push_back(ValueRecord(Arg, Type::UIntTy)); MachineInstr *TheCall = BuildMI(X86::CALLpcrel32, - 1).addExternalSymbol("malloc", true); + 1).addExternalSymbol("malloc", true); doCall(ValueRecord(getReg(I), I.getType()), TheCall, Args); } @@ -2128,7 +2129,7 @@ std::vector Args; Args.push_back(ValueRecord(I.getOperand(0))); MachineInstr *TheCall = BuildMI(X86::CALLpcrel32, - 1).addExternalSymbol("free", true); + 1).addExternalSymbol("free", true); doCall(ValueRecord(0, Type::VoidTy), TheCall, Args); } From lattner at cs.uiuc.edu Thu Oct 23 11:30:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 11:30:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineConstantPool.h Message-ID: <200310231629.LAA31376@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineConstantPool.h updated: 1.2 -> 1.3 --- Log message: Actually share constants local to a function! --- Diffs of the changes: (+7 -2) Index: llvm/include/llvm/CodeGen/MachineConstantPool.h diff -u llvm/include/llvm/CodeGen/MachineConstantPool.h:1.2 llvm/include/llvm/CodeGen/MachineConstantPool.h:1.3 --- llvm/include/llvm/CodeGen/MachineConstantPool.h:1.2 Mon Oct 20 15:19:23 2003 +++ llvm/include/llvm/CodeGen/MachineConstantPool.h Thu Oct 23 11:29:12 2003 @@ -30,10 +30,15 @@ public: /// getConstantPoolIndex - Create a new entry in the constant pool or return - /// an existing one. This should eventually allow sharing of duplicate - /// objects in the constant pool, but this is adequate for now. + /// an existing one. /// unsigned getConstantPoolIndex(Constant *C) { + // Check to see if we already have this constant. + // + // FIXME, this could be made much more efficient for large constant pools. + for (unsigned i = 0, e = Constants.size(); i != e; ++i) + if (Constants[i] == C) + return i; Constants.push_back(C); return Constants.size()-1; } From lattner at cs.uiuc.edu Thu Oct 23 11:49:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 11:49:01 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/Benchmarks/McCat/08-main/main.c Message-ID: <200310231648.LAA32539@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/Benchmarks/McCat/08-main: main.c updated: 1.1 -> 1.2 --- Log message: Fix floating point precision problem --- Diffs of the changes: (+2 -2) Index: llvm/test/Programs/MultiSource/Benchmarks/McCat/08-main/main.c diff -u llvm/test/Programs/MultiSource/Benchmarks/McCat/08-main/main.c:1.1 llvm/test/Programs/MultiSource/Benchmarks/McCat/08-main/main.c:1.2 --- llvm/test/Programs/MultiSource/Benchmarks/McCat/08-main/main.c:1.1 Mon May 12 13:26:43 2003 +++ llvm/test/Programs/MultiSource/Benchmarks/McCat/08-main/main.c Thu Oct 23 11:48:47 2003 @@ -80,8 +80,8 @@ /*printf("MakeSphere");*/ dfi = 2*PI/sli; /* The step in the slices */ dtheta = 2*PI/pol; /* The step in the amount of polys in a slice */ - for(fi=-PI;fi Changes in directory llvm/lib/Target/Sparc: SparcInstrSelection.cpp updated: 1.125 -> 1.126 --- Log message: Make code layout more consistent. --- Diffs of the changes: (+54 -58) Index: llvm/lib/Target/Sparc/SparcInstrSelection.cpp diff -u llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.125 llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.126 --- llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.125 Wed Oct 22 00:09:56 2003 +++ llvm/lib/Target/Sparc/SparcInstrSelection.cpp Thu Oct 23 11:48:30 2003 @@ -1541,22 +1541,19 @@ // Let's check for chain rules outside the switch so that we don't have // to duplicate the list of chain rule production numbers here again // - if (ThisIsAChainRule(ruleForNode)) - { - // Chain rules have a single nonterminal on the RHS. - // Get the rule that matches the RHS non-terminal and use that instead. - // - assert(nts[0] && ! nts[1] - && "A chain rule should have only one RHS non-terminal!"); - nextRule = burm_rule(subtreeRoot->state, nts[0]); - nts = burm_nts[nextRule]; - GetInstructionsByRule(subtreeRoot, nextRule, nts, target, mvec); - } - else - { - switch(ruleForNode) { - case 1: // stmt: Ret - case 2: // stmt: RetValue(reg) + if (ThisIsAChainRule(ruleForNode)) { + // Chain rules have a single nonterminal on the RHS. + // Get the rule that matches the RHS non-terminal and use that instead. + // + assert(nts[0] && ! nts[1] + && "A chain rule should have only one RHS non-terminal!"); + nextRule = burm_rule(subtreeRoot->state, nts[0]); + nts = burm_nts[nextRule]; + GetInstructionsByRule(subtreeRoot, nextRule, nts, target, mvec); + } else { + switch(ruleForNode) { + case 1: // stmt: Ret + case 2: // stmt: RetValue(reg) { // NOTE: Prepass of register allocation is responsible // for moving return value to appropriate register. // Copy the return value to the required return register. @@ -2192,11 +2189,11 @@ mvec.push_back(BuildMI(V9::ANDNr, 3).addReg(lhs).addReg(notArg) .addReg(dest, MOTy::Def)); - if (notArg->getType() == Type::BoolTy) - { // set 1 in result register if result of above is non-zero - mvec.push_back(BuildMI(V9::MOVRNZi, 3).addReg(dest).addZImm(1) - .addReg(dest, MOTy::UseAndDef)); - } + if (notArg->getType() == Type::BoolTy) { + // set 1 in result register if result of above is non-zero + mvec.push_back(BuildMI(V9::MOVRNZi, 3).addReg(dest).addZImm(1) + .addReg(dest, MOTy::UseAndDef)); + } break; } @@ -2223,11 +2220,11 @@ mvec.push_back(BuildMI(V9::ORNr, 3).addReg(lhs).addReg(notArg) .addReg(dest, MOTy::Def)); - if (notArg->getType() == Type::BoolTy) - { // set 1 in result register if result of above is non-zero - mvec.push_back(BuildMI(V9::MOVRNZi, 3).addReg(dest).addZImm(1) - .addReg(dest, MOTy::UseAndDef)); - } + if (notArg->getType() == Type::BoolTy) { + // set 1 in result register if result of above is non-zero + mvec.push_back(BuildMI(V9::MOVRNZi, 3).addReg(dest).addZImm(1) + .addReg(dest, MOTy::UseAndDef)); + } break; } @@ -2253,11 +2250,11 @@ mvec.push_back(BuildMI(V9::XNORr, 3).addReg(lhs).addReg(notArg) .addReg(dest, MOTy::Def)); - if (notArg->getType() == Type::BoolTy) - { // set 1 in result register if result of above is non-zero - mvec.push_back(BuildMI(V9::MOVRNZi, 3).addReg(dest).addZImm(1) - .addReg(dest, MOTy::UseAndDef)); - } + if (notArg->getType() == Type::BoolTy) { + // set 1 in result register if result of above is non-zero + mvec.push_back(BuildMI(V9::MOVRNZi, 3).addReg(dest).addZImm(1) + .addReg(dest, MOTy::UseAndDef)); + } break; } @@ -2278,37 +2275,36 @@ bool computeBoolVal = (subtreeRoot->parent() == NULL || ! AllUsesAreBranches(setCCInstr)); - if (computeBoolVal) - { - InstrTreeNode* constNode = subtreeRoot->rightChild(); - assert(constNode && - constNode->getNodeType() ==InstrTreeNode::NTConstNode); - Constant *constVal = cast(constNode->getValue()); - bool isValidConst; - - if ((constVal->getType()->isInteger() - || isa(constVal->getType())) - && target.getInstrInfo().ConvertConstantToIntType(target, + if (computeBoolVal) { + InstrTreeNode* constNode = subtreeRoot->rightChild(); + assert(constNode && + constNode->getNodeType() ==InstrTreeNode::NTConstNode); + Constant *constVal = cast(constNode->getValue()); + bool isValidConst; + + if ((constVal->getType()->isInteger() + || isa(constVal->getType())) + && target.getInstrInfo().ConvertConstantToIntType(target, constVal, constVal->getType(), isValidConst) == 0 - && isValidConst) - { - // That constant is an integer zero after all... - // Use a MOVR[op] to compute the boolean result - // Unconditionally set register to 0 - mvec.push_back(BuildMI(V9::SETHI, 2).addZImm(0) - .addRegDef(setCCInstr)); + && isValidConst) + { + // That constant is an integer zero after all... + // Use a MOVR[op] to compute the boolean result + // Unconditionally set register to 0 + mvec.push_back(BuildMI(V9::SETHI, 2).addZImm(0) + .addRegDef(setCCInstr)); - // Now conditionally move 1 into the register. - // Mark the register as a use (as well as a def) because the old - // value will be retained if the condition is false. - MachineOpCode movOpCode = ChooseMovpregiForSetCC(subtreeRoot); - mvec.push_back(BuildMI(movOpCode, 3) - .addReg(subtreeRoot->leftChild()->getValue()) - .addZImm(1).addReg(setCCInstr, MOTy::UseAndDef)); + // Now conditionally move 1 into the register. + // Mark the register as a use (as well as a def) because the old + // value will be retained if the condition is false. + MachineOpCode movOpCode = ChooseMovpregiForSetCC(subtreeRoot); + mvec.push_back(BuildMI(movOpCode, 3) + .addReg(subtreeRoot->leftChild()->getValue()) + .addZImm(1).addReg(setCCInstr, MOTy::UseAndDef)); - break; - } + break; } + } // ELSE FALL THROUGH } From lattner at cs.uiuc.edu Thu Oct 23 11:52:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 11:52:02 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/IPO.h Message-ID: <200310231652.LAA02490@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms: IPO.h updated: 1.22 -> 1.23 --- Log message: Include new prototype --- Diffs of the changes: (+6 -0) Index: llvm/include/llvm/Transforms/IPO.h diff -u llvm/include/llvm/Transforms/IPO.h:1.22 llvm/include/llvm/Transforms/IPO.h:1.23 --- llvm/include/llvm/Transforms/IPO.h:1.22 Mon Oct 20 15:19:47 2003 +++ llvm/include/llvm/Transforms/IPO.h Thu Oct 23 11:51:49 2003 @@ -104,6 +104,12 @@ // Pass *createDeadArgEliminationPass(bool DeleteFromExternalFunctions=false); +//===----------------------------------------------------------------------===// +// createIPConstantPropagationPass - This pass propagates constants from call +// sites into the bodies of functions. +// +Pass *createIPConstantPropagationPass(); + //===----------------------------------------------------------------------===// // These passes are wrappers that can do a few simple structure mutation From lattner at cs.uiuc.edu Thu Oct 23 11:53:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 11:53:02 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/IPConstantPropagation.cpp Message-ID: <200310231652.LAA02589@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: IPConstantPropagation.cpp added (r1.1) --- Log message: Check in initial version of ipcp --- Diffs of the changes: (+110 -0) Index: llvm/lib/Transforms/IPO/IPConstantPropagation.cpp diff -c /dev/null llvm/lib/Transforms/IPO/IPConstantPropagation.cpp:1.1 *** /dev/null Thu Oct 23 11:52:37 2003 --- llvm/lib/Transforms/IPO/IPConstantPropagation.cpp Thu Oct 23 11:52:27 2003 *************** *** 0 **** --- 1,110 ---- + //===-- IPConstantPropagation.cpp - Propagate constants through calls -----===// + // + // 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 pass implements an _extremely_ simple interprocedural constant + // propagation pass. It could certainly be improved in many different ways, + // like using a worklist. This pass makes arguments dead, but does not remove + // them. The existing dead argument elimination pass should be run after this + // to clean up the mess. + // + //===----------------------------------------------------------------------===// + + #include "llvm/Transforms/IPO.h" + #include "llvm/Module.h" + #include "llvm/Pass.h" + #include "llvm/Constants.h" + #include "llvm/Support/CallSite.h" + #include "Support/Statistic.h" + + namespace { + Statistic<> NumArgumentsProped("ipconstprop", + "Number of args turned into constants"); + + /// IPCP - The interprocedural constant propagation pass + /// + struct IPCP : public Pass { + bool run(Module &M); + private: + bool processFunction(Function &F); + }; + RegisterOpt X("ipconstprop", "Interprocedural constant propagation"); + } + + Pass *createIPConstantPropagationPass() { return new IPCP(); } + + bool IPCP::run(Module &M) { + bool Changed = false; + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) + if (!I->isExternal() && I->hasInternalLinkage()) + Changed |= processFunction(*I); + return Changed; + } + + /// processFunction - Look at all uses of the specified function. If all uses + /// are direct call sites, and all pass a particular constant in for an + /// argument, propagate that constant in as the argument. + /// + bool IPCP::processFunction(Function &F) { + if (F.aempty() || F.use_empty()) return false; // No arguments? Early exit. + + std::vector > ArgumentConstants; + ArgumentConstants.resize(F.asize()); + + unsigned NumNonconstant = 0; + + for (Value::use_iterator I = F.use_begin(), E = F.use_end(); I != E; ++I) + if (!isa(*I)) + return false; // Used by a non-instruction, do not transform + else { + CallSite CS = CallSite::get(cast(*I)); + if (CS.getInstruction() == 0 || + CS.getCalledFunction() != &F) + return false; // Not a direct call site? + + // Check out all of the potentially constant arguments + CallSite::arg_iterator AI = CS.arg_begin(); + for (unsigned i = 0, e = ArgumentConstants.size(); i != e; ++i, ++AI) { + if (*AI == &F) return false; // Passes the function into itself + + if (!ArgumentConstants[i].second) { + if (isa(*AI) || isa(*AI)) { + Constant *C = dyn_cast(*AI); + if (!C) C = ConstantPointerRef::get(cast(*AI)); + + if (!ArgumentConstants[i].first) + ArgumentConstants[i].first = C; + else if (ArgumentConstants[i].first != C) { + // Became non-constant + ArgumentConstants[i].second = true; + ++NumNonconstant; + if (NumNonconstant == ArgumentConstants.size()) return false; + } + } else { + // This is not a constant argument. Mark the argument as + // non-constant. + ArgumentConstants[i].second = true; + ++NumNonconstant; + if (NumNonconstant == ArgumentConstants.size()) return false; + } + } + } + } + + // If we got to this point, there is a constant argument! + assert(NumNonconstant != ArgumentConstants.size()); + Function::aiterator AI = F.abegin(); + for (unsigned i = 0, e = ArgumentConstants.size(); i != e; ++i, ++AI) + // Do we have a constant argument!? + if (!ArgumentConstants[i].second) { + assert(ArgumentConstants[i].first && "Unknown constant value!"); + AI->replaceAllUsesWith(ArgumentConstants[i].first); + ++NumArgumentsProped; + } + return true; + } From lattner at cs.uiuc.edu Thu Oct 23 12:22:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 12:22:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200310231721.MAA06750@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.137 -> 1.138 --- Log message: Delete unused EmitByteSwap method Implement mul/div/rem constant expressions --- Diffs of the changes: (+43 -49) Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.137 llvm/lib/Target/X86/InstSelectSimple.cpp:1.138 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.137 Thu Oct 23 11:22:08 2003 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Thu Oct 23 12:21:43 2003 @@ -192,10 +192,6 @@ /// void promote32(unsigned targetReg, const ValueRecord &VR); - /// EmitByteSwap - Byteswap SrcReg into DestReg. - /// - void EmitByteSwap(unsigned DestReg, unsigned SrcReg, unsigned Class); - /// emitGEPOperation - Common code shared between visitGetElementPtrInst and /// constant expression GEP support. /// @@ -215,6 +211,11 @@ Value *Op0, Value *Op1, unsigned OperatorClass, unsigned TargetReg); + void emitDivRemOperation(MachineBasicBlock *BB, + MachineBasicBlock::iterator &IP, + unsigned Op0Reg, unsigned Op1Reg, bool isDiv, + const Type *Ty, unsigned TargetReg); + /// emitSetCCOperation - Common code shared between visitSetCondInst and /// constant expression support. void emitSetCCOperation(MachineBasicBlock *BB, @@ -355,6 +356,22 @@ Class, R); return; + case Instruction::Mul: { + unsigned Op0Reg = getReg(CE->getOperand(0), MBB, IP); + unsigned Op1Reg = getReg(CE->getOperand(1), MBB, IP); + doMultiply(MBB, IP, R, CE->getType(), Op0Reg, Op1Reg); + return; + } + case Instruction::Div: + case Instruction::Rem: { + unsigned Op0Reg = getReg(CE->getOperand(0), MBB, IP); + unsigned Op1Reg = getReg(CE->getOperand(1), MBB, IP); + emitDivRemOperation(MBB, IP, Op0Reg, Op1Reg, + CE->getOpcode() == Instruction::Div, + CE->getType(), R); + return; + } + case Instruction::SetNE: case Instruction::SetEQ: case Instruction::SetLT: @@ -1339,21 +1356,30 @@ /// instructions work differently for signed and unsigned operands. /// void ISel::visitDivRem(BinaryOperator &I) { - unsigned Class = getClass(I.getType()); - unsigned Op0Reg, Op1Reg, ResultReg = getReg(I); + unsigned Op0Reg = getReg(I.getOperand(0)); + unsigned Op1Reg = getReg(I.getOperand(1)); + unsigned ResultReg = getReg(I); + + MachineBasicBlock::iterator IP = BB->end(); + emitDivRemOperation(BB, IP, Op0Reg, Op1Reg, I.getOpcode() == Instruction::Div, + I.getType(), ResultReg); +} +void ISel::emitDivRemOperation(MachineBasicBlock *BB, + MachineBasicBlock::iterator &IP, + unsigned Op0Reg, unsigned Op1Reg, bool isDiv, + const Type *Ty, unsigned ResultReg) { + unsigned Class = getClass(Ty); switch (Class) { case cFP: // Floating point divide - if (I.getOpcode() == Instruction::Div) { - Op0Reg = getReg(I.getOperand(0)); - Op1Reg = getReg(I.getOperand(1)); + if (isDiv) { BuildMI(BB, X86::FpDIV, 2, ResultReg).addReg(Op0Reg).addReg(Op1Reg); } else { // Floating point remainder... MachineInstr *TheCall = BuildMI(X86::CALLpcrel32, 1).addExternalSymbol("fmod", true); std::vector Args; - Args.push_back(ValueRecord(I.getOperand(0))); - Args.push_back(ValueRecord(I.getOperand(1))); + Args.push_back(ValueRecord(Op0Reg, Type::DoubleTy)); + Args.push_back(ValueRecord(Op1Reg, Type::DoubleTy)); doCall(ValueRecord(ResultReg, Type::DoubleTy), TheCall, Args); } return; @@ -1361,14 +1387,13 @@ static const char *FnName[] = { "__moddi3", "__divdi3", "__umoddi3", "__udivdi3" }; - unsigned NameIdx = I.getType()->isUnsigned()*2; - NameIdx += I.getOpcode() == Instruction::Div; + unsigned NameIdx = Ty->isUnsigned()*2 + isDiv; MachineInstr *TheCall = BuildMI(X86::CALLpcrel32, 1).addExternalSymbol(FnName[NameIdx], true); std::vector Args; - Args.push_back(ValueRecord(I.getOperand(0))); - Args.push_back(ValueRecord(I.getOperand(1))); + Args.push_back(ValueRecord(Op0Reg, Type::LongTy)); + Args.push_back(ValueRecord(Op1Reg, Type::LongTy)); doCall(ValueRecord(ResultReg, Type::LongTy), TheCall, Args); return; } @@ -1388,17 +1413,16 @@ { X86::IDIVr8, X86::IDIVr16, X86::IDIVr32, 0 }, // Signed division }; - bool isSigned = I.getType()->isSigned(); + bool isSigned = Ty->isSigned(); unsigned Reg = Regs[Class]; unsigned ExtReg = ExtRegs[Class]; // Put the first operand into one of the A registers... - Op0Reg = getReg(I.getOperand(0)); BuildMI(BB, MovOpcode[Class], 1, Reg).addReg(Op0Reg); if (isSigned) { // Emit a sign extension instruction... - unsigned ShiftResult = makeAnotherReg(I.getType()); + unsigned ShiftResult = makeAnotherReg(Ty); BuildMI(BB, SarOpcode[Class], 2, ShiftResult).addReg(Op0Reg).addZImm(31); BuildMI(BB, MovOpcode[Class], 1, ExtReg).addReg(ShiftResult); } else { @@ -1407,11 +1431,10 @@ } // Emit the appropriate divide or remainder instruction... - Op1Reg = getReg(I.getOperand(1)); BuildMI(BB, DivOpcode[isSigned][Class], 1).addReg(Op1Reg); // Figure out which register we want to pick the result out of... - unsigned DestReg = (I.getOpcode() == Instruction::Div) ? Reg : ExtReg; + unsigned DestReg = isDiv ? Reg : ExtReg; // Put the result into the destination register... BuildMI(BB, MovOpcode[Class], 1, ResultReg).addReg(DestReg); @@ -1540,35 +1563,6 @@ const unsigned *Opc = NonConstantOperand[isLeftShift*2+isSigned]; BuildMI(BB, Opc[Class], 1, DestReg).addReg(SrcReg); - } -} - - -/// EmitByteSwap - Byteswap SrcReg into DestReg. -/// -void ISel::EmitByteSwap(unsigned DestReg, unsigned SrcReg, unsigned Class) { - // Emit the byte swap instruction... - switch (Class) { - case cByte: - // No byteswap necessary for 8 bit value... - BuildMI(BB, X86::MOVrr8, 1, DestReg).addReg(SrcReg); - break; - case cInt: - // Use the 32 bit bswap instruction to do a 32 bit swap... - BuildMI(BB, X86::BSWAPr32, 1, DestReg).addReg(SrcReg); - break; - - case cShort: - // For 16 bit we have to use an xchg instruction, because there is no - // 16-bit bswap. XCHG is necessarily not in SSA form, so we force things - // into AX to do the xchg. - // - BuildMI(BB, X86::MOVrr16, 1, X86::AX).addReg(SrcReg); - BuildMI(BB, X86::XCHGrr8, 2).addReg(X86::AL, MOTy::UseAndDef) - .addReg(X86::AH, MOTy::UseAndDef); - BuildMI(BB, X86::MOVrr16, 1, DestReg).addReg(X86::AX); - break; - default: assert(0 && "Cannot byteswap this class!"); } } From lattner at cs.uiuc.edu Thu Oct 23 12:32:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 12:32:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/CBackend/2003-10-23-ZeroArgVarargs.ll Message-ID: <200310231731.MAA14113@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CBackend: 2003-10-23-ZeroArgVarargs.ll added (r1.1) --- Log message: Zero arg varargs functions are legal in LLVM, but not in C. --- Diffs of the changes: (+9 -0) Index: llvm/test/Regression/CBackend/2003-10-23-ZeroArgVarargs.ll diff -c /dev/null llvm/test/Regression/CBackend/2003-10-23-ZeroArgVarargs.ll:1.1 *** /dev/null Thu Oct 23 12:31:44 2003 --- llvm/test/Regression/CBackend/2003-10-23-ZeroArgVarargs.ll Thu Oct 23 12:31:33 2003 *************** *** 0 **** --- 1,9 ---- + + declare sbyte* %llvm.va_start() + declare void %llvm.va_end(sbyte*) + + void %test(...) { + %P = call sbyte* %llvm.va_start() + call void %llvm.va_end(sbyte* %P) + ret void + } From brukman at cs.uiuc.edu Thu Oct 23 12:40:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Oct 23 12:40:01 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/InstrSelection/InstrForest.cpp InstrSelection.cpp InstrSelectionSupport.cpp Message-ID: <200310231739.MAA14198@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/InstrSelection: InstrForest.cpp updated: 1.48 -> 1.49 InstrSelection.cpp updated: 1.63 -> 1.64 InstrSelectionSupport.cpp updated: 1.56 -> 1.57 --- Log message: Make code layout more consistent. --- Diffs of the changes: (+263 -322) Index: llvm/lib/CodeGen/InstrSelection/InstrForest.cpp diff -u llvm/lib/CodeGen/InstrSelection/InstrForest.cpp:1.48 llvm/lib/CodeGen/InstrSelection/InstrForest.cpp:1.49 --- llvm/lib/CodeGen/InstrSelection/InstrForest.cpp:1.48 Mon Oct 20 14:43:15 2003 +++ llvm/lib/CodeGen/InstrSelection/InstrForest.cpp Thu Oct 23 12:39:37 2003 @@ -19,13 +19,13 @@ // //===----------------------------------------------------------------------===// -#include "llvm/CodeGen/InstrForest.h" -#include "llvm/CodeGen/MachineCodeForInstruction.h" +#include "llvm/Constant.h" #include "llvm/Function.h" #include "llvm/iTerminators.h" #include "llvm/iMemory.h" -#include "llvm/Constant.h" #include "llvm/Type.h" +#include "llvm/CodeGen/InstrForest.h" +#include "llvm/CodeGen/MachineCodeForInstruction.h" #include "llvm/CodeGen/MachineInstr.h" #include "Support/STLExtras.h" #include "Config/alloca.h" @@ -35,102 +35,82 @@ //------------------------------------------------------------------------ void -InstrTreeNode::dump(int dumpChildren, int indent) const -{ +InstrTreeNode::dump(int dumpChildren, int indent) const { dumpNode(indent); - if (dumpChildren) - { - if (LeftChild) - LeftChild->dump(dumpChildren, indent+1); - if (RightChild) - RightChild->dump(dumpChildren, indent+1); - } + if (dumpChildren) { + if (LeftChild) + LeftChild->dump(dumpChildren, indent+1); + if (RightChild) + RightChild->dump(dumpChildren, indent+1); + } } InstructionNode::InstructionNode(Instruction* I) - : InstrTreeNode(NTInstructionNode, I), - codeIsFoldedIntoParent(false) + : InstrTreeNode(NTInstructionNode, I), codeIsFoldedIntoParent(false) { opLabel = I->getOpcode(); // Distinguish special cases of some instructions such as Ret and Br // - if (opLabel == Instruction::Ret && cast(I)->getReturnValue()) - { - opLabel = RetValueOp; // ret(value) operation - } + if (opLabel == Instruction::Ret && cast(I)->getReturnValue()) { + opLabel = RetValueOp; // ret(value) operation + } else if (opLabel ==Instruction::Br && !cast(I)->isUnconditional()) - { - opLabel = BrCondOp; // br(cond) operation - } - else if (opLabel >= Instruction::SetEQ && opLabel <= Instruction::SetGT) - { - opLabel = SetCCOp; // common label for all SetCC ops - } - else if (opLabel == Instruction::Alloca && I->getNumOperands() > 0) - { - opLabel = AllocaN; // Alloca(ptr, N) operation - } - else if (opLabel == Instruction::GetElementPtr && - cast(I)->hasIndices()) - { - opLabel = opLabel + 100; // getElem with index vector - } - else if (opLabel == Instruction::Xor && - BinaryOperator::isNot(I)) - { - opLabel = (I->getType() == Type::BoolTy)? NotOp // boolean Not operator - : BNotOp; // bitwise Not operator - } - else if (opLabel == Instruction::And || - opLabel == Instruction::Or || - opLabel == Instruction::Xor) - { - // Distinguish bitwise operators from logical operators! - if (I->getType() != Type::BoolTy) - opLabel = opLabel + 100; // bitwise operator - } - else if (opLabel == Instruction::Cast) - { - const Type *ITy = I->getType(); - switch(ITy->getPrimitiveID()) - { - case Type::BoolTyID: opLabel = ToBoolTy; break; - case Type::UByteTyID: opLabel = ToUByteTy; break; - case Type::SByteTyID: opLabel = ToSByteTy; break; - case Type::UShortTyID: opLabel = ToUShortTy; break; - case Type::ShortTyID: opLabel = ToShortTy; break; - case Type::UIntTyID: opLabel = ToUIntTy; break; - case Type::IntTyID: opLabel = ToIntTy; break; - case Type::ULongTyID: opLabel = ToULongTy; break; - case Type::LongTyID: opLabel = ToLongTy; break; - case Type::FloatTyID: opLabel = ToFloatTy; break; - case Type::DoubleTyID: opLabel = ToDoubleTy; break; - case Type::ArrayTyID: opLabel = ToArrayTy; break; - case Type::PointerTyID: opLabel = ToPointerTy; break; - default: - // Just use `Cast' opcode otherwise. It's probably ignored. - break; - } + { + opLabel = BrCondOp; // br(cond) operation + } else if (opLabel >= Instruction::SetEQ && opLabel <= Instruction::SetGT) { + opLabel = SetCCOp; // common label for all SetCC ops + } else if (opLabel == Instruction::Alloca && I->getNumOperands() > 0) { + opLabel = AllocaN; // Alloca(ptr, N) operation + } else if (opLabel == Instruction::GetElementPtr && + cast(I)->hasIndices()) { + opLabel = opLabel + 100; // getElem with index vector + } else if (opLabel == Instruction::Xor && + BinaryOperator::isNot(I)) { + opLabel = (I->getType() == Type::BoolTy)? NotOp // boolean Not operator + : BNotOp; // bitwise Not operator + } else if (opLabel == Instruction::And || opLabel == Instruction::Or || + opLabel == Instruction::Xor) { + // Distinguish bitwise operators from logical operators! + if (I->getType() != Type::BoolTy) + opLabel = opLabel + 100; // bitwise operator + } else if (opLabel == Instruction::Cast) { + const Type *ITy = I->getType(); + switch(ITy->getPrimitiveID()) + { + case Type::BoolTyID: opLabel = ToBoolTy; break; + case Type::UByteTyID: opLabel = ToUByteTy; break; + case Type::SByteTyID: opLabel = ToSByteTy; break; + case Type::UShortTyID: opLabel = ToUShortTy; break; + case Type::ShortTyID: opLabel = ToShortTy; break; + case Type::UIntTyID: opLabel = ToUIntTy; break; + case Type::IntTyID: opLabel = ToIntTy; break; + case Type::ULongTyID: opLabel = ToULongTy; break; + case Type::LongTyID: opLabel = ToLongTy; break; + case Type::FloatTyID: opLabel = ToFloatTy; break; + case Type::DoubleTyID: opLabel = ToDoubleTy; break; + case Type::ArrayTyID: opLabel = ToArrayTy; break; + case Type::PointerTyID: opLabel = ToPointerTy; break; + default: + // Just use `Cast' opcode otherwise. It's probably ignored. + break; } + } } void -InstructionNode::dumpNode(int indent) const -{ +InstructionNode::dumpNode(int indent) const { for (int i=0; i < indent; i++) std::cerr << " "; std::cerr << getInstruction()->getOpcodeName() << " [label " << getOpLabel() << "]" << "\n"; } - void -VRegListNode::dumpNode(int indent) const -{ +VRegListNode::dumpNode(int indent) const { for (int i=0; i < indent; i++) std::cerr << " "; @@ -139,8 +119,7 @@ void -VRegNode::dumpNode(int indent) const -{ +VRegNode::dumpNode(int indent) const { for (int i=0; i < indent; i++) std::cerr << " "; @@ -149,8 +128,7 @@ } void -ConstantNode::dumpNode(int indent) const -{ +ConstantNode::dumpNode(int indent) const { for (int i=0; i < indent; i++) std::cerr << " "; @@ -158,9 +136,7 @@ << (int) getValue()->getValueType() << ")" << "\n"; } -void -LabelNode::dumpNode(int indent) const -{ +void LabelNode::dumpNode(int indent) const { for (int i=0; i < indent; i++) std::cerr << " "; @@ -173,56 +149,46 @@ // A forest of instruction trees, usually for a single method. //------------------------------------------------------------------------ -InstrForest::InstrForest(Function *F) -{ +InstrForest::InstrForest(Function *F) { for (Function::iterator BB = F->begin(), FE = F->end(); BB != FE; ++BB) { for(BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) buildTreeForInstruction(I); } } -InstrForest::~InstrForest() -{ +InstrForest::~InstrForest() { for_each(treeRoots.begin(), treeRoots.end(), deleter); } -void -InstrForest::dump() const -{ +void InstrForest::dump() const { for (const_root_iterator I = roots_begin(); I != roots_end(); ++I) (*I)->dump(/*dumpChildren*/ 1, /*indent*/ 0); } -inline void -InstrForest::eraseRoot(InstructionNode* node) -{ +inline void InstrForest::eraseRoot(InstructionNode* node) { for (RootSet::reverse_iterator RI=treeRoots.rbegin(), RE=treeRoots.rend(); RI != RE; ++RI) if (*RI == node) treeRoots.erase(RI.base()-1); } -inline void -InstrForest::noteTreeNodeForInstr(Instruction *instr, - InstructionNode *treeNode) -{ +inline void InstrForest::noteTreeNodeForInstr(Instruction *instr, + InstructionNode *treeNode) { (*this)[instr] = treeNode; treeRoots.push_back(treeNode); // mark node as root of a new tree } -inline void -InstrForest::setLeftChild(InstrTreeNode *parent, InstrTreeNode *child) -{ +inline void InstrForest::setLeftChild(InstrTreeNode *parent, + InstrTreeNode *child) { parent->LeftChild = child; child->Parent = parent; if (InstructionNode* instrNode = dyn_cast(child)) eraseRoot(instrNode); // no longer a tree root } -inline void -InstrForest::setRightChild(InstrTreeNode *parent, InstrTreeNode *child) -{ +inline void InstrForest::setRightChild(InstrTreeNode *parent, + InstrTreeNode *child) { parent->RightChild = child; child->Parent = parent; if (InstructionNode* instrNode = dyn_cast(child)) @@ -230,26 +196,23 @@ } -InstructionNode* -InstrForest::buildTreeForInstruction(Instruction *instr) -{ +InstructionNode* InstrForest::buildTreeForInstruction(Instruction *instr) { InstructionNode *treeNode = getTreeNodeForInstr(instr); - if (treeNode) - { - // treeNode has already been constructed for this instruction - assert(treeNode->getInstruction() == instr); - return treeNode; - } + if (treeNode) { + // treeNode has already been constructed for this instruction + assert(treeNode->getInstruction() == instr); + return treeNode; + } // Otherwise, create a new tree node for this instruction. // treeNode = new InstructionNode(instr); noteTreeNodeForInstr(instr, treeNode); - if (instr->getOpcode() == Instruction::Call) - { // Operands of call instruction - return treeNode; - } + if (instr->getOpcode() == Instruction::Call) { + // Operands of call instruction + return treeNode; + } // If the instruction has more than 2 instruction operands, // then we need to create artificial list nodes to hold them. @@ -285,46 +248,42 @@ if (includeAddressOperand || isa(operand) || isa(operand) || isa(operand) || isa(operand)) - { - // This operand is a data value + { + // This operand is a data value - // An instruction that computes the incoming value is added as a - // child of the current instruction if: - // the value has only a single use - // AND both instructions are in the same basic block. - // AND the current instruction is not a PHI (because the incoming - // value is conceptually in a predecessor block, - // even though it may be in the same static block) - // - // (Note that if the value has only a single use (viz., `instr'), - // the def of the value can be safely moved just before instr - // and therefore it is safe to combine these two instructions.) - // - // In all other cases, the virtual register holding the value - // is used directly, i.e., made a child of the instruction node. - // - InstrTreeNode* opTreeNode; - if (isa(operand) && operand->hasOneUse() && - cast(operand)->getParent() == instr->getParent() && - instr->getOpcode() != Instruction::PHI && - instr->getOpcode() != Instruction::Call) - { - // Recursively create a treeNode for it. - opTreeNode = buildTreeForInstruction((Instruction*)operand); - } - else if (Constant *CPV = dyn_cast(operand)) - { - // Create a leaf node for a constant - opTreeNode = new ConstantNode(CPV); - } - else - { - // Create a leaf node for the virtual register - opTreeNode = new VRegNode(operand); - } + // An instruction that computes the incoming value is added as a + // child of the current instruction if: + // the value has only a single use + // AND both instructions are in the same basic block. + // AND the current instruction is not a PHI (because the incoming + // value is conceptually in a predecessor block, + // even though it may be in the same static block) + // + // (Note that if the value has only a single use (viz., `instr'), + // the def of the value can be safely moved just before instr + // and therefore it is safe to combine these two instructions.) + // + // In all other cases, the virtual register holding the value + // is used directly, i.e., made a child of the instruction node. + // + InstrTreeNode* opTreeNode; + if (isa(operand) && operand->hasOneUse() && + cast(operand)->getParent() == instr->getParent() && + instr->getOpcode() != Instruction::PHI && + instr->getOpcode() != Instruction::Call) + { + // Recursively create a treeNode for it. + opTreeNode = buildTreeForInstruction((Instruction*)operand); + } else if (Constant *CPV = dyn_cast(operand)) { + // Create a leaf node for a constant + opTreeNode = new ConstantNode(CPV); + } else { + // Create a leaf node for the virtual register + opTreeNode = new VRegNode(operand); + } - childArray[numChildren++] = opTreeNode; - } + childArray[numChildren++] = opTreeNode; + } } //-------------------------------------------------------------------- @@ -338,15 +297,14 @@ InstrTreeNode *parent = treeNode; - if (numChildren > 2) - { - unsigned instrOpcode = treeNode->getInstruction()->getOpcode(); - assert(instrOpcode == Instruction::PHI || - instrOpcode == Instruction::Call || - instrOpcode == Instruction::Load || - instrOpcode == Instruction::Store || - instrOpcode == Instruction::GetElementPtr); - } + if (numChildren > 2) { + unsigned instrOpcode = treeNode->getInstruction()->getOpcode(); + assert(instrOpcode == Instruction::PHI || + instrOpcode == Instruction::Call || + instrOpcode == Instruction::Load || + instrOpcode == Instruction::Store || + instrOpcode == Instruction::GetElementPtr); + } // Insert the first child as a direct child if (numChildren >= 1) @@ -355,21 +313,19 @@ int n; // Create a list node for children 2 .. N-1, if any - for (n = numChildren-1; n >= 2; n--) - { - // We have more than two children - InstrTreeNode *listNode = new VRegListNode(); - setRightChild(parent, listNode); - setLeftChild(listNode, childArray[numChildren - n]); - parent = listNode; - } + for (n = numChildren-1; n >= 2; n--) { + // We have more than two children + InstrTreeNode *listNode = new VRegListNode(); + setRightChild(parent, listNode); + setLeftChild(listNode, childArray[numChildren - n]); + parent = listNode; + } // Now insert the last remaining child (if any). - if (numChildren >= 2) - { - assert(n == 1); - setRightChild(parent, childArray[numChildren - 1]); - } + if (numChildren >= 2) { + assert(n == 1); + setRightChild(parent, childArray[numChildren - 1]); + } delete [] childArray; return treeNode; Index: llvm/lib/CodeGen/InstrSelection/InstrSelection.cpp diff -u llvm/lib/CodeGen/InstrSelection/InstrSelection.cpp:1.63 llvm/lib/CodeGen/InstrSelection/InstrSelection.cpp:1.64 --- llvm/lib/CodeGen/InstrSelection/InstrSelection.cpp:1.63 Mon Oct 20 14:43:15 2003 +++ llvm/lib/CodeGen/InstrSelection/InstrSelection.cpp Thu Oct 23 12:39:37 2003 @@ -14,19 +14,19 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Function.h" +#include "llvm/iPHINode.h" +#include "llvm/Pass.h" +#include "llvm/CodeGen/InstrForest.h" #include "llvm/CodeGen/InstrSelection.h" #include "llvm/CodeGen/InstrSelectionSupport.h" -#include "llvm/CodeGen/InstrForest.h" #include "llvm/CodeGen/MachineCodeForInstruction.h" #include "llvm/CodeGen/MachineFunction.h" -#include "llvm/Target/TargetRegInfo.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Function.h" -#include "llvm/iPHINode.h" -#include "llvm/Pass.h" +#include "llvm/Target/TargetRegInfo.h" #include "Support/CommandLine.h" #include "Support/LeakDetector.h" -using std::vector; +#include std::vector FixConstantOperandsForInstr(Instruction* vmInstr, MachineInstr* minstr, @@ -66,7 +66,7 @@ TargetMachine &Target; void InsertCodeForPhis(Function &F); void InsertPhiElimInstructions(BasicBlock *BB, - const vector& CpVec); + const std::vector& CpVec); void SelectInstructionsForTree(InstrTreeNode* treeRoot, int goalnt); void PostprocessMachineCodeForTree(InstructionNode* instrNode, int ruleForNode, short* nts); @@ -89,9 +89,8 @@ mcfi.addTemp(this); Operands.push_back(Use(s1, this)); // s1 must be non-null - if (s2) { + if (s2) Operands.push_back(Use(s2, this)); - } // TmpInstructions should not be garbage checked. LeakDetector::removeGarbageObject(this); @@ -106,8 +105,10 @@ { mcfi.addTemp(this); - if (s1) { Operands.push_back(Use(s1, this)); } - if (s2) { Operands.push_back(Use(s2, this)); } + if (s1) + Operands.push_back(Use(s1, this)); + if (s2) + Operands.push_back(Use(s2, this)); // TmpInstructions should not be garbage checked. LeakDetector::removeGarbageObject(this); @@ -121,37 +122,34 @@ // InstrForest instrForest(&F); - if (SelectDebugLevel >= Select_DebugInstTrees) - { - std::cerr << "\n\n*** Input to instruction selection for function " - << F.getName() << "\n\n" << F - << "\n\n*** Instruction trees for function " - << F.getName() << "\n\n"; - instrForest.dump(); - } + if (SelectDebugLevel >= Select_DebugInstTrees) { + std::cerr << "\n\n*** Input to instruction selection for function " + << F.getName() << "\n\n" << F + << "\n\n*** Instruction trees for function " + << F.getName() << "\n\n"; + instrForest.dump(); + } // // Invoke BURG instruction selection for each tree // for (InstrForest::const_root_iterator RI = instrForest.roots_begin(); - RI != instrForest.roots_end(); ++RI) - { - InstructionNode* basicNode = *RI; - assert(basicNode->parent() == NULL && "A `root' node has a parent?"); - - // Invoke BURM to label each tree node with a state - burm_label(basicNode); + RI != instrForest.roots_end(); ++RI) { + InstructionNode* basicNode = *RI; + assert(basicNode->parent() == NULL && "A `root' node has a parent?"); - if (SelectDebugLevel >= Select_DebugBurgTrees) - { - printcover(basicNode, 1, 0); - std::cerr << "\nCover cost == " << treecost(basicNode, 1, 0) <<"\n\n"; - printMatches(basicNode); - } + // Invoke BURM to label each tree node with a state + burm_label(basicNode); - // Then recursively walk the tree to select instructions - SelectInstructionsForTree(basicNode, /*goalnt*/1); + if (SelectDebugLevel >= Select_DebugBurgTrees) { + printcover(basicNode, 1, 0); + std::cerr << "\nCover cost == " << treecost(basicNode, 1, 0) <<"\n\n"; + printMatches(basicNode); } + + // Then recursively walk the tree to select instructions + SelectInstructionsForTree(basicNode, /*goalnt*/1); + } // // Create the MachineBasicBlock records and add all of the MachineInstrs @@ -172,11 +170,10 @@ // Insert phi elimination code InsertCodeForPhis(F); - if (SelectDebugLevel >= Select_PrintMachineCode) - { - std::cerr << "\n*** Machine instructions after INSTRUCTION SELECTION\n"; - MachineFunction::get(&F).dump(); - } + if (SelectDebugLevel >= Select_PrintMachineCode) { + std::cerr << "\n*** Machine instructions after INSTRUCTION SELECTION\n"; + MachineFunction::get(&F).dump(); + } return true; } @@ -187,8 +184,7 @@ //------------------------------------------------------------------------- void -InstructionSelection::InsertCodeForPhis(Function &F) -{ +InstructionSelection::InsertCodeForPhis(Function &F) { // for all basic blocks in function // MachineFunction &MF = MachineFunction::get(&F); @@ -207,12 +203,12 @@ // for (unsigned i = 0; i < PN->getNumIncomingValues(); ++i) { // insert the copy instruction to the predecessor BB - vector mvec, CpVec; + std::vector mvec, CpVec; Target.getRegInfo().cpValue2Value(PN->getIncomingValue(i), PhiCpRes, mvec); - for (vector::iterator MI=mvec.begin(); + for (std::vector::iterator MI=mvec.begin(); MI != mvec.end(); ++MI) { - vector CpVec2 = + std::vector CpVec2 = FixConstantOperandsForInstr(const_cast(PN), *MI, Target); CpVec2.push_back(*MI); CpVec.insert(CpVec.end(), CpVec2.begin(), CpVec2.end()); @@ -221,7 +217,7 @@ InsertPhiElimInstructions(PN->getIncomingBlock(i), CpVec); } - vector mvec; + std::vector mvec; Target.getRegInfo().cpValue2Value(PhiCpRes, const_cast(PN), mvec); BB->insert(BB->begin(), mvec.begin(), mvec.end()); @@ -236,7 +232,7 @@ void InstructionSelection::InsertPhiElimInstructions(BasicBlock *BB, - const vector& CpVec) + const std::vector& CpVec) { Instruction *TermInst = (Instruction*)BB->getTerminator(); MachineCodeForInstruction &MC4Term = MachineCodeForInstruction::get(TermInst); @@ -304,50 +300,47 @@ // (If this is a list node, not an instruction, then skip this step). // This function is specific to the target architecture. // - if (treeRoot->opLabel != VRegListOp) - { - vector minstrVec; + if (treeRoot->opLabel != VRegListOp) { + std::vector minstrVec; - InstructionNode* instrNode = (InstructionNode*)treeRoot; - assert(instrNode->getNodeType() == InstrTreeNode::NTInstructionNode); + InstructionNode* instrNode = (InstructionNode*)treeRoot; + assert(instrNode->getNodeType() == InstrTreeNode::NTInstructionNode); - GetInstructionsByRule(instrNode, ruleForNode, nts, Target, minstrVec); + GetInstructionsByRule(instrNode, ruleForNode, nts, Target, minstrVec); - MachineCodeForInstruction &mvec = - MachineCodeForInstruction::get(instrNode->getInstruction()); - mvec.insert(mvec.end(), minstrVec.begin(), minstrVec.end()); - } + MachineCodeForInstruction &mvec = + MachineCodeForInstruction::get(instrNode->getInstruction()); + mvec.insert(mvec.end(), minstrVec.begin(), minstrVec.end()); + } // Then, recursively compile the child nodes, if any. // - if (nts[0]) - { // i.e., there is at least one kid - InstrTreeNode* kids[2]; - int currentRule = ruleForNode; - burm_kids(treeRoot, currentRule, kids); + if (nts[0]) { + // i.e., there is at least one kid + InstrTreeNode* kids[2]; + int currentRule = ruleForNode; + burm_kids(treeRoot, currentRule, kids); - // First skip over any chain rules so that we don't visit - // the current node again. - // - while (ThisIsAChainRule(currentRule)) - { - currentRule = burm_rule(treeRoot->state, nts[0]); - nts = burm_nts[currentRule]; - burm_kids(treeRoot, currentRule, kids); - } + // First skip over any chain rules so that we don't visit + // the current node again. + // + while (ThisIsAChainRule(currentRule)) { + currentRule = burm_rule(treeRoot->state, nts[0]); + nts = burm_nts[currentRule]; + burm_kids(treeRoot, currentRule, kids); + } - // Now we have the first non-chain rule so we have found - // the actual child nodes. Recursively compile them. - // - for (unsigned i = 0; nts[i]; i++) - { - assert(i < 2); - InstrTreeNode::InstrTreeNodeType nodeType = kids[i]->getNodeType(); - if (nodeType == InstrTreeNode::NTVRegListNode || - nodeType == InstrTreeNode::NTInstructionNode) - SelectInstructionsForTree(kids[i], nts[i]); - } + // Now we have the first non-chain rule so we have found + // the actual child nodes. Recursively compile them. + // + for (unsigned i = 0; nts[i]; i++) { + assert(i < 2); + InstrTreeNode::InstrTreeNodeType nodeType = kids[i]->getNodeType(); + if (nodeType == InstrTreeNode::NTVRegListNode || + nodeType == InstrTreeNode::NTInstructionNode) + SelectInstructionsForTree(kids[i], nts[i]); } + } // Finally, do any post-processing on this node after its children // have been translated @@ -373,13 +366,12 @@ // Instruction* vmInstr = instrNode->getInstruction(); MachineCodeForInstruction &mvec = MachineCodeForInstruction::get(vmInstr); - for (unsigned i = mvec.size(); i != 0; --i) - { - vector loadConstVec = - FixConstantOperandsForInstr(vmInstr, mvec[i-1], Target); + for (unsigned i = mvec.size(); i != 0; --i) { + std::vector loadConstVec = + FixConstantOperandsForInstr(vmInstr, mvec[i-1], Target); - mvec.insert(mvec.begin()+i-1, loadConstVec.begin(), loadConstVec.end()); - } + mvec.insert(mvec.begin()+i-1, loadConstVec.begin(), loadConstVec.end()); + } } Index: llvm/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp diff -u llvm/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp:1.56 llvm/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp:1.57 --- llvm/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp:1.56 Mon Oct 20 14:43:15 2003 +++ llvm/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp Thu Oct 23 12:39:37 2003 @@ -66,17 +66,14 @@ getImmedValue = 0; if (canUseImmed && - target.getInstrInfo().constantFitsInImmedField(opCode, intValue)) - { + target.getInstrInfo().constantFitsInImmedField(opCode, intValue)) { opType = isSigned? MachineOperand::MO_SignExtendedImmed : MachineOperand::MO_UnextendedImmed; getImmedValue = intValue; - } - else if (intValue == 0 && target.getRegInfo().getZeroRegNum() >= 0) - { - opType = MachineOperand::MO_MachineRegister; - getMachineRegNum = target.getRegInfo().getZeroRegNum(); - } + } else if (intValue == 0 && target.getRegInfo().getZeroRegNum() >= 0) { + opType = MachineOperand::MO_MachineRegister; + getMachineRegNum = target.getRegInfo().getZeroRegNum(); + } return opType; } @@ -158,52 +155,48 @@ MachineOperand::MO_VirtualRegister; // Operand may be a virtual register or a compile-time constant - if (mop.getType() == MachineOperand::MO_VirtualRegister) - { - assert(mop.getVRegValue() != NULL); - opValue = mop.getVRegValue(); - if (Constant *opConst = dyn_cast(opValue)) { - opType = ChooseRegOrImmed(opConst, opCode, target, - (immedPos == (int)op), machineRegNum, - immedValue); - if (opType == MachineOperand::MO_VirtualRegister) - constantThatMustBeLoaded = true; - } + if (mop.getType() == MachineOperand::MO_VirtualRegister) { + assert(mop.getVRegValue() != NULL); + opValue = mop.getVRegValue(); + if (Constant *opConst = dyn_cast(opValue)) { + opType = ChooseRegOrImmed(opConst, opCode, target, + (immedPos == (int)op), machineRegNum, + immedValue); + if (opType == MachineOperand::MO_VirtualRegister) + constantThatMustBeLoaded = true; + } + } else { + assert(mop.isImmediate()); + bool isSigned = mop.getType() == MachineOperand::MO_SignExtendedImmed; + + // Bit-selection flags indicate an instruction that is extracting + // bits from its operand so ignore this even if it is a big constant. + if (mop.opHiBits32() || mop.opLoBits32() || + mop.opHiBits64() || mop.opLoBits64()) + continue; + + opType = ChooseRegOrImmed(mop.getImmedValue(), isSigned, + opCode, target, (immedPos == (int)op), + machineRegNum, immedValue); + + if (opType == MachineOperand::MO_SignExtendedImmed || + opType == MachineOperand::MO_UnextendedImmed) { + // The optype is an immediate value + // This means we need to change the opcode, e.g. ADDr -> ADDi + unsigned newOpcode = convertOpcodeFromRegToImm(opCode); + minstr->setOpcode(newOpcode); } - else - { - assert(mop.isImmediate()); - bool isSigned = mop.getType() == MachineOperand::MO_SignExtendedImmed; - - // Bit-selection flags indicate an instruction that is extracting - // bits from its operand so ignore this even if it is a big constant. - if (mop.opHiBits32() || mop.opLoBits32() || - mop.opHiBits64() || mop.opLoBits64()) - continue; - - opType = ChooseRegOrImmed(mop.getImmedValue(), isSigned, - opCode, target, (immedPos == (int)op), - machineRegNum, immedValue); - - if (opType == MachineOperand::MO_SignExtendedImmed || - opType == MachineOperand::MO_UnextendedImmed) { - // The optype is an immediate value - // This means we need to change the opcode, e.g. ADDr -> ADDi - unsigned newOpcode = convertOpcodeFromRegToImm(opCode); - minstr->setOpcode(newOpcode); - } - if (opType == mop.getType()) - continue; // no change: this is the most common case + if (opType == mop.getType()) + continue; // no change: this is the most common case - if (opType == MachineOperand::MO_VirtualRegister) - { - constantThatMustBeLoaded = true; - opValue = isSigned - ? (Value*)ConstantSInt::get(Type::LongTy, immedValue) - : (Value*)ConstantUInt::get(Type::ULongTy,(uint64_t)immedValue); - } + if (opType == MachineOperand::MO_VirtualRegister) { + constantThatMustBeLoaded = true; + opValue = isSigned + ? (Value*)ConstantSInt::get(Type::LongTy, immedValue) + : (Value*)ConstantUInt::get(Type::ULongTy,(uint64_t)immedValue); } + } if (opType == MachineOperand::MO_MachineRegister) minstr->SetMachineOperandReg(op, machineRegNum); @@ -250,16 +243,16 @@ InsertCodeToLoadConstant(F, oldVal, vmInstr, MVec, target); minstr->setImplicitRef(i, tmpReg); - if (isCall) - { // find and replace the argument in the CallArgsDescriptor - unsigned i=lastCallArgNum; - while (argDesc->getArgInfo(i).getArgVal() != oldVal) - ++i; - assert(i < argDesc->getNumArgs() && - "Constant operands to a call *must* be in the arg list"); - lastCallArgNum = i; - argDesc->getArgInfo(i).replaceArgVal(tmpReg); - } + if (isCall) { + // find and replace the argument in the CallArgsDescriptor + unsigned i=lastCallArgNum; + while (argDesc->getArgInfo(i).getArgVal() != oldVal) + ++i; + assert(i < argDesc->getNumArgs() && + "Constant operands to a call *must* be in the arg list"); + lastCallArgNum = i; + argDesc->getArgInfo(i).replaceArgVal(tmpReg); + } } return MVec; From brukman at cs.uiuc.edu Thu Oct 23 12:44:02 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Oct 23 12:44:02 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/InstrSched/SchedPriorities.cpp Message-ID: <200310231743.MAA14274@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/InstrSched: SchedPriorities.cpp updated: 1.27 -> 1.28 --- Log message: * Eliminate `using' directive * Make code layout more consistent --- Diffs of the changes: (+90 -108) Index: llvm/lib/CodeGen/InstrSched/SchedPriorities.cpp diff -u llvm/lib/CodeGen/InstrSched/SchedPriorities.cpp:1.27 llvm/lib/CodeGen/InstrSched/SchedPriorities.cpp:1.28 --- llvm/lib/CodeGen/InstrSched/SchedPriorities.cpp:1.27 Mon Oct 20 14:43:15 2003 +++ llvm/lib/CodeGen/InstrSched/SchedPriorities.cpp Thu Oct 23 12:43:17 2003 @@ -22,7 +22,6 @@ #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/Support/CFG.h" #include "Support/PostOrderIterator.h" -using std::cerr; std::ostream &operator<<(std::ostream &os, const NodeDelayPair* nd) { return os << "Delay for node " << nd->node->getNodeId() @@ -43,41 +42,35 @@ void -SchedPriorities::initialize() -{ +SchedPriorities::initialize() { initializeReadyHeap(graph); } void -SchedPriorities::computeDelays(const SchedGraph* graph) -{ +SchedPriorities::computeDelays(const SchedGraph* graph) { po_iterator poIter = po_begin(graph), poEnd =po_end(graph); - for ( ; poIter != poEnd; ++poIter) - { - const SchedGraphNode* node = *poIter; - cycles_t nodeDelay; - if (node->beginOutEdges() == node->endOutEdges()) - nodeDelay = node->getLatency(); - else - { - // Iterate over the out-edges of the node to compute delay - nodeDelay = 0; - for (SchedGraphNode::const_iterator E=node->beginOutEdges(); - E != node->endOutEdges(); ++E) - { - cycles_t sinkDelay = getNodeDelay((SchedGraphNode*)(*E)->getSink()); - nodeDelay = std::max(nodeDelay, sinkDelay + (*E)->getMinDelay()); - } - } - getNodeDelayRef(node) = nodeDelay; + for ( ; poIter != poEnd; ++poIter) { + const SchedGraphNode* node = *poIter; + cycles_t nodeDelay; + if (node->beginOutEdges() == node->endOutEdges()) + nodeDelay = node->getLatency(); + else { + // Iterate over the out-edges of the node to compute delay + nodeDelay = 0; + for (SchedGraphNode::const_iterator E=node->beginOutEdges(); + E != node->endOutEdges(); ++E) { + cycles_t sinkDelay = getNodeDelay((SchedGraphNode*)(*E)->getSink()); + nodeDelay = std::max(nodeDelay, sinkDelay + (*E)->getMinDelay()); + } } + getNodeDelayRef(node) = nodeDelay; + } } void -SchedPriorities::initializeReadyHeap(const SchedGraph* graph) -{ +SchedPriorities::initializeReadyHeap(const SchedGraph* graph) { const SchedGraphNode* graphRoot = (const SchedGraphNode*)graph->getRoot(); assert(graphRoot->getMachineInstr() == NULL && "Expect dummy root"); @@ -88,9 +81,9 @@ #undef TEST_HEAP_CONVERSION #ifdef TEST_HEAP_CONVERSION - cerr << "Before heap conversion:\n"; + std::cerr << "Before heap conversion:\n"; copy(candsAsHeap.begin(), candsAsHeap.end(), - ostream_iterator(cerr,"\n")); + ostream_iterator(std::cerr,"\n")); #endif candsAsHeap.makeHeap(); @@ -98,55 +91,54 @@ nextToTry = candsAsHeap.begin(); #ifdef TEST_HEAP_CONVERSION - cerr << "After heap conversion:\n"; + std::cerr << "After heap conversion:\n"; copy(candsAsHeap.begin(), candsAsHeap.end(), - ostream_iterator(cerr,"\n")); + ostream_iterator(std::cerr,"\n")); #endif } void -SchedPriorities::insertReady(const SchedGraphNode* node) -{ +SchedPriorities::insertReady(const SchedGraphNode* node) { candsAsHeap.insert(node, nodeDelayVec[node->getNodeId()]); candsAsSet.insert(node); mcands.clear(); // ensure reset choices is called before any more choices earliestReadyTime = std::min(earliestReadyTime, getEarliestReadyTimeForNode(node)); - if (SchedDebugLevel >= Sched_PrintSchedTrace) - { - cerr << " Node " << node->getNodeId() << " will be ready in Cycle " - << getEarliestReadyTimeForNode(node) << "; " - << " Delay = " <<(long)getNodeDelay(node) << "; Instruction: \n"; - cerr << " " << *node->getMachineInstr() << "\n"; - } + if (SchedDebugLevel >= Sched_PrintSchedTrace) { + std::cerr << " Node " << node->getNodeId() << " will be ready in Cycle " + << getEarliestReadyTimeForNode(node) << "; " + << " Delay = " <<(long)getNodeDelay(node) << "; Instruction: \n" + << " " << *node->getMachineInstr() << "\n"; + } } void SchedPriorities::issuedReadyNodeAt(cycles_t curTime, - const SchedGraphNode* node) -{ + const SchedGraphNode* node) { candsAsHeap.removeNode(node); candsAsSet.erase(node); mcands.clear(); // ensure reset choices is called before any more choices - if (earliestReadyTime == getEarliestReadyTimeForNode(node)) - {// earliestReadyTime may have been due to this node, so recompute it - earliestReadyTime = HUGE_LATENCY; - for (NodeHeap::const_iterator I=candsAsHeap.begin(); - I != candsAsHeap.end(); ++I) - if (candsAsHeap.getNode(I)) - earliestReadyTime = std::min(earliestReadyTime, - getEarliestReadyTimeForNode(candsAsHeap.getNode(I))); - } + if (earliestReadyTime == getEarliestReadyTimeForNode(node)) { + // earliestReadyTime may have been due to this node, so recompute it + earliestReadyTime = HUGE_LATENCY; + for (NodeHeap::const_iterator I=candsAsHeap.begin(); + I != candsAsHeap.end(); ++I) + if (candsAsHeap.getNode(I)) { + earliestReadyTime = + std::min(earliestReadyTime, + getEarliestReadyTimeForNode(candsAsHeap.getNode(I))); + } + } // Now update ready times for successors for (SchedGraphNode::const_iterator E=node->beginOutEdges(); - E != node->endOutEdges(); ++E) - { - cycles_t& etime = getEarliestReadyTimeForNodeRef((SchedGraphNode*)(*E)->getSink()); - etime = std::max(etime, curTime + (*E)->getMinDelay()); - } + E != node->endOutEdges(); ++E) { + cycles_t& etime = + getEarliestReadyTimeForNodeRef((SchedGraphNode*)(*E)->getSink()); + etime = std::max(etime, curTime + (*E)->getMinDelay()); + } } @@ -160,15 +152,13 @@ //---------------------------------------------------------------------- inline int -SchedPriorities::chooseByRule1(std::vector& mcands) -{ +SchedPriorities::chooseByRule1(std::vector& mcands) { return (mcands.size() == 1)? 0 // only one choice exists so take it : -1; // -1 indicates multiple choices } inline int -SchedPriorities::chooseByRule2(std::vector& mcands) -{ +SchedPriorities::chooseByRule2(std::vector& mcands) { assert(mcands.size() >= 1 && "Should have at least one candidate here."); for (unsigned i=0, N = mcands.size(); i < N; i++) if (instructionHasLastUse(methodLiveVarInfo, @@ -178,67 +168,60 @@ } inline int -SchedPriorities::chooseByRule3(std::vector& mcands) -{ +SchedPriorities::chooseByRule3(std::vector& mcands) { assert(mcands.size() >= 1 && "Should have at least one candidate here."); int maxUses = candsAsHeap.getNode(mcands[0])->getNumOutEdges(); int indexWithMaxUses = 0; - for (unsigned i=1, N = mcands.size(); i < N; i++) - { - int numUses = candsAsHeap.getNode(mcands[i])->getNumOutEdges(); - if (numUses > maxUses) - { - maxUses = numUses; - indexWithMaxUses = i; - } + for (unsigned i=1, N = mcands.size(); i < N; i++) { + int numUses = candsAsHeap.getNode(mcands[i])->getNumOutEdges(); + if (numUses > maxUses) { + maxUses = numUses; + indexWithMaxUses = i; } + } return indexWithMaxUses; } const SchedGraphNode* SchedPriorities::getNextHighest(const SchedulingManager& S, - cycles_t curTime) -{ + cycles_t curTime) { int nextIdx = -1; const SchedGraphNode* nextChoice = NULL; if (mcands.size() == 0) findSetWithMaxDelay(mcands, S); - while (nextIdx < 0 && mcands.size() > 0) - { - nextIdx = chooseByRule1(mcands); // rule 1 + while (nextIdx < 0 && mcands.size() > 0) { + nextIdx = chooseByRule1(mcands); // rule 1 - if (nextIdx == -1) - nextIdx = chooseByRule2(mcands); // rule 2 + if (nextIdx == -1) + nextIdx = chooseByRule2(mcands); // rule 2 - if (nextIdx == -1) - nextIdx = chooseByRule3(mcands); // rule 3 + if (nextIdx == -1) + nextIdx = chooseByRule3(mcands); // rule 3 - if (nextIdx == -1) - nextIdx = 0; // default to first choice by delays - - // We have found the next best candidate. Check if it ready in - // the current cycle, and if it is feasible. - // If not, remove it from mcands and continue. Refill mcands if - // it becomes empty. - nextChoice = candsAsHeap.getNode(mcands[nextIdx]); - if (getEarliestReadyTimeForNode(nextChoice) > curTime - || ! instrIsFeasible(S, nextChoice->getMachineInstr()->getOpCode())) - { - mcands.erase(mcands.begin() + nextIdx); - nextIdx = -1; - if (mcands.size() == 0) - findSetWithMaxDelay(mcands, S); - } - } - - if (nextIdx >= 0) + if (nextIdx == -1) + nextIdx = 0; // default to first choice by delays + + // We have found the next best candidate. Check if it ready in + // the current cycle, and if it is feasible. + // If not, remove it from mcands and continue. Refill mcands if + // it becomes empty. + nextChoice = candsAsHeap.getNode(mcands[nextIdx]); + if (getEarliestReadyTimeForNode(nextChoice) > curTime + || ! instrIsFeasible(S, nextChoice->getMachineInstr()->getOpCode())) { mcands.erase(mcands.begin() + nextIdx); - return nextChoice; - } - else + nextIdx = -1; + if (mcands.size() == 0) + findSetWithMaxDelay(mcands, S); + } + } + + if (nextIdx >= 0) { + mcands.erase(mcands.begin() + nextIdx); + return nextChoice; + } else return NULL; } @@ -258,15 +241,14 @@ nextToTry = next; - if (SchedDebugLevel >= Sched_PrintSchedTrace) - { - cerr << " Cycle " << (long)getTime() << ": " - << "Next highest delay = " << (long)maxDelay << " : " - << mcands.size() << " Nodes with this delay: "; - for (unsigned i=0; i < mcands.size(); i++) - cerr << candsAsHeap.getNode(mcands[i])->getNodeId() << ", "; - cerr << "\n"; - } + if (SchedDebugLevel >= Sched_PrintSchedTrace) { + std::cerr << " Cycle " << (long)getTime() << ": " + << "Next highest delay = " << (long)maxDelay << " : " + << mcands.size() << " Nodes with this delay: "; + for (unsigned i=0; i < mcands.size(); i++) + std::cerr << candsAsHeap.getNode(mcands[i])->getNodeId() << ", "; + std::cerr << "\n"; + } } } From lattner at cs.uiuc.edu Thu Oct 23 12:46:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 12:46:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp Message-ID: <200310231745.MAA15969@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: DeadArgumentElimination.cpp updated: 1.8 -> 1.9 --- Log message: * We were forgetting to pass varargs arguments through a call * Add a work around for bug PR56, gross but necessary for now. --- Diffs of the changes: (+18 -0) Index: llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp diff -u llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp:1.8 llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp:1.9 --- llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp:1.8 Wed Oct 22 22:48:17 2003 +++ llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp Thu Oct 23 12:44:53 2003 @@ -380,6 +380,17 @@ DeadRetVal.erase(F); } + // Work around LLVM bug PR56: the CWriter cannot emit varargs functions which + // have zero fixed arguments. + // + // FIXME: once this bug is fixed in the CWriter, this hack should be removed. + // + bool ExtraArgHack = false; + if (Params.empty() && FTy->isVarArg()) { + ExtraArgHack = true; + Params.push_back(Type::IntTy); + } + FunctionType *NFTy = FunctionType::get(RetTy, Params, FTy->isVarArg()); // Create the new function body and insert it into the module... @@ -399,6 +410,13 @@ for (Function::aiterator I = F->abegin(), E = F->aend(); I != E; ++I, ++AI) if (!DeadArguments.count(I)) // Remove operands for dead arguments Args.push_back(*AI); + + if (ExtraArgHack) + Args.push_back(Constant::getNullValue(Type::IntTy)); + + // Push any varargs arguments on the list + for (; AI != CS.arg_end(); ++AI) + Args.push_back(*AI); Instruction *New; if (InvokeInst *II = dyn_cast(Call)) { From brukman at cs.uiuc.edu Thu Oct 23 13:01:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Oct 23 13:01:01 2003 Subject: [llvm-commits] CVS: llvm/lib/AsmParser/Parser.cpp Message-ID: <200310231800.NAA31376@zion.cs.uiuc.edu> Changes in directory llvm/lib/AsmParser: Parser.cpp updated: 1.11 -> 1.12 --- Log message: * Eliminate `using' directive * Order #includes as per style guide --- Diffs of the changes: (+10 -9) Index: llvm/lib/AsmParser/Parser.cpp diff -u llvm/lib/AsmParser/Parser.cpp:1.11 llvm/lib/AsmParser/Parser.cpp:1.12 --- llvm/lib/AsmParser/Parser.cpp:1.11 Mon Oct 20 14:43:14 2003 +++ llvm/lib/AsmParser/Parser.cpp Thu Oct 23 13:00:34 2003 @@ -11,15 +11,14 @@ // //===------------------------------------------------------------------------=== -#include "llvm/Analysis/Verifier.h" -#include "llvm/Module.h" #include "ParserInternals.h" -using std::string; +#include "llvm/Module.h" +#include "llvm/Analysis/Verifier.h" // The useful interface defined by this file... Parse an ASCII file, and return // the internal representation in a nice slice'n'dice'able representation. // -Module *ParseAssemblyFile(const string &Filename) { // throw (ParseException) +Module *ParseAssemblyFile(const std::string &Filename) { FILE *F = stdin; if (Filename != "-") { @@ -49,7 +48,8 @@ //===------------------------------------------------------------------------=== -ParseException::ParseException(const string &filename, const string &message, +ParseException::ParseException(const std::string &filename, + const std::string &message, int lineNo, int colNo) : Filename(filename), Message(message) { LineNo = lineNo; ColumnNo = colNo; @@ -61,8 +61,9 @@ ColumnNo = E.ColumnNo; } -const string ParseException::getMessage() const { // Includes info from options - string Result; +// Includes info from options +const std::string ParseException::getMessage() const { + std::string Result; char Buffer[10]; if (Filename == "-") @@ -72,10 +73,10 @@ if (LineNo != -1) { sprintf(Buffer, "%d", LineNo); - Result += string(":") + Buffer; + Result += std::string(":") + Buffer; if (ColumnNo != -1) { sprintf(Buffer, "%d", ColumnNo); - Result += string(",") + Buffer; + Result += std::string(",") + Buffer; } } From brukman at cs.uiuc.edu Thu Oct 23 13:03:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Oct 23 13:03:01 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAlloc/IGNode.cpp IGNode.h Message-ID: <200310231802.NAA04513@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/RegAlloc: IGNode.cpp updated: 1.10 -> 1.11 IGNode.h updated: 1.18 -> 1.19 --- Log message: * Use C++ style comments instead of C-style * Make file description more readable * Make code layout more consistent, include comment in assert so it's visible during execution if it hits --- Diffs of the changes: (+25 -30) Index: llvm/lib/CodeGen/RegAlloc/IGNode.cpp diff -u llvm/lib/CodeGen/RegAlloc/IGNode.cpp:1.10 llvm/lib/CodeGen/RegAlloc/IGNode.cpp:1.11 --- llvm/lib/CodeGen/RegAlloc/IGNode.cpp:1.10 Mon Oct 20 14:43:16 2003 +++ llvm/lib/CodeGen/RegAlloc/IGNode.cpp Thu Oct 23 13:02:47 2003 @@ -7,7 +7,8 @@ // //===----------------------------------------------------------------------===// // -// class IGNode for coloring-based register allocation for LLVM. +// This file implements an Interference graph node for coloring-based register +// allocation. // //===----------------------------------------------------------------------===// @@ -28,7 +29,7 @@ assert(0 && "Invalid adj list size"); } - for(int i=0; i < neighs; i++) + for (int i=0; i < neighs; i++) AdjList[i]->decCurDegree(); } @@ -39,7 +40,7 @@ void IGNode::delAdjIGNode(const IGNode *Node) { std::vector::iterator It=find(AdjList.begin(), AdjList.end(), Node); - assert( It != AdjList.end() ); // the node must be there + assert(It != AdjList.end() && "The node must be there!"); AdjList.erase(It); } @@ -48,13 +49,10 @@ //----------------------------------------------------------------------------- unsigned -IGNode::getCombinedDegree(const IGNode* otherNode) const -{ +IGNode::getCombinedDegree(const IGNode* otherNode) const { std::vector nbrs(AdjList); nbrs.insert(nbrs.end(), otherNode->AdjList.begin(), otherNode->AdjList.end()); sort(nbrs.begin(), nbrs.end()); std::vector::iterator new_end = unique(nbrs.begin(), nbrs.end()); return new_end - nbrs.begin(); } - - Index: llvm/lib/CodeGen/RegAlloc/IGNode.h diff -u llvm/lib/CodeGen/RegAlloc/IGNode.h:1.18 llvm/lib/CodeGen/RegAlloc/IGNode.h:1.19 --- llvm/lib/CodeGen/RegAlloc/IGNode.h:1.18 Tue Oct 21 10:24:53 2003 +++ llvm/lib/CodeGen/RegAlloc/IGNode.h Thu Oct 23 13:02:47 2003 @@ -6,29 +6,26 @@ // the University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// - -/* Title: IGNode.h -*- C++ -*- - Author: Ruchira Sasanka - Date: July 25, 01 - Purpose: Represents a node in an interference graph. - Notes: - - For efficiency, the AdjList is updated only once - ie. we can add but not - remove nodes from AdjList. - - The removal of nodes from IG is simulated by decrementing the CurDegree. - If this node is put on stack (that is removed from IG), the CurDegree of all - the neighbors are decremented and this node is marked OnStack. Hence - the effective neighbors in the AdjList are the ones that do not have the - OnStack flag set (therefore, they are in the IG). - - The methods that modify/use the CurDegree must be called only - after all modifications to the IG are over (i.e., all neighbors are fixed). - - The vector representation is the most efficient one for adj list. - Though nodes are removed when coalescing is done, we access it in sequence - for far many times when coloring (colorNode()). -*/ +// +// This file represents a node in an interference graph. +// +// For efficiency, the AdjList is updated only once - ie. we can add but not +// remove nodes from AdjList. +// +// The removal of nodes from IG is simulated by decrementing the CurDegree. +// If this node is put on stack (that is removed from IG), the CurDegree of all +// the neighbors are decremented and this node is marked OnStack. Hence +// the effective neighbors in the AdjList are the ones that do not have the +// OnStack flag set (therefore, they are in the IG). +// +// The methods that modify/use the CurDegree must be called only +// after all modifications to the IG are over (i.e., all neighbors are fixed). +// +// The vector representation is the most efficient one for adj list. +// Though nodes are removed when coalescing is done, we access it in sequence +// for far many times when coloring (colorNode()). +// +//===----------------------------------------------------------------------===// #ifndef IGNODE_H #define IGNODE_H From brukman at cs.uiuc.edu Thu Oct 23 13:05:05 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Oct 23 13:05:05 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAlloc/LiveRange.h LiveRangeInfo.cpp LiveRangeInfo.h Message-ID: <200310231804.NAA07204@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/RegAlloc: LiveRange.h updated: 1.23 -> 1.24 LiveRangeInfo.cpp updated: 1.45 -> 1.46 LiveRangeInfo.h updated: 1.21 -> 1.22 --- Log message: * Order #includes as per style guide * Doxygen-ify comments * Make code layout more consistent --- Diffs of the changes: (+45 -46) Index: llvm/lib/CodeGen/RegAlloc/LiveRange.h diff -u llvm/lib/CodeGen/RegAlloc/LiveRange.h:1.23 llvm/lib/CodeGen/RegAlloc/LiveRange.h:1.24 --- llvm/lib/CodeGen/RegAlloc/LiveRange.h:1.23 Tue Oct 21 10:17:13 2003 +++ llvm/lib/CodeGen/RegAlloc/LiveRange.h Thu Oct 23 13:03:49 2003 @@ -18,58 +18,58 @@ #ifndef LIVERANGE_H #define LIVERANGE_H -#include "llvm/CodeGen/ValueSet.h" #include "llvm/Value.h" +#include "llvm/CodeGen/ValueSet.h" class RegClass; class IGNode; class LiveRange : public ValueSet { - RegClass *MyRegClass; // register classs (e.g., int, FP) for this LR + RegClass *MyRegClass; // register class (e.g., int, FP) for this LR - // doesSpanAcrossCalls - Does this live range span across calls? - // This information is used by graph - // coloring algo to avoid allocating volatile colors to live ranges - // that span across calls (since they have to be saved/restored) - // + /// doesSpanAcrossCalls - Does this live range span across calls? + /// This information is used by graph coloring algo to avoid allocating + /// volatile colors to live ranges that span across calls (since they have to + /// be saved/restored) + /// bool doesSpanAcrossCalls; IGNode *UserIGNode; // IGNode which uses this LR int Color; // color assigned to this live range bool mustSpill; // whether this LR must be spilt - // mustSaveAcrossCalls - whether this LR must be saved accross calls - // ***TODO REMOVE this - // + /// mustSaveAcrossCalls - whether this LR must be saved accross calls + /// ***TODO REMOVE this + /// bool mustSaveAcrossCalls; - // SuggestedColor - if this LR has a suggested color, can it be - // really alloated? A suggested color cannot be allocated when the - // suggested color is volatile and when there are call - // interferences. - // + /// SuggestedColor - if this LR has a suggested color, can it be + /// really alloated? A suggested color cannot be allocated when the + /// suggested color is volatile and when there are call + /// interferences. + /// int SuggestedColor; // The suggested color for this LR - // CanUseSuggestedCol - It is possible that a suggested color for - // this live range is not available before graph coloring (e.g., it - // can be allocated to another live range which interferes with - // this) - // + /// CanUseSuggestedCol - It is possible that a suggested color for + /// this live range is not available before graph coloring (e.g., it + /// can be allocated to another live range which interferes with + /// this) + /// bool CanUseSuggestedCol; - // SpilledStackOffsetFromFP - If this LR is spilled, its stack - // offset from *FP*. The spilled offsets must always be relative to - // the FP. - // + /// SpilledStackOffsetFromFP - If this LR is spilled, its stack + /// offset from *FP*. The spilled offsets must always be relative to + /// the FP. + /// int SpilledStackOffsetFromFP; - // HasSpillOffset 0 Whether this live range has a spill offset - // + /// HasSpillOffset 0 Whether this live range has a spill offset + /// bool HasSpillOffset; - // The spill cost of this live range. Calculated using loop depth of - // each reference to each Value in the live range - // + /// The spill cost of this live range. Calculated using loop depth of + /// each reference to each Value in the live range + /// unsigned SpillCost; public: Index: llvm/lib/CodeGen/RegAlloc/LiveRangeInfo.cpp diff -u llvm/lib/CodeGen/RegAlloc/LiveRangeInfo.cpp:1.45 llvm/lib/CodeGen/RegAlloc/LiveRangeInfo.cpp:1.46 --- llvm/lib/CodeGen/RegAlloc/LiveRangeInfo.cpp:1.45 Mon Oct 20 14:43:16 2003 +++ llvm/lib/CodeGen/RegAlloc/LiveRangeInfo.cpp Thu Oct 23 13:03:50 2003 @@ -11,16 +11,16 @@ // //===----------------------------------------------------------------------===// +#include "IGNode.h" #include "LiveRangeInfo.h" #include "RegAllocCommon.h" #include "RegClass.h" -#include "IGNode.h" +#include "llvm/Function.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetRegInfo.h" -#include "llvm/Function.h" #include "Support/SetOperations.h" unsigned LiveRange::getRegClassID() const { return getRegClass()->getID(); } @@ -217,7 +217,6 @@ } } // for all machine instructions in the BB - } // for all BBs in function // Now we have to suggest clors for call and return arg live ranges. @@ -278,8 +277,7 @@ // Checks if live range LR interferes with any node assigned or suggested to // be assigned the specified color // -inline bool InterferesWithColor(const LiveRange& LR, unsigned color) -{ +inline bool InterferesWithColor(const LiveRange& LR, unsigned color) { IGNode* lrNode = LR.getUserIGNode(); for (unsigned n=0, NN = lrNode->getNumOfNeighbors(); n < NN; n++) { LiveRange *neighLR = lrNode->getAdjIGNode(n)->getParentLR(); @@ -299,8 +297,7 @@ // (4) LR2 has color and LR1 interferes with any LR that has the same color // inline bool InterfsPreventCoalescing(const LiveRange& LROfDef, - const LiveRange& LROfUse) -{ + const LiveRange& LROfUse) { // (4) if they have different suggested colors, cannot coalesce if (LROfDef.hasSuggestedColor() && LROfUse.hasSuggestedColor()) return true; Index: llvm/lib/CodeGen/RegAlloc/LiveRangeInfo.h diff -u llvm/lib/CodeGen/RegAlloc/LiveRangeInfo.h:1.21 llvm/lib/CodeGen/RegAlloc/LiveRangeInfo.h:1.22 --- llvm/lib/CodeGen/RegAlloc/LiveRangeInfo.h:1.21 Tue Oct 21 10:17:13 2003 +++ llvm/lib/CodeGen/RegAlloc/LiveRangeInfo.h Thu Oct 23 13:03:50 2003 @@ -87,20 +87,22 @@ std::vector & RCList); - // Destructor to destroy all LiveRanges in the LiveRange Map + /// Destructor to destroy all LiveRanges in the LiveRange Map + /// ~LiveRangeInfo(); // Main entry point for live range construction // void constructLiveRanges(); - // return the common live range map for this method - // + /// return the common live range map for this method + /// inline const LiveRangeMapType *getLiveRangeMap() const { return &LiveRangeMap; } - // Method used to get the live range containing a Value. - // This may return NULL if no live range exists for a Value (eg, some consts) + /// Method used to get the live range containing a Value. + /// This may return NULL if no live range exists for a Value (eg, some consts) + /// inline LiveRange *getLiveRangeForValue(const Value *Val) { return LiveRangeMap[Val]; } @@ -109,13 +111,13 @@ return I->second; } - // Method for coalescing live ranges. Called only after interference info - // is calculated. - // + /// Method for coalescing live ranges. Called only after interference info + /// is calculated. + /// void coalesceLRs(); - // debugging method to print the live ranges - // + /// debugging method to print the live ranges + /// void printLiveRanges(); }; From brukman at cs.uiuc.edu Thu Oct 23 13:07:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Oct 23 13:07:01 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp PhyRegAlloc.h Message-ID: <200310231806.NAA13874@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/RegAlloc: PhyRegAlloc.cpp updated: 1.121 -> 1.122 PhyRegAlloc.h updated: 1.57 -> 1.58 --- Log message: * Fix order of #include files * Doxygen-ify method comments --- Diffs of the changes: (+22 -21) Index: llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp diff -u llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.121 llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.122 --- llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.121 Wed Oct 22 15:44:23 2003 +++ llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp Thu Oct 23 13:06:27 2003 @@ -20,29 +20,29 @@ // //===----------------------------------------------------------------------===// +#include "IGNode.h" #include "PhyRegAlloc.h" #include "RegAllocCommon.h" #include "RegClass.h" -#include "IGNode.h" +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/iOther.h" +#include "llvm/Module.h" +#include "llvm/Type.h" +#include "llvm/Analysis/LoopInfo.h" #include "llvm/CodeGen/FunctionLiveVarInfo.h" #include "llvm/CodeGen/InstrSelection.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineFunctionInfo.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineInstrAnnot.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineFunctionInfo.h" #include "llvm/CodeGen/Passes.h" -#include "llvm/Analysis/LoopInfo.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Type.h" -#include "llvm/iOther.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Constants.h" -#include "llvm/Module.h" #include "llvm/Support/InstIterator.h" -#include "Support/STLExtras.h" -#include "Support/SetOperations.h" +#include "llvm/Target/TargetInstrInfo.h" #include "Support/CommandLine.h" +#include "Support/SetOperations.h" +#include "Support/STLExtras.h" #include RegAllocDebugLevel_t DEBUG_RA; Index: llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.h diff -u llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.h:1.57 llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.h:1.58 --- llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.h:1.57 Wed Oct 22 15:44:29 2003 +++ llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.h Thu Oct 23 13:06:27 2003 @@ -27,8 +27,8 @@ #include "LiveRangeInfo.h" #include "llvm/Pass.h" #include "llvm/CodeGen/MachineBasicBlock.h" -#include "llvm/Target/TargetRegInfo.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetRegInfo.h" #include class MachineFunction; @@ -136,8 +136,9 @@ MachineBasicBlock::iterator& MII, MachineBasicBlock &MBB, unsigned OpNum); - // Method for inserting caller saving code. The caller must save all the - // volatile registers live across a call. + /// Method for inserting caller saving code. The caller must save all the + /// volatile registers live across a call. + /// void insertCallerSavingCode(std::vector& instrnsBefore, std::vector& instrnsAfter, MachineInstr *CallMI, @@ -154,12 +155,12 @@ std::vector& MIBef, std::vector& MIAft); - // Callback method used to find unused registers. - // LVSetBef is the live variable set to search for an unused register. - // If it is not specified, the LV set before the current MI is used. - // This is sufficient as long as no new copy instructions are generated - // to copy the free register to memory. - // + /// Callback method used to find unused registers. + /// LVSetBef is the live variable set to search for an unused register. + /// If it is not specified, the LV set before the current MI is used. + /// This is sufficient as long as no new copy instructions are generated + /// to copy the free register to memory. + /// int getUnusedUniRegAtMI(RegClass *RC, int RegType, const MachineInstr *MI, const ValueSet *LVSetBef = 0); From gaeke at cs.uiuc.edu Thu Oct 23 13:11:02 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu Oct 23 13:11:02 2003 Subject: [llvm-commits] CVS: llvm/docs/TestingGuide.html Message-ID: <200310231810.NAA12548@gally.cs.uiuc.edu> Changes in directory llvm/docs: TestingGuide.html updated: 1.2 -> 1.3 --- Log message: Reformat. A few minor edits. --- Diffs of the changes: (+297 -221) Index: llvm/docs/TestingGuide.html diff -u llvm/docs/TestingGuide.html:1.2 llvm/docs/TestingGuide.html:1.3 --- llvm/docs/TestingGuide.html:1.2 Fri Oct 10 14:50:53 2003 +++ llvm/docs/TestingGuide.html Thu Oct 23 13:10:28 2003 @@ -1,351 +1,427 @@ - - LLVM Test Suite Guide - - - - -

    LLVM Test Suite Guide

    + + + + LLVM Test Suite Guide + + + + +
    + LLVM Test Suite Guide +
    + +
      +
    1. Overview
    2. +
    3. Requirements
    4. +
    5. Quick Start
    6. +
    7. LLVM Test Suite Organization
    8. + +
    9. LLVM Test Suite Tree
    10. +
    11. QMTest Structure
    12. +
    13. Programs Structure
    14. +
    15. Running the LLVM Tests
    16. +

      Written by John T. Criswell

      +
    -

    Overview

    + - This document is the reference manual for the LLVM test suite. It +
    +

    + This document is the reference manual for the LLVM test suite. It documents the structure of the LLVM test suite, the tools needed to use it, and how to add and run tests. +

    +
    -

    Requirements

    + +
    +

    In order to use the LLVM test suite, you will need all of the software required to build LLVM, plus the following: +

    -
    QMTest -
    - The LLVM test suite uses QMTest to organize and run tests. -

    - -

    Python -
    - You will need a python interpreter that works with QMTest. - Python will need zlib and SAX support enabled. -

    +

    QMTest
    +
    The LLVM test suite uses QMTest to organize and + run tests.
    + +
    Python
    +
    You will need a Python interpreter that works with + QMTest. Python will need zlib and SAX support + enabled.
    +
    -

    Quick Start

    + - To run all of the tests in LLVM, use the Master Makefile in llvm/test: -

    - - cd test -
    - make -
    +

    +

    + The tests are located in the LLVM source tree under the directory + llvm/test. To run all of the tests in LLVM, use the Master + Makefile in that directory: +

    +
    +	 % make -C llvm/test
    +	

    - To run only the code fragment tests (i.e. those that do basic testing of LLVM), run the tests organized by QMTest: -

    +

    - - cd test -
    - make qmtest -
    +
    +	 % make -C llvm/test qmtest
    +	

    - To run only the tests that compile and execute whole programs, run the Programs tests: -

    +

    - - cd test/Programs -
    - make -
    -

    +

    +	 % make -C llvm/test/Programs
    +	
    +
    -

    LLVM Test Suite Organization

    + - The LLVM test suite contains two major types of tests: -
      -
    • Code Fragments
      +
      +

      The LLVM test suite contains two major categories of tests: code + fragments and whole programs.

      +
      + + + +
      +

      Code fragments are small pieces of code that test a specific feature of LLVM or trigger a specific bug in LLVM. They are usually written in LLVM assembly language, but can be - written in other languages if the test targets a particular language - front end. -

      - Code fragments are not complete programs, and they are never executed - to determine correct behavior. -

      - The tests in the llvm/test/Features and llvm/test/Regression directories - contain code fragments. - -

    • Whole Programs
      - Whole Programs are pieces of code which can be compiled and - linked into a stand-alone program that can be executed. These programs - are generally written in high level languages such as C or C++, but - sometimes they are written straight in LLVM assembly. -

      - These programs are compiled and then executed using several different - methods (native compiler, LLVM C backend, LLVM JIT, LLVM native code - generation, etc). The output of these programs is compared to ensure - that LLVM is compiling the program correctly. - -

      - In addition to compiling and executing programs, whole program tests - serve as a way of benchmarking LLVM performance, both in terms of the - efficiency of the programs generated as well as the speed with which - LLVM compiles, optimizes, and generates code. - -

      - The test/Programs directory contains all tests which compile and + written in other languages if the test targets a + particular language front end. +

      + Code fragments are not complete programs, and they are + never executed to determine correct behavior. +

      + The tests in the Features and + Regression directories contain code fragments. +

      + + + + +
      +

      + Whole Programs are pieces of code which can be compiled and + linked into a stand-alone program that can be executed. These + programs are generally written in high level languages such as C + or C++, but sometimes they are written straight in LLVM + assembly. +

      + These programs are compiled and then executed using several + different methods (native compiler, LLVM C backend, LLVM JIT, + LLVM native code generation, etc). The output of these programs + is compared to ensure that LLVM is compiling the program + correctly. +

      + In addition to compiling and executing programs, whole program + tests serve as a way of benchmarking LLVM performance, both in + terms of the efficiency of the programs generated as well as the + speed with which LLVM compiles, optimizes, and generates code. +

      + The Programs directory contains all tests which compile and benchmark whole programs. -

    +

    + -

    LLVM Test Suite Tree

    + - The LLVM test suite is broken up into the following directory - hierarchy: - +
    +

    Each type of test in the LLVM test suite has its own directory. The + major subtrees of the test suite directory tree are as follows:

    +
      -
    • Features
      - This directory contains sample codes that test various features +
    • Features +

      + This directory contains sample codes that test various features of the LLVM language. These pieces of sample code are run through various assembler, disassembler, and optimizer passes. -

      +

      -
    • Regression
      +
    • Regression +

      This directory contains regression tests for LLVM. When a bug is found in LLVM, a regression test containing just enough code to reproduce the problem should be written and placed somewhere underneath this directory. In most cases, this will be a small piece of LLVM assembly language code, often distilled from an actual application or benchmark. -

      +

      -
    • Programs
      - The Programs directory contains programs that can be compiled +
    • Programs +

      + The Programs directory contains programs that can be compiled with LLVM and executed. These programs are compiled using the native compiler and various LLVM backends. The output from the program compiled with the native compiler is assumed correct; the results from the other programs are compared to the native program output and pass if they match. -

      +

      In addition for testing correctness, the Programs directory also performs timing tests of various LLVM optimizations. It also records compilation times for the compilers and the JIT. This information can be used to compare the effectiveness of LLVM's optimizations and code generation. -

      +

      The Programs directory is subdivided into several smaller subdirectories: +

      +
        -
      • SingleSource
        +
      • Programs/SingleSource +

        The SingleSource directory contains test programs that are only a single source file in size. These are usually small benchmark programs or small programs that - calculate a particular value. Several such programs are grouped - together in each directory. -

        - -

      • MultiSource
        - The MultiSource directory contains subdirectories which contain - entire programs with multiple source files. Large benchmarks and - whole applications go here. -

        + calculate a particular value. Several such programs are + grouped together in each directory. +

        + +
      • Programs/MultiSource +

        + The MultiSource directory contains subdirectories which + contain entire programs with multiple source files. + Large benchmarks and whole applications go here. +

        -
      • External
        +
      • Programs/External +

        The External directory contains Makefiles for building code that is external to (i.e. not distributed with) LLVM. The most prominent member of this directory is - the SPEC 2000 benchmark suite. The presence and location - of these external programs is configured by the LLVM - configure script. + the SPEC 2000 benchmark suite. The presence and + location of these external programs is configured by the + LLVM configure script. +

      -

    • QMTest
      - This directory contains the QMTest information files. Inside this - directory are QMTest administration files and the Python code that - implements the LLVM test and database classes. +
    • QMTest +

      + This directory contains the QMTest information files. Inside + this directory are QMTest administration files and the Python + code that implements the LLVM test and database classes. +

    +
    -

    QMTest Structure

    + - The LLVM test suite is partially driven by QMTest and partially +
    +

    + The LLVM test suite is partially driven by QMTest and partially driven by GNU Make. Specifically, the Features and Regression tests are all driven by QMTest. The Programs directory is currently driven by a set of Makefiles. -

    - +

    The QMTest system needs to have several pieces of information available; these pieces of configuration information are known collectively as the "context" in QMTest parlance. Since the context for LLVM is relatively large, the master Makefile in llvm/test sets it for you. - -

    - - The LLVM database class makes the directory tree underneath llvm/test a +

    + The LLVM database class makes the subdirectories of llvm/test a QMTest test database. For each directory that contains tests driven by QMTest, it knows what type of test the source file is and how to run it. - -

    - - Hence, the QMTest namespace is essentially what you see in - llvm/test/Feature and llvm/test/Regression, but there is some magic that +

    + Hence, the QMTest namespace is essentially what you see in the + Feature and Regression directories, but there is some magic that the database class performs (as described below). - -

    - +

    The QMTest namespace is currently composed of the following tests and test suites: +

      -
    • Feature
      - These are the feature tests found in llvm/test/Feature. They are broken - up into the following categories: +
    • Feature +

      + These are the feature tests found in the Feature directory. + They are broken up into the following categories: +

        -
      • ad
        - Assembler/Disassembler tests. These tests verify that a piece of - LLVM assembly language can be assembled into bytecode and then - disassembled into the original assembly language code. - It does this several times to ensure that assembled - output can be disassembled and disassembler output can - be assembled. It also verifies that the give assembly language file - can be assembled correctly. +
      • ad

        + Assembler/Disassembler tests. These tests verify that a + piece of LLVM assembly language can be assembled into + bytecode and then disassembled into the original + assembly language code. It does this several times to + ensure that assembled output can be disassembled and + disassembler output can be assembled. It also verifies + that the give assembly language file can be assembled + correctly. +

        -
      • opt
        +
      • opt +

        Optimizer tests. These tests verify that two of the optimizer passes completely optimize a program (i.e. after a single pass, they cannot optimize a program any further). -

        +

        -
      • mc
        - Machine code tests. These tests verify that the LLVM assembly - language file can be translated into native assembly code. +
      • mc

        + Machine code tests. These tests verify that the LLVM + assembly language file can be translated into native + assembly code. +

        -
      • cc
        - C code tests. These tests verify that the specified LLVM assembly - code can be converted into C source code using the C backend. +
      • cc +

        + C code tests. These tests verify that the specified + LLVM assembly code can be converted into C source code + using the C backend. +

      - - The LLVM database class looks at every file in llvm/test/Feature and - creates a fake test hierarchy containing - Feature.<testtype>.<testname>. - So, if you add an LLVM assembly language file to llvm/test/Feature, it - actually creates 5 news test: assembler/disassembler, assembler, + The LLVM database class looks at every file in the Feature + directory and creates a fake test hierarchy containing + Feature.<testtype>.<testname>. So, if you + add an LLVM assembly language file to the Feature directory, it + actually creates 5 new tests: assembler/disassembler, assembler, optimizer, machine code, and C code. +

      -
    • Regression
      - These are the regression tests. There is one suite for each directory - in llvm/test/Regression. -

      - - If you add a new directory to llvm/test/Regression, you will need to - modify llvm/test/QMTest/llvmdb.py so that it knows what sorts of tests - are in it and how to run them. +

    • Regression +

      + These are the regression tests. There is one suite for each + subdirectory of the Regression directory. If you add a new + subdirectory there, you will need to modify, at least, the + RegressionMap variable in QMTest/llvmdb.py so + that QMTest knows how to run the tests in the new subdirectory. +

    +
    -

    Programs Structure

    - - As mentioned previously, the Programs tree in llvm/test provides three types - of tests: MultiSource, SingleSource, and External. Each tree is then - subdivided into several categories, including applications, benchmarks, - regression tests, code that is strange grammatically, etc. These - organizations should be relatively self explanatory. -

    - In addition to the regular Programs tests, the Programs tree also provides a - mechanism for compiling the programs in different ways. If the variable TEST - is defined on the gmake command line, the test system will include a Makefile - named TEST.<value of TEST variable>.Makefile. This Makefile can modify - build rules that yield different results. -

    - For example, the LLVM nightly tester uses TEST.nightly.Makefile to create the - nightly test reports. To run the nightly tests, run gmake - TEST=nightly. -

    - There are several TEST Makefiles available in the tree. Some of them are - designed for internal LLVM research and will not work outside of the LLVM - research group. They may still be valuable, however, as a guide to writing - your own TEST Makefile for any optimization or analysis passes that you - develop with LLVM. - - -

    Running the LLVM Tests

    + - First, all tests are executed within the LLVM object directory tree. They - are not executed inside of the LLVM source tree. This is because - the test suite creates temporary files during execution. - -

    - +

    +

    + As mentioned previously, the Programs tree in llvm/test provides three + types of tests: MultiSource, SingleSource, and External. Each tree is + then subdivided into several categories, including applications, + benchmarks, regression tests, code that is strange grammatically, etc. + These organizations should be relatively self explanatory. +

    + In addition to the regular Programs tests, the Programs tree also + provides a mechanism for compiling the programs in different ways. If + the variable TEST is defined on the gmake command line, the test system + will include a Makefile named TEST.<value of TEST + variable>.Makefile. This Makefile can modify build rules to + yield different results. +

    + For example, the LLVM nightly tester uses TEST.nightly.Makefile + to create the nightly test reports. To run the nightly tests, run + gmake TEST=nightly. +

    + There are several TEST Makefiles available in the tree. Some of them + are designed for internal LLVM research and will not work outside of the + LLVM research group. They may still be valuable, however, as a guide to + writing your own TEST Makefile for any optimization or analysis passes + that you develop with LLVM. +

    +
    + + + + + +
    +

    + First, all tests are executed within the LLVM object directory tree. + They 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 both the QMTest driven tests and the Programs tests. By default, it will run all of the tests. -

    +

    To run only the QMTest driven tests, run make qmtest at the - command line in llvm/tests. To run a specific qmtest, suffix the test name - with ".t" when running make. -

    + command line in llvm/tests. To run a specific qmtest, suffix the test + name with ".t" when running make. +

    For example, to run the Regression.LLC tests, type make Regression.LLC.t in llvm/tests. -

    +

    Note that the Makefiles in llvm/test/Features and llvm/test/Regression - are gone. You must now use QMTest from the llvm/test directory to run them. -

    - - To run the Programs test, cd into the llvm/test/Programs directory - and type make. Alternatively, you can type make + are gone. You must now use QMTest from the llvm/test directory to run + them. +

    + To run the Programs test, cd into the llvm/test/Programs directory and + type make. Alternatively, you can type make TEST=<type> test to run one of the specialized tests in - llvm/test/Programs/TEST.<type>.Makefile. For example, you could run - the nightly tester tests using the following commands: -

    - - cd llvm/test/Programs -
    - make TEST=nightly test -
    + llvm/test/Programs/TEST.<type>.Makefile. For example, you could + run the nightly tester tests using the following commands: +

    + +
    +	 % cd llvm/test/Programs
    +	 % make TEST=nightly test
    +	

    - Regardless of which test you're running, the results are printed on standard - output and standard error. You can redirect these results to a file if you - choose. -

    + Regardless of which test you're running, the results are printed on + standard output and standard error. You can redirect these results to a + file if you choose. +

    Some tests are known to fail. Some are bugs that we have not fixed yet; - others are features that we haven't added yet (or may never add). In QMTest, - the result for such tests will be XFAIL (eXpected FAILure). In this way, you - can tell the difference between an expected and unexpected failure. -

    - The Programs tests have no such feature as of this time. If the test passes, - only warnings and other miscellaneous output will be generated. If a test - fails, a large <program> FAILED message will be displayed. This will - help you separate benign warnings from actual test failures. - -


    + others are features that we haven't added yet (or may never add). In + QMTest, the result for such tests will be XFAIL (eXpected FAILure). In + this way, you can tell the difference between an expected and unexpected + failure. +

    + The Programs tests have no such feature as of this time. If the test + passes, only warnings and other miscellaneous output will be generated. + If a test fails, a large <program> FAILED message will be + displayed. This will help you separate benign warnings from actual test + failures. +

    +
    + + + +
    +
    John T. Criswell
    +Last modified: $Date: 2003/10/23 18:10:28 $ +
    - + From brukman at cs.uiuc.edu Thu Oct 23 13:11:21 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Oct 23 13:11:21 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAlloc/InterferenceGraph.cpp RegClass.cpp Message-ID: <200310231810.NAA23480@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/RegAlloc: InterferenceGraph.cpp updated: 1.17 -> 1.18 RegClass.cpp updated: 1.26 -> 1.27 --- Log message: * Eliminate `using' directive * Fix order of #includes * Make code layout more consistent * Eliminate extraneous whitespace and comment-lines --- Diffs of the changes: (+26 -52) Index: llvm/lib/CodeGen/RegAlloc/InterferenceGraph.cpp diff -u llvm/lib/CodeGen/RegAlloc/InterferenceGraph.cpp:1.17 llvm/lib/CodeGen/RegAlloc/InterferenceGraph.cpp:1.18 --- llvm/lib/CodeGen/RegAlloc/InterferenceGraph.cpp:1.17 Mon Oct 20 14:43:16 2003 +++ llvm/lib/CodeGen/RegAlloc/InterferenceGraph.cpp Thu Oct 23 13:10:02 2003 @@ -11,12 +11,11 @@ // //===----------------------------------------------------------------------===// -#include "RegAllocCommon.h" -#include "InterferenceGraph.h" #include "IGNode.h" +#include "InterferenceGraph.h" +#include "RegAllocCommon.h" #include "Support/STLExtras.h" #include -using std::cerr; // for asserting this IG node is infact in the IGNodeList of this class inline static void assertIGNode(const InterferenceGraph *IG, Index: llvm/lib/CodeGen/RegAlloc/RegClass.cpp diff -u llvm/lib/CodeGen/RegAlloc/RegClass.cpp:1.26 llvm/lib/CodeGen/RegAlloc/RegClass.cpp:1.27 --- llvm/lib/CodeGen/RegAlloc/RegClass.cpp:1.26 Mon Oct 20 14:43:16 2003 +++ llvm/lib/CodeGen/RegAlloc/RegClass.cpp Thu Oct 23 13:10:02 2003 @@ -11,9 +11,9 @@ // //===----------------------------------------------------------------------===// -#include "RegClass.h" -#include "RegAllocCommon.h" #include "IGNode.h" +#include "RegAllocCommon.h" +#include "RegClass.h" #include "llvm/Target/TargetRegInfo.h" //---------------------------------------------------------------------------- @@ -26,7 +26,7 @@ : Meth(M), MRI(_MRI_), MRC(_MRC_), RegClassID( _MRC_->getRegClassID() ), IG(this), IGNodeStack() { - if( DEBUG_RA >= RA_DEBUG_Interference) + if (DEBUG_RA >= RA_DEBUG_Interference) std::cerr << "Created Reg Class: " << RegClassID << "\n"; IsColorUsedArr.resize(MRC->getNumOfAllRegs()); @@ -39,23 +39,19 @@ //---------------------------------------------------------------------------- void RegClass::colorAllRegs() { - if(DEBUG_RA >= RA_DEBUG_Coloring) + if (DEBUG_RA >= RA_DEBUG_Coloring) std::cerr << "Coloring IG of reg class " << RegClassID << " ...\n"; - // pre-color IGNodes pushAllIGNodes(); // push all IG Nodes unsigned int StackSize = IGNodeStack.size(); IGNode *CurIGNode; - // for all LRs on stack - for( unsigned int IGN=0; IGN < StackSize; IGN++) { - + for (unsigned int IGN=0; IGN < StackSize; IGN++) { CurIGNode = IGNodeStack.top(); // pop the IGNode on top of stack IGNodeStack.pop(); colorIGNode (CurIGNode); // color it } - } @@ -73,13 +69,13 @@ // push non-constrained IGNodes bool PushedAll = pushUnconstrainedIGNodes(); - if( DEBUG_RA >= RA_DEBUG_Coloring) { + if (DEBUG_RA >= RA_DEBUG_Coloring) { std::cerr << " Puhsed all-unconstrained IGNodes. "; if( PushedAll ) std::cerr << " No constrained nodes left."; std::cerr << "\n"; } - if( PushedAll ) // if NO constrained nodes left + if (PushedAll) // if NO constrained nodes left return; @@ -89,24 +85,15 @@ do { //get node with min spill cost - // IGNode *IGNodeSpill = getIGNodeWithMinSpillCost(); - // push that node on to stack - // IGNodeStack.push(IGNodeSpill); - // set its OnStack flag and decrement degree of neighs - // IGNodeSpill->pushOnStack(); - // now push NON-constrained ones, if any - // NeedMoreSpills = !pushUnconstrainedIGNodes(); - if (DEBUG_RA >= RA_DEBUG_Coloring) std::cerr << "\nConstrained IG Node found !@!" << IGNodeSpill->getIndex(); - } while(NeedMoreSpills); // repeat until we have pushed all } @@ -127,21 +114,21 @@ bool pushedall = true; // a pass over IGNodeList - for( unsigned i =0; i < IGNodeListSize; i++) { + for (unsigned i =0; i < IGNodeListSize; i++) { // get IGNode i from IGNodeList IGNode *IGNode = IG.getIGNodeList()[i]; - if( !IGNode ) // can be null due to merging + if (!IGNode ) // can be null due to merging continue; // if already pushed on stack, continue. This can happen since this // method can be called repeatedly until all constrained nodes are // pushed - if( IGNode->isOnStack() ) + if (IGNode->isOnStack() ) continue; // if the degree of IGNode is lower - if( (unsigned) IGNode->getCurDegree() < MRC->getNumOfAvailRegs()) { + if ((unsigned) IGNode->getCurDegree() < MRC->getNumOfAvailRegs()) { IGNodeStack.push( IGNode ); // push IGNode on to the stack IGNode->pushOnStack(); // set OnStack and dec deg of neighs @@ -163,9 +150,7 @@ //---------------------------------------------------------------------------- // Get the IGNode with the minimum spill cost //---------------------------------------------------------------------------- -IGNode * RegClass::getIGNodeWithMinSpillCost() -{ - +IGNode * RegClass::getIGNodeWithMinSpillCost() { unsigned int IGNodeListSize = IG.getIGNodeList().size(); double MinSpillCost = 0; IGNode *MinCostIGNode = NULL; @@ -173,45 +158,37 @@ // pass over IGNodeList to find the IGNode with minimum spill cost // among all IGNodes that are not yet pushed on to the stack - // - for( unsigned int i =0; i < IGNodeListSize; i++) { + for (unsigned int i =0; i < IGNodeListSize; i++) { IGNode *IGNode = IG.getIGNodeList()[i]; - if( ! IGNode ) // can be null due to merging + if (!IGNode) // can be null due to merging continue; - if( ! IGNode->isOnStack() ) { - + if (!IGNode->isOnStack()) { double SpillCost = (double) IGNode->getParentLR()->getSpillCost() / (double) (IGNode->getCurDegree() + 1); - if( isFirstNode ) { // for the first IG node + if (isFirstNode) { // for the first IG node MinSpillCost = SpillCost; MinCostIGNode = IGNode; isFirstNode = false; - } - - else if( MinSpillCost > SpillCost) { + } else if (MinSpillCost > SpillCost) { MinSpillCost = SpillCost; MinCostIGNode = IGNode; } - } } - assert( MinCostIGNode && "No IGNode to spill"); + assert (MinCostIGNode && "No IGNode to spill"); return MinCostIGNode; } - //---------------------------------------------------------------------------- // Color the IGNode using the machine specific code. //---------------------------------------------------------------------------- -void RegClass::colorIGNode(IGNode *const Node) -{ - - if( ! Node->hasColor() ) { // not colored as an arg etc. +void RegClass::colorIGNode(IGNode *const Node) { + if (! Node->hasColor()) { // not colored as an arg etc. // init all elements of to IsColorUsedAr false; clearColorsUsed(); @@ -242,22 +219,20 @@ // call the target specific code for coloring // MRC->colorIGNode(Node, IsColorUsedArr); - } - else { - if( DEBUG_RA >= RA_DEBUG_Coloring) { + } else { + if (DEBUG_RA >= RA_DEBUG_Coloring) { std::cerr << " Node " << Node->getIndex(); std::cerr << " already colored with color " << Node->getColor() << "\n"; } } - if( !Node->hasColor() ) { - if( DEBUG_RA >= RA_DEBUG_Coloring) { + if (!Node->hasColor() ) { + if (DEBUG_RA >= RA_DEBUG_Coloring) { std::cerr << " Node " << Node->getIndex(); std::cerr << " - could not find a color (needs spilling)\n"; } } - } void RegClass::printIGNodeList() const { From lattner at cs.uiuc.edu Thu Oct 23 13:27:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 13:27:02 2003 Subject: [llvm-commits] CVS: llvm/tools/gccld/GenerateCode.cpp Message-ID: <200310231826.NAA00382@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccld: GenerateCode.cpp updated: 1.9 -> 1.10 --- Log message: Turn on the IPCP pass by default. It has passed all of the tests --- Diffs of the changes: (+3 -0) Index: llvm/tools/gccld/GenerateCode.cpp diff -u llvm/tools/gccld/GenerateCode.cpp:1.9 llvm/tools/gccld/GenerateCode.cpp:1.10 --- llvm/tools/gccld/GenerateCode.cpp:1.9 Mon Oct 20 12:58:43 2003 +++ llvm/tools/gccld/GenerateCode.cpp Thu Oct 23 13:25:57 2003 @@ -68,6 +68,9 @@ Passes.add(createInternalizePass()); } + // Propagate constants at call sites into the functions they call. + Passes.add(createIPConstantPropagationPass()); + // Remove unused arguments from functions... Passes.add(createDeadArgEliminationPass()); From lattner at cs.uiuc.edu Thu Oct 23 13:27:16 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 13:27:16 2003 Subject: [llvm-commits] CVS: llvm/tools/gccas/gccas.cpp Message-ID: <200310231826.NAA00375@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccas: gccas.cpp updated: 1.82 -> 1.83 --- Log message: Turn on the IPCP pass by default. It has passed all of the tests --- Diffs of the changes: (+4 -0) Index: llvm/tools/gccas/gccas.cpp diff -u llvm/tools/gccas/gccas.cpp:1.82 llvm/tools/gccas/gccas.cpp:1.83 --- llvm/tools/gccas/gccas.cpp:1.82 Mon Oct 20 12:58:41 2003 +++ llvm/tools/gccas/gccas.cpp Thu Oct 23 13:25:53 2003 @@ -56,8 +56,12 @@ PM.add(createVerifierPass()); // Verify that input is correct addPass(PM, createLowerSetJmpPass()); // Lower llvm.setjmp/.longjmp addPass(PM, createFunctionResolvingPass()); // Resolve (...) functions + addPass(PM, createCFGSimplificationPass()); // Clean up disgusting code addPass(PM, createRaiseAllocationsPass()); // call %malloc -> malloc inst addPass(PM, createGlobalDCEPass()); // Remove unused globals + addPass(PM, createIPConstantPropagationPass());// IP Constant Propagation + addPass(PM, createDeadArgEliminationPass()); // Dead argument elimination + addPass(PM, createPruneEHPass()); // Remove dead EH info if (!DisableInline) From lattner at cs.uiuc.edu Thu Oct 23 13:40:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 13:40:01 2003 Subject: [llvm-commits] CVS: llvm/lib/CWriter/Writer.cpp Message-ID: <200310231839.NAA00592@zion.cs.uiuc.edu> Changes in directory llvm/lib/CWriter: Writer.cpp updated: 1.136 -> 1.137 --- Log message: Fail gracefully if we have a zero arg varargs function --- Diffs of the changes: (+6 -0) Index: llvm/lib/CWriter/Writer.cpp diff -u llvm/lib/CWriter/Writer.cpp:1.136 llvm/lib/CWriter/Writer.cpp:1.137 --- llvm/lib/CWriter/Writer.cpp:1.136 Mon Oct 20 14:43:15 2003 +++ llvm/lib/CWriter/Writer.cpp Thu Oct 23 13:39:22 2003 @@ -1193,6 +1193,12 @@ Out << "va_start(*(va_list*)&" << Mang->getValueName(&I) << ", "; // Output the last argument to the enclosing function... + if (I.getParent()->getParent()->aempty()) { + std::cerr << "The C backend does not currently support zero " + << "argument varargs functions, such as '" + << I.getParent()->getParent()->getName() << "'!\n"; + abort(); + } writeOperand(&I.getParent()->getParent()->aback()); Out << ")"; return; From lattner at cs.uiuc.edu Thu Oct 23 13:50:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 13:50:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/IPConstantPropagation.cpp Message-ID: <200310231849.NAA16456@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: IPConstantPropagation.cpp updated: 1.1 -> 1.2 --- Log message: We might as well strip off any CPRs before propagation --- Diffs of the changes: (+4 -1) Index: llvm/lib/Transforms/IPO/IPConstantPropagation.cpp diff -u llvm/lib/Transforms/IPO/IPConstantPropagation.cpp:1.1 llvm/lib/Transforms/IPO/IPConstantPropagation.cpp:1.2 --- llvm/lib/Transforms/IPO/IPConstantPropagation.cpp:1.1 Thu Oct 23 11:52:27 2003 +++ llvm/lib/Transforms/IPO/IPConstantPropagation.cpp Thu Oct 23 13:49:23 2003 @@ -103,7 +103,10 @@ // Do we have a constant argument!? if (!ArgumentConstants[i].second) { assert(ArgumentConstants[i].first && "Unknown constant value!"); - AI->replaceAllUsesWith(ArgumentConstants[i].first); + Value *V = ArgumentConstants[i].first; + if (ConstantPointerRef *CPR = dyn_cast(V)) + V = CPR->getValue(); + AI->replaceAllUsesWith(V); ++NumArgumentsProped; } return true; From gaeke at cs.uiuc.edu Thu Oct 23 13:52:02 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu Oct 23 13:52:02 2003 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp Message-ID: <200310231851.NAA02827@gally.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: RuntimeOptimizations.cpp updated: 1.7 -> 1.8 --- Log message: Comment out FunctionPassManager for now. --- Diffs of the changes: (+1 -1) Index: reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp diff -u reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp:1.7 reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp:1.8 --- reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp:1.7 Mon Sep 8 15:58:59 2003 +++ reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp Thu Oct 23 13:51:13 2003 @@ -57,11 +57,11 @@ DEBUG(std::cerr << "Function created from trace: \n" << *TF); // Run some stuff on it +#if 0 FunctionPassManager PM; PM.add (createVerifierPass ()); PM.run (*TF); -#if 0 // Make the ExecutionEngine generate code for the function and give us // a pointer to it. From gaeke at cs.uiuc.edu Thu Oct 23 13:53:02 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu Oct 23 13:53:02 2003 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/TraceToFunction.cpp Message-ID: <200310231852.NAA02878@gally.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: TraceToFunction.cpp updated: 1.9 -> 1.10 --- Log message: Add TODOs to head-of-file comment. Fix an apparently mistakenly reversed if-test. --- Diffs of the changes: (+18 -1) Index: reopt/lib/LightWtProfiling/TraceToFunction.cpp diff -u reopt/lib/LightWtProfiling/TraceToFunction.cpp:1.9 reopt/lib/LightWtProfiling/TraceToFunction.cpp:1.10 --- reopt/lib/LightWtProfiling/TraceToFunction.cpp:1.9 Tue Oct 14 16:24:52 2003 +++ reopt/lib/LightWtProfiling/TraceToFunction.cpp Thu Oct 23 13:51:54 2003 @@ -3,6 +3,23 @@ // Repackage traces as functions, so that global (function-level) optimizations // can be applied to traces. // +// TODO (also search for FIXME in this file): +// 1) Only let things go into the LiveIn/Out sets for which we have register +// allocation information available. Otherwise abort. +// a) Also only let things go into the LiveOut sets which definitely define +// a value (e.g., not "call void ...") +// 2) For each basic block that exits the trace, we need to keep track of the +// address that the "ret" instruction would have returned to. +// a) Use the O2CMap to find, for each Exit BB of the TraceFunction, the +// corresponding BB of the matrix Function. +// b) Get its Terminator, which should be a BranchInst having an off-Trace +// destination, which is a BasicBlock in the matrix Function. +// c) Use the mapping information (probably BB TO MI MAP) to translate the +// BasicBlock to a uint64_t address. (Figure out how Anand's code does +// this.) +// 3) a) Used before defined --> live-in and live-out: dui bu dui? +// b) Live in and not defined by trace --> not live out. +// //===----------------------------------------------------------------------===// #include "Trace.h" @@ -120,7 +137,7 @@ Value *V = I.getOperand (i); // V is used in the trace by instruction I. if (!(isa (V) || isa (V))) - if (DefinedInTraceBeforeUse (V, T)) + if (!DefinedInTraceBeforeUse (V, T)) S.insert (V); } } From criswell at cs.uiuc.edu Thu Oct 23 14:17:02 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Oct 23 14:17:02 2003 Subject: [llvm-commits] CVS: llvm/configure Message-ID: <200310231916.OAA30487@choi.cs.uiuc.edu> Changes in directory llvm: configure updated: 1.48 -> 1.49 --- Log message: Updated configure script. --- Diffs of the changes: (+1 -2) Index: llvm/configure diff -u llvm/configure:1.48 llvm/configure:1.49 --- llvm/configure:1.48 Thu Oct 16 19:50:38 2003 +++ llvm/configure Thu Oct 23 14:16:12 2003 @@ -19694,8 +19694,7 @@ - -for ac_header in malloc.h strings.h sys/mman.h sys/resource.h +for ac_header in malloc.h sys/mman.h sys/resource.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then From lattner at cs.uiuc.edu Thu Oct 23 14:27:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 14:27:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/CBackend/2003-10-23-UnusedType.ll Message-ID: <200310231926.OAA17541@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CBackend: 2003-10-23-UnusedType.ll added (r1.1) --- Log message: New testcase, which failes to compile. 252.eon hits this problem --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/CBackend/2003-10-23-UnusedType.ll diff -c /dev/null llvm/test/Regression/CBackend/2003-10-23-UnusedType.ll:1.1 *** /dev/null Thu Oct 23 14:26:03 2003 --- llvm/test/Regression/CBackend/2003-10-23-UnusedType.ll Thu Oct 23 14:25:53 2003 *************** *** 0 **** --- 1,3 ---- + + %A = type { uint, sbyte*, { uint, uint, uint, uint, uint, uint, uint, uint }*, ushort } + From lattner at cs.uiuc.edu Thu Oct 23 14:31:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 14:31:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/FindUsedTypes.cpp Message-ID: <200310231930.OAA18522@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: FindUsedTypes.cpp updated: 1.20 -> 1.21 --- Log message: Fix bug: CBackend/2003-10-23-UnusedType.ll and hopefully 252.eon --- Diffs of the changes: (+11 -0) Index: llvm/lib/Analysis/IPA/FindUsedTypes.cpp diff -u llvm/lib/Analysis/IPA/FindUsedTypes.cpp:1.20 llvm/lib/Analysis/IPA/FindUsedTypes.cpp:1.21 --- llvm/lib/Analysis/IPA/FindUsedTypes.cpp:1.20 Mon Oct 20 14:43:08 2003 +++ llvm/lib/Analysis/IPA/FindUsedTypes.cpp Thu Oct 23 14:30:30 2003 @@ -41,12 +41,22 @@ IncorporateType(*I); } +void FindUsedTypes::IncorporateSymbolTable(const SymbolTable &ST) { + SymbolTable::const_iterator TI = ST.find(Type::TypeTy); + if (TI == ST.end()) return; // No named types + + for (SymbolTable::type_const_iterator I = TI->second.begin(), + E = TI->second.end(); I != E; ++I) + IncorporateType(cast(I->second)); +} // run - This incorporates all types used by the specified module // bool FindUsedTypes::run(Module &m) { UsedTypes.clear(); // reset if run multiple times... + IncorporateSymbolTable(m.getSymbolTable()); + // Loop over global variables, incorporating their types for (Module::const_giterator I = m.gbegin(), E = m.gend(); I != E; ++I) IncorporateType(I->getType()); @@ -54,6 +64,7 @@ for (Module::iterator MI = m.begin(), ME = m.end(); MI != ME; ++MI) { IncorporateType(MI->getType()); const Function &F = *MI; + IncorporateSymbolTable(F.getSymbolTable()); // Loop over all of the instructions in the function, adding their return // type as well as the types of their operands. From lattner at cs.uiuc.edu Thu Oct 23 14:34:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 14:34:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/CallSite.h Message-ID: <200310231933.OAA20149@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: CallSite.h updated: 1.7 -> 1.8 --- Log message: Add assertions --- Diffs of the changes: (+6 -1) Index: llvm/include/llvm/Support/CallSite.h diff -u llvm/include/llvm/Support/CallSite.h:1.7 llvm/include/llvm/Support/CallSite.h:1.8 --- llvm/include/llvm/Support/CallSite.h:1.7 Mon Oct 20 15:19:26 2003 +++ llvm/include/llvm/Support/CallSite.h Thu Oct 23 14:33:49 2003 @@ -50,7 +50,10 @@ /// getCalledValue - Return the pointer to function that is being called... /// - Value *getCalledValue() const { return I->getOperand(0); } + Value *getCalledValue() const { + assert(I && "Not a call or invoke instruction!"); + return I->getOperand(0); + } /// getCalledFunction - Return the function being called if this is a direct /// call, otherwise return null (if it's an indirect call). @@ -62,6 +65,7 @@ /// setCalledFunction - Set the callee to the specified value... /// void setCalledFunction(Value *V) { + assert(I && "Not a call or invoke instruction!"); I->setOperand(0, V); } @@ -73,6 +77,7 @@ /// list for a call site. /// arg_iterator arg_begin() const { + assert(I && "Not a call or invoke instruction!"); if (I->getOpcode() == Instruction::Call) return I->op_begin()+1; // Skip Function else From lattner at cs.uiuc.edu Thu Oct 23 14:34:15 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 14:34:15 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/FindUsedTypes.h Message-ID: <200310231933.OAA20142@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: FindUsedTypes.h updated: 1.18 -> 1.19 --- Log message: Fix bug in eon hopefully --- Diffs of the changes: (+4 -0) Index: llvm/include/llvm/Analysis/FindUsedTypes.h diff -u llvm/include/llvm/Analysis/FindUsedTypes.h:1.18 llvm/include/llvm/Analysis/FindUsedTypes.h:1.19 --- llvm/include/llvm/Analysis/FindUsedTypes.h:1.18 Mon Oct 20 15:19:18 2003 +++ llvm/include/llvm/Analysis/FindUsedTypes.h Thu Oct 23 14:33:44 2003 @@ -39,6 +39,10 @@ /// void IncorporateType(const Type *Ty); + /// IncorporateSymbolTable - Include any named types. + /// + void IncorporateSymbolTable(const SymbolTable &ST); + public: /// run - This incorporates all types used by the specified module bool run(Module &M); From criswell at cs.uiuc.edu Thu Oct 23 14:45:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Oct 23 14:45:01 2003 Subject: [llvm-commits] CVS: llvm-www/releases/download.html Message-ID: <200310231944.OAA11016@choi.cs.uiuc.edu> Changes in directory llvm-www/releases: download.html updated: 1.1 -> 1.2 --- Log message: Enabling the downloading of LLVM. --- Diffs of the changes: (+0 -6) Index: llvm-www/releases/download.html diff -u llvm-www/releases/download.html:1.1 llvm-www/releases/download.html:1.2 --- llvm-www/releases/download.html:1.1 Wed Oct 15 15:00:05 2003 +++ llvm-www/releases/download.html Thu Oct 23 14:43:52 2003 @@ -30,16 +30,10 @@

      -
    - -
  • LLVM -
  • GCC Front End for x86 -
  • GCC Front End for Sparc From criswell at cs.uiuc.edu Thu Oct 23 14:46:00 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Oct 23 14:46:00 2003 Subject: [llvm-commits] CVS: llvm-www/releases/1.0/cfrontend.sparc.tar.gz cfrontend.x86.tar.gz llvm.tar.gz Message-ID: <200310231945.OAA11041@choi.cs.uiuc.edu> Changes in directory llvm-www/releases/1.0: cfrontend.sparc.tar.gz added (r1.1) cfrontend.x86.tar.gz added (r1.1) llvm.tar.gz added (r1.1) --- Log message: LLVM 1.0, Release Candidate 1 --- Diffs of the changes: (+0 -0) Index: llvm-www/releases/1.0/cfrontend.sparc.tar.gz Index: llvm-www/releases/1.0/cfrontend.x86.tar.gz Index: llvm-www/releases/1.0/llvm.tar.gz From lattner at cs.uiuc.edu Thu Oct 23 14:49:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 14:49:02 2003 Subject: [llvm-commits] CVS: llvm/docs/WritingAnLLVMPass.html Message-ID: <200310231948.OAA20463@zion.cs.uiuc.edu> Changes in directory llvm/docs: WritingAnLLVMPass.html updated: 1.19 -> 1.20 --- Log message: Remove explicit paths --- Diffs of the changes: (+2 -3) Index: llvm/docs/WritingAnLLVMPass.html diff -u llvm/docs/WritingAnLLVMPass.html:1.19 llvm/docs/WritingAnLLVMPass.html:1.20 --- llvm/docs/WritingAnLLVMPass.html:1.19 Wed Sep 10 00:29:43 2003 +++ llvm/docs/WritingAnLLVMPass.html Thu Oct 23 14:48:11 2003 @@ -1159,9 +1159,8 @@
     (gdb) break PassManager::run
     Breakpoint 1 at 0x2413bc: file Pass.cpp, line 70.
    -(gdb) run test.bc -load /shared/lattner/cvs/llvm/lib/Debug/[libname].so -[passoption]
    -Starting program: /shared/lattner/cvs/llvm/tools/Debug/opt test.bc 
    -    -load /shared/lattner/cvs/llvm/lib/Debug/[libname].so -[passoption]
    +(gdb) run test.bc -load $(LLVMTOP)/llvm/lib/Debug/[libname].so -[passoption]
    +Starting program: opt test.bc -load $(LLVMTOP)/llvm/lib/Debug/[libname].so -[passoption]
     Breakpoint 1, PassManager::run (this=0xffbef174, M=@0x70b298) at Pass.cpp:70
     70      bool PassManager::run(Module &M) { return PM->run(M); }
     (gdb)
    
    
    
    
    From lattner at cs.uiuc.edu  Thu Oct 23 14:50:03 2003
    From: lattner at cs.uiuc.edu (Chris Lattner)
    Date: Thu Oct 23 14:50:03 2003
    Subject: [llvm-commits] CVS: llvm/docs/GettingStarted.html
    Message-ID: <200310231949.OAA20489@zion.cs.uiuc.edu>
    
    
    Changes in directory llvm/docs:
    
    GettingStarted.html updated: 1.41 -> 1.42
    
    ---
    Log message:
    
    Recommend using -z3
    
    
    ---
    Diffs of the changes:  (+4 -4)
    
    Index: llvm/docs/GettingStarted.html
    diff -u llvm/docs/GettingStarted.html:1.41 llvm/docs/GettingStarted.html:1.42
    --- llvm/docs/GettingStarted.html:1.41	Tue Oct 21 16:24:38 2003
    +++ llvm/docs/GettingStarted.html	Thu Oct 23 14:49:01 2003
    @@ -110,7 +110,7 @@
                     
  • cd where-you-want-llvm-to-live
  • cvs -d :pserver:anon at llvm-cvs.cs.uiuc.edu:/var/cvs/llvm login
  • Hit the return key when prompted for the password. -
  • cvs -d :pserver:anon at llvm-cvs.cs.uiuc.edu:/var/cvs/llvm co llvm +
  • cvs -z3 -d :pserver:anon at llvm-cvs.cs.uiuc.edu:/var/cvs/llvm co llvm
  • cd llvm @@ -359,7 +359,7 @@
  • cd where-you-want-llvm-to-live
  • cvs -d :pserver:anon at llvm-cvs.cs.uiuc.edu:/var/cvs/llvm login
  • Hit the return key when prompted for the password. -
  • cvs -d :pserver:anon at llvm-cvs.cs.uiuc.edu:/var/cvs/llvm co llvm +
  • cvs -z3 -d :pserver:anon at llvm-cvs.cs.uiuc.edu:/var/cvs/llvm co llvm

    This will create an 'llvm' directory in the current @@ -820,7 +820,7 @@ that has been retargeted to emit LLVM code as the machine code output. It works just like any other GCC compiler, taking the typical -c, -S, -E, -o options that are typically used. The source code for the - llvmgcc tool is currently not included in the LLVM cvs tree + llvmgcc tool is currently not included in the LLVM CVS tree because it is quite large and not very interesting.

      @@ -874,7 +874,7 @@
      cvsupdate
      cvsupdate is a script that will update your CVS tree, but produce a much cleaner and more organized output - than simply running `cvs up -dP' will. For example, it will group + than simply running `cvs -z3 up -dP' will. For example, it will group together all the new and updated files and modified files in separate sections, so you can see at a glance what has changed. If you are at the top of your LLVM CVS tree, running utils/cvsupdate is the From criswell at cs.uiuc.edu Thu Oct 23 15:02:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Oct 23 15:02:01 2003 Subject: [llvm-commits] [release_1] CVS: llvm/LICENSE.TXT Message-ID: <200310232001.PAA11133@choi.cs.uiuc.edu> Changes in directory llvm: LICENSE.TXT updated: 1.3 -> 1.3.2.1 --- Log message: Removed pre-release license. --- Diffs of the changes: (+0 -34) Index: llvm/LICENSE.TXT diff -u llvm/LICENSE.TXT:1.3 llvm/LICENSE.TXT:1.3.2.1 --- llvm/LICENSE.TXT:1.3 Thu Oct 23 11:18:51 2003 +++ llvm/LICENSE.TXT Thu Oct 23 15:01:36 2003 @@ -1,37 +1,3 @@ -NOTICE: -======= -All distributions of LLVM prior to the 1.0 Release will be licensed to you -under the LLVM pre-release license. The 1.0 Release will be announced on the -LLVM Announcements Mailing List. - -After the 1.0 Release of LLVM, the LLVM code will be licensed to you under the -LLVM Release License (aka the Illinois Open Source License). - -The main point is that you cannot re-distribute LLVM until the 1.0 Release. - -============================================================================== -LLVM pre-release license -============================================================================== - -This is a pre-release distribution of the LLVM software and is provided for -evaluation only. This version of the LLVM software or modifications thereof -should not be distributed to third parties for any purpose. Any third parties -interested in it can request a copy directly by sending e-mail to -llvmdev at cs.uiuc.edu. As this is an evaluation release, we would appreciate any -and all feedback, ideas, and reports of bugs that you encounter. You may -discuss development of LLVM on llvmdev at cs.uiuc.edu, and bugs can be submitted -through the LLVM Bug Tracker at http://llvm.cs.uiuc.edu/bugzilla/ . We thank -you for your interest in LLVM and look forward to any comments or feedback you -may have. - -THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE -SOFTWARE. - ============================================================================== LLVM Release License ============================================================================== From criswell at cs.uiuc.edu Thu Oct 23 15:04:00 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Oct 23 15:04:00 2003 Subject: [llvm-commits] [release_1] CVS: llvm/README.txt Message-ID: <200310232003.PAA11155@choi.cs.uiuc.edu> Changes in directory llvm: README.txt updated: 1.3 -> 1.3.2.1 --- Log message: Added LLVM copyright header per Vikram's request. --- Diffs of the changes: (+9 -0) Index: llvm/README.txt diff -u llvm/README.txt:1.3 llvm/README.txt:1.3.2.1 --- llvm/README.txt:1.3 Fri Oct 17 16:10:57 2003 +++ llvm/README.txt Thu Oct 23 15:03:38 2003 @@ -1,3 +1,12 @@ +##===----------------------------------------------------------------------===## +# +# 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. +# +##===----------------------------------------------------------------------===## + Welcome to LLVM! This file provides the location of all important LLVM documentation. In From criswell at cs.uiuc.edu Thu Oct 23 15:24:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Oct 23 15:24:01 2003 Subject: [llvm-commits] [release_1] CVS: llvm/docs/AliasAnalysis.html CFEBuildInstrs.html CodingStandards.html CommandLine.html DSGraphStatus.html FAQ.html GettingStarted.html HowToSubmitABug.html LangRef.html OpenProjects.html ProgrammersManual.html Projects.html ReleaseNotes.html TestingGuide.html WritingAnLLVMPass.html ReleaseTasks.html Message-ID: <200310232023.PAA11266@choi.cs.uiuc.edu> Changes in directory llvm/docs: AliasAnalysis.html updated: 1.7 -> 1.7.2.1 CFEBuildInstrs.html updated: 1.3 -> 1.3.2.1 CodingStandards.html updated: 1.12 -> 1.12.2.1 CommandLine.html updated: 1.15 -> 1.15.2.1 DSGraphStatus.html updated: 1.15 -> 1.15.10.1 FAQ.html updated: 1.1 -> 1.1.2.1 GettingStarted.html updated: 1.41 -> 1.41.2.1 HowToSubmitABug.html updated: 1.8 -> 1.8.2.1 LangRef.html updated: 1.34 -> 1.34.2.1 OpenProjects.html updated: 1.11 -> 1.11.2.1 ProgrammersManual.html updated: 1.47 -> 1.47.2.1 Projects.html updated: 1.7 -> 1.7.2.1 ReleaseNotes.html updated: 1.11 -> 1.11.2.1 TestingGuide.html updated: 1.3 -> 1.3.2.1 WritingAnLLVMPass.html updated: 1.19 -> 1.19.2.1 ReleaseTasks.html (r1.12) removed --- Log message: Removing Release Tasks. This belongs in the web site repository. Added a link to the LLVM home page at the end of each page. --- Diffs of the changes: (+41 -9) Index: llvm/docs/AliasAnalysis.html diff -u llvm/docs/AliasAnalysis.html:1.7 llvm/docs/AliasAnalysis.html:1.7.2.1 --- llvm/docs/AliasAnalysis.html:1.7 Wed Oct 22 21:29:42 2003 +++ llvm/docs/AliasAnalysis.html Thu Oct 23 15:23:00 2003 @@ -494,10 +494,12 @@ -
      +
      +
      Chris Lattner
      -Last modified: $Date: 2003/10/23 02:29:42 $ +The LLVM Compiler Infrastructure +
      +Last modified: $Date: 2003/10/23 20:23:00 $
      - Index: llvm/docs/CFEBuildInstrs.html diff -u llvm/docs/CFEBuildInstrs.html:1.3 llvm/docs/CFEBuildInstrs.html:1.3.2.1 --- llvm/docs/CFEBuildInstrs.html:1.3 Wed Oct 22 22:55:23 2003 +++ llvm/docs/CFEBuildInstrs.html Thu Oct 23 15:23:00 2003 @@ -149,7 +149,9 @@
      Brian Gaeke
      -Last modified: $Date: 2003/10/23 03:55:23 $ +The LLVM Compiler Infrastructure +
      +Last modified: $Date: 2003/10/23 20:23:00 $
      Index: llvm/docs/CodingStandards.html diff -u llvm/docs/CodingStandards.html:1.12 llvm/docs/CodingStandards.html:1.12.2.1 --- llvm/docs/CodingStandards.html:1.12 Mon Oct 13 09:58:11 2003 +++ llvm/docs/CodingStandards.html Thu Oct 23 15:23:00 2003 @@ -831,6 +831,8 @@
      Chris Lattner
      +The LLVM Compiler Infrastructure +
      Last modified: Sun Oct 12 22:12:43 CDT 2003 Index: llvm/docs/CommandLine.html diff -u llvm/docs/CommandLine.html:1.15 llvm/docs/CommandLine.html:1.15.2.1 --- llvm/docs/CommandLine.html:1.15 Thu Aug 21 17:14:26 2003 +++ llvm/docs/CommandLine.html Thu Oct 23 15:23:00 2003 @@ -1530,6 +1530,8 @@
      Chris Lattner
      +The LLVM Compiler Infrastructure +
      Last modified: Fri Aug 1 16:30:11 CDT 2003 Index: llvm/docs/DSGraphStatus.html diff -u llvm/docs/DSGraphStatus.html:1.15 llvm/docs/DSGraphStatus.html:1.15.10.1 --- llvm/docs/DSGraphStatus.html:1.15 Tue May 20 16:01:22 2003 +++ llvm/docs/DSGraphStatus.html Thu Oct 23 15:23:00 2003 @@ -875,6 +875,8 @@
      Chris Lattner
      + The LLVM Compiler Infrastructure +
      Last modified: Thu Nov 14 20:00:50 CST 2002 Index: llvm/docs/FAQ.html diff -u llvm/docs/FAQ.html:1.1 llvm/docs/FAQ.html:1.1.2.1 --- llvm/docs/FAQ.html:1.1 Mon Oct 13 11:13:06 2003 +++ llvm/docs/FAQ.html Thu Oct 23 15:23:00 2003 @@ -141,5 +141,8 @@

  • +The LLVM Compiler Infrastructure +
    + Index: llvm/docs/GettingStarted.html diff -u llvm/docs/GettingStarted.html:1.41 llvm/docs/GettingStarted.html:1.41.2.1 --- llvm/docs/GettingStarted.html:1.41 Tue Oct 21 16:24:38 2003 +++ llvm/docs/GettingStarted.html Thu Oct 23 15:23:00 2003 @@ -1010,10 +1010,12 @@ If you have any questions or run into any snags (or you have any additions...), please send an email to Chris Lattner.

    + The LLVM Compiler Infrastructure +
    - - -Last modified: Mon Aug 11 13:52:22 CDT 2003 - + + + Last modified: Mon Aug 11 13:52:22 CDT 2003 + Index: llvm/docs/HowToSubmitABug.html diff -u llvm/docs/HowToSubmitABug.html:1.8 llvm/docs/HowToSubmitABug.html:1.8.2.1 --- llvm/docs/HowToSubmitABug.html:1.8 Wed Oct 22 12:01:44 2003 +++ llvm/docs/HowToSubmitABug.html Thu Oct 23 15:23:00 2003 @@ -273,6 +273,8 @@
    Chris Lattner
    +The LLVM Compiler Infrastructure +
    Last modified: Tue Oct 14 15:57:47 CDT 2003 Index: llvm/docs/LangRef.html diff -u llvm/docs/LangRef.html:1.34 llvm/docs/LangRef.html:1.34.2.1 --- llvm/docs/LangRef.html:1.34 Tue Oct 21 10:43:55 2003 +++ llvm/docs/LangRef.html Thu Oct 23 15:23:01 2003 @@ -1947,6 +1947,8 @@
    Chris Lattner
    +The LLVM Compiler Infrastructure +
    Last modified: Tue Oct 21 10:43:36 CDT 2003 Index: llvm/docs/OpenProjects.html diff -u llvm/docs/OpenProjects.html:1.11 llvm/docs/OpenProjects.html:1.11.2.1 --- llvm/docs/OpenProjects.html:1.11 Wed Oct 1 16:49:55 2003 +++ llvm/docs/OpenProjects.html Thu Oct 23 15:23:01 2003 @@ -275,6 +275,8 @@
    Chris Lattner
    +The LLVM Compiler Infrastructure +
    Last modified: Wed Oct 1 16:48:54 CDT 2003 Index: llvm/docs/ProgrammersManual.html diff -u llvm/docs/ProgrammersManual.html:1.47 llvm/docs/ProgrammersManual.html:1.47.2.1 --- llvm/docs/ProgrammersManual.html:1.47 Sat Sep 20 09:43:16 2003 +++ llvm/docs/ProgrammersManual.html Thu Oct 23 15:23:01 2003 @@ -1787,6 +1787,8 @@
    By: Dinakar Dhurjati and Chris Lattner
    +The LLVM Compiler Infrastructure +
    Last modified: Sat Sep 20 09:25:11 CDT 2003 Index: llvm/docs/Projects.html diff -u llvm/docs/Projects.html:1.7 llvm/docs/Projects.html:1.7.2.1 --- llvm/docs/Projects.html:1.7 Tue Oct 21 14:35:06 2003 +++ llvm/docs/Projects.html Thu Oct 23 15:23:01 2003 @@ -383,5 +383,8 @@
    Written by John Criswell. +
    +The LLVM Compiler Infrastructure +
    Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.11 llvm/docs/ReleaseNotes.html:1.11.2.1 --- llvm/docs/ReleaseNotes.html:1.11 Wed Oct 22 13:19:08 2003 +++ llvm/docs/ReleaseNotes.html Thu Oct 23 15:23:01 2003 @@ -389,6 +389,8 @@
    Maintained By: The LLVM Team
    +The LLVM Compiler Infrastructure +
    Last modified: Mon Oct 20 14:04:51 CDT 2003 Index: llvm/docs/TestingGuide.html diff -u llvm/docs/TestingGuide.html:1.3 llvm/docs/TestingGuide.html:1.3.2.1 --- llvm/docs/TestingGuide.html:1.3 Thu Oct 23 13:10:28 2003 +++ llvm/docs/TestingGuide.html Thu Oct 23 15:23:01 2003 @@ -420,7 +420,9 @@
    John T. Criswell
    -Last modified: $Date: 2003/10/23 18:10:28 $ +The LLVM Compiler Infrastructure +
    +Last modified: $Date: 2003/10/23 20:23:01 $
    Index: llvm/docs/WritingAnLLVMPass.html diff -u llvm/docs/WritingAnLLVMPass.html:1.19 llvm/docs/WritingAnLLVMPass.html:1.19.2.1 --- llvm/docs/WritingAnLLVMPass.html:1.19 Wed Sep 10 00:29:43 2003 +++ llvm/docs/WritingAnLLVMPass.html Thu Oct 23 15:23:01 2003 @@ -1274,6 +1274,8 @@
    Chris Lattner
    +The LLVM Compiler Infrastructure +
    Last modified: Tue Jul 22 15:52:30 CDT 2003 From criswell at cs.uiuc.edu Thu Oct 23 15:28:02 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Oct 23 15:28:02 2003 Subject: [llvm-commits] CVS: llvm-www/releases/1.0/llvm.tar.gz Message-ID: <200310232027.PAA11344@choi.cs.uiuc.edu> Changes in directory llvm-www/releases/1.0: llvm.tar.gz updated: 1.1 -> 1.2 --- Log message: LLVM Release 1.0, Candidate 2 The license is a pure 1.0 license now, and the docs have been updated with little links to the LLVM web site. --- Diffs of the changes: (+0 -0) Index: llvm-www/releases/1.0/llvm.tar.gz From gaeke at cs.uiuc.edu Thu Oct 23 15:33:01 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu Oct 23 15:33:01 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAlloc/AllocInfo.h Message-ID: <200310232032.PAA02812@trinity.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/RegAlloc: AllocInfo.h added (r1.1) --- Log message: New file, containing AllocInfo structure. --- Diffs of the changes: (+61 -0) Index: llvm/lib/CodeGen/RegAlloc/AllocInfo.h diff -c /dev/null llvm/lib/CodeGen/RegAlloc/AllocInfo.h:1.1 *** /dev/null Thu Oct 23 15:32:32 2003 --- llvm/lib/CodeGen/RegAlloc/AllocInfo.h Thu Oct 23 15:31:51 2003 *************** *** 0 **** --- 1,61 ---- + //===-- AllocInfo.h - Store info about regalloc decisions -------*- C++ -*-===// + // + // 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 header file contains the data structure used to save the state + // of the global, graph-coloring register allocator. + // + //===----------------------------------------------------------------------===// + + #ifndef ALLOCINFO_H + #define ALLOCINFO_H + + #include "llvm/Type.h" + #include "llvm/DerivedTypes.h" + #include "llvm/Constants.h" + + /// AllocInfo - Structure representing one instruction's operand's-worth of + /// register allocation state. We create tables made out of these data + /// structures to generate mapping information for this register allocator. + /// + struct AllocInfo { + unsigned Instruction; + unsigned Operand; + unsigned AllocState; + int Placement; + AllocInfo (unsigned Instruction_, unsigned Operand_, + unsigned AllocState_, int Placement_) : + Instruction (Instruction_), Operand (Operand_), + AllocState (AllocState_), Placement (Placement_) { } + + /// getConstantType - Return a StructType representing an AllocInfo object. + /// + static StructType *getConstantType () { + std::vector TV; + TV.push_back (Type::UIntTy); + TV.push_back (Type::UIntTy); + TV.push_back (Type::UIntTy); + TV.push_back (Type::IntTy); + return StructType::get (TV); + } + + /// toConstant - Convert this AllocInfo into an LLVM Constant of type + /// getConstantType(), and return the Constant. + /// + Constant *toConstant () const { + StructType *ST = getConstantType (); + std::vector CV; + CV.push_back (ConstantUInt::get (Type::UIntTy, Instruction)); + CV.push_back (ConstantUInt::get (Type::UIntTy, Operand)); + CV.push_back (ConstantUInt::get (Type::UIntTy, AllocState)); + CV.push_back (ConstantSInt::get (Type::IntTy, Placement)); + return ConstantStruct::get (ST, CV); + } + }; + + #endif // ALLOCINFO_H From gaeke at cs.uiuc.edu Thu Oct 23 15:33:15 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu Oct 23 15:33:15 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.h Message-ID: <200310232032.PAA02805@trinity.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/RegAlloc: PhyRegAlloc.h updated: 1.58 -> 1.59 --- Log message: Make FnAllocState contain vectors of AllocInfo, instead of LLVM Constants. --- Diffs of the changes: (+1 -1) Index: llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.h diff -u llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.h:1.58 llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.h:1.59 --- llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.h:1.58 Thu Oct 23 13:06:27 2003 +++ llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.h Thu Oct 23 15:32:02 2003 @@ -85,7 +85,7 @@ AddedInstrns AddedInstrAtEntry; // to store instrns added at entry const LoopInfo *LoopDepthCalc; // to calculate loop depths - std::map > FnAllocState; + std::map > FnAllocState; PhyRegAlloc(const PhyRegAlloc&); // DO NOT IMPLEMENT void operator=(const PhyRegAlloc&); // DO NOT IMPLEMENT From gaeke at cs.uiuc.edu Thu Oct 23 15:34:02 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu Oct 23 15:34:02 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp Message-ID: <200310232033.PAA02841@trinity.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/RegAlloc: PhyRegAlloc.cpp updated: 1.122 -> 1.123 --- Log message: Move AllocInfo structure to a private AllocInfo.h header file. Make FnAllocState contain vectors of AllocInfo, instead of LLVM Constants. Give doFinalization a method comment, and let it do the work of converting AllocInfos to LLVM Constants. --- Diffs of the changes: (+15 -48) Index: llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp diff -u llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.122 llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.123 --- llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.122 Thu Oct 23 13:06:27 2003 +++ llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp Thu Oct 23 15:32:55 2003 @@ -20,6 +20,7 @@ // //===----------------------------------------------------------------------===// +#include "AllocInfo.h" #include "IGNode.h" #include "PhyRegAlloc.h" #include "RegAllocCommon.h" @@ -1129,54 +1130,12 @@ } -namespace { - /// AllocInfo - Structure representing one instruction's - /// operand's-worth of register allocation state. We create tables - /// made out of these data structures to generate mapping information - /// for this register allocator. (FIXME: This might move to a header - /// file at some point.) - /// - struct AllocInfo { - unsigned Instruction; - unsigned Operand; - unsigned AllocState; - int Placement; - AllocInfo (unsigned Instruction_, unsigned Operand_, - unsigned AllocState_, int Placement_) : - Instruction (Instruction_), Operand (Operand_), - AllocState (AllocState_), Placement (Placement_) { } - /// getConstantType - Return a StructType representing an AllocInfo - /// object. - /// - static StructType *getConstantType () { - std::vector TV; - TV.push_back (Type::UIntTy); - TV.push_back (Type::UIntTy); - TV.push_back (Type::UIntTy); - TV.push_back (Type::IntTy); - return StructType::get (TV); - } - /// toConstant - Convert this AllocInfo into an LLVM Constant of type - /// getConstantType(), and return the Constant. - /// - Constant *toConstant () const { - StructType *ST = getConstantType (); - std::vector CV; - CV.push_back (ConstantUInt::get (Type::UIntTy, Instruction)); - CV.push_back (ConstantUInt::get (Type::UIntTy, Operand)); - CV.push_back (ConstantUInt::get (Type::UIntTy, AllocState)); - CV.push_back (ConstantSInt::get (Type::IntTy, Placement)); - return ConstantStruct::get (ST, CV); - } - }; -} - /// Save the global register allocation decisions made by the register /// allocator so that they can be accessed later (sort of like "poor man's /// debug info"). /// void PhyRegAlloc::saveState () { - std::vector &state = FnAllocState[Fn]; + std::vector &state = FnAllocState[Fn]; unsigned Insn = 0; LiveRangeMapType::const_iterator HMIEnd = LRI->getLiveRangeMap ()->end (); for (const_inst_iterator II=inst_begin (Fn), IE=inst_end (Fn); II != IE; ++II) @@ -1204,11 +1163,11 @@ Placement = L->getSpillOffFromFP (); } } - state.push_back (AllocInfo (Insn, i, AllocState, - Placement).toConstant ()); + state.push_back (AllocInfo (Insn, i, AllocState, Placement)); } } + /// Check the saved state filled in by saveState(), and abort if it looks /// wrong. Only used when debugging. /// @@ -1216,6 +1175,11 @@ /// not yet implemented } +/// Finish the job of saveState(), by collapsing FnAllocState into an LLVM +/// Constant and stuffing it inside the Module. (NOTE: Soon, there will be +/// other, better ways of storing the saved state; this one is cumbersome and +/// will never work with the JIT.) +/// bool PhyRegAlloc::doFinalization (Module &M) { if (!SaveRegAllocState) return false; // Nothing to do here, unless we're saving state. @@ -1234,11 +1198,14 @@ if (FnAllocState.find (F) == FnAllocState.end ()) { allstate.push_back (ConstantPointerNull::get (PT)); } else { - std::vector &state = FnAllocState[F]; + std::vector &state = FnAllocState[F]; // Convert state into an LLVM ConstantArray, and put it in a // ConstantStruct (named S) along with its size. - unsigned Size = state.size (); + std::vector stateConstants; + for (unsigned i = 0, s = state.size (); i != s; ++i) + stateConstants.push_back (state[i].toConstant ()); + unsigned Size = stateConstants.size (); ArrayType *AT = ArrayType::get (AllocInfo::getConstantType (), Size); std::vector TV; TV.push_back (Type::UIntTy); @@ -1246,7 +1213,7 @@ StructType *ST = StructType::get (TV); std::vector CV; CV.push_back (ConstantUInt::get (Type::UIntTy, Size)); - CV.push_back (ConstantArray::get (AT, state)); + CV.push_back (ConstantArray::get (AT, stateConstants)); Constant *S = ConstantStruct::get (ST, CV); GlobalVariable *GV = From gaeke at cs.uiuc.edu Thu Oct 23 15:40:01 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu Oct 23 15:40:01 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAlloc/AllocInfo.h Message-ID: <200310232039.PAA03038@trinity.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/RegAlloc: AllocInfo.h updated: 1.1 -> 1.2 --- Log message: Move the implementations of ==, != on AllocInfos here, from UnpackTraceFunction. --- Diffs of the changes: (+9 -0) Index: llvm/lib/CodeGen/RegAlloc/AllocInfo.h diff -u llvm/lib/CodeGen/RegAlloc/AllocInfo.h:1.1 llvm/lib/CodeGen/RegAlloc/AllocInfo.h:1.2 --- llvm/lib/CodeGen/RegAlloc/AllocInfo.h:1.1 Thu Oct 23 15:31:51 2003 +++ llvm/lib/CodeGen/RegAlloc/AllocInfo.h Thu Oct 23 15:39:18 2003 @@ -56,6 +56,15 @@ CV.push_back (ConstantSInt::get (Type::IntTy, Placement)); return ConstantStruct::get (ST, CV); } + + /// AllocInfos compare equal if the allocation placements are equal + /// (i.e., they can be equal even if they refer to operands from two + /// different instructions.) + /// + bool operator== (const AllocInfo &X) const { + return (X.AllocState == AllocState) && (X.Placement == Placement); + } + bool operator!= (const AllocInfo &X) const { return !(*this == X); } }; #endif // ALLOCINFO_H From criswell at cs.uiuc.edu Thu Oct 23 16:15:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Oct 23 16:15:01 2003 Subject: [llvm-commits] CVS: llvm-www/releases/1.0/cfrontend.sparc.tar.gz Message-ID: <200310232114.QAA11484@choi.cs.uiuc.edu> Changes in directory llvm-www/releases/1.0: cfrontend.sparc.tar.gz updated: 1.1 -> 1.2 --- Log message: GCC front end for Sparc, Candidate 2. Moved a script so that it can fix prototypes correctly. --- Diffs of the changes: (+0 -0) Index: llvm-www/releases/1.0/cfrontend.sparc.tar.gz From criswell at cs.uiuc.edu Thu Oct 23 16:23:04 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Oct 23 16:23:04 2003 Subject: [llvm-commits] [release_1] CVS: llvm/docs/GettingStarted.html Message-ID: <200310232122.QAA11552@choi.cs.uiuc.edu> Changes in directory llvm/docs: GettingStarted.html updated: 1.41.2.1 -> 1.41.2.2 --- Log message: Added information about fixing the headers on Solaris. --- Diffs of the changes: (+18 -1) Index: llvm/docs/GettingStarted.html diff -u llvm/docs/GettingStarted.html:1.41.2.1 llvm/docs/GettingStarted.html:1.41.2.2 --- llvm/docs/GettingStarted.html:1.41.2.1 Thu Oct 23 15:23:00 2003 +++ llvm/docs/GettingStarted.html Thu Oct 23 16:22:19 2003 @@ -90,6 +90,11 @@
  • cd where-you-want-the-C-front-end-to-live
  • gunzip --stdout cfrontend.platform.tar.gz | tar -xvf - +
  • Sparc Only:
    + + cd cfrontend/sparc
    + ./fixheaders +

    @@ -377,7 +382,8 @@

    Before configuring and compiling the LLVM suite, you need to extract the - LLVM GCC front end from the binary distribution. It is used for building the + LLVM GCC front end from the binary distribution. It is used for building + the bytecode libraries later used by the GCC front end for linking programs, and its location must be specified when the LLVM suite is configured.

    @@ -389,6 +395,17 @@
  • gunzip --stdout cfrontend.platform.tar.gz | tar -xvf - + + If you are on a Sparc/Solaris machine, you will need to fix the header + files: + +

    + + + cd cfrontend/sparc +
    + ./fixheaders +

    Local LLVM Configuration

    From criswell at cs.uiuc.edu Thu Oct 23 17:16:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Oct 23 17:16:01 2003 Subject: [llvm-commits] [release_1] CVS: llvm/docs/CFEBuildInstrs.html GettingStarted.html Message-ID: <200310232215.RAA11792@choi.cs.uiuc.edu> Changes in directory llvm/docs: CFEBuildInstrs.html updated: 1.3.2.1 -> 1.3.2.2 GettingStarted.html updated: 1.41.2.2 -> 1.41.2.3 --- Log message: Added information on why someone would want to build the GCC front end. Added a link to this information from the Getting Started Guide. Changed the word "wicked" to "elite." The original sounds much cooler, but I fear the PR police when I take off my tinfoil hat. --- Diffs of the changes: (+19 -4) Index: llvm/docs/CFEBuildInstrs.html diff -u llvm/docs/CFEBuildInstrs.html:1.3.2.1 llvm/docs/CFEBuildInstrs.html:1.3.2.2 --- llvm/docs/CFEBuildInstrs.html:1.3.2.1 Thu Oct 23 15:23:00 2003 +++ llvm/docs/CFEBuildInstrs.html Thu Oct 23 17:15:14 2003 @@ -15,9 +15,12 @@ C/C++ front-end, based on GCC 3.4, from source.

    NOTE: This is currently a somewhat fragile, error-prone -process, and you should only try to do it if (A) you really, really, -really can't use the binaries we distribute, and (B) you are a wicked -good GCC hacker.

    +process, and you should only try to do it if +
      +
    • (A) you really, really, really can't use the binaries we distribute +
    • (B) you need GCC to fix some of the header files on your system +
    • (C) you are an elite GCC hacker.

      +

    We welcome patches to help make this process simpler.

    @@ -151,7 +154,7 @@
    Brian Gaeke
    The LLVM Compiler Infrastructure
    -Last modified: $Date: 2003/10/23 20:23:00 $ +Last modified: $Date: 2003/10/23 22:15:14 $
    Index: llvm/docs/GettingStarted.html diff -u llvm/docs/GettingStarted.html:1.41.2.2 llvm/docs/GettingStarted.html:1.41.2.3 --- llvm/docs/GettingStarted.html:1.41.2.2 Thu Oct 23 16:22:19 2003 +++ llvm/docs/GettingStarted.html Thu Oct 23 17:15:14 2003 @@ -407,6 +407,18 @@ ./fixheaders
    +

    + The binary versions of the GCC front end may not suit all of your needs. + For example, the binary distribution may include an old version of a system + header file, not "fix" a header file that needs to be fixed for GCC, or it + may be linked with libraries not available on your system. +

    + +

    + In cases like these, you may want to try + building the GCC front end from source. + This is not for the faint of heart, so be forewarned. +

    Local LLVM Configuration

    From gaeke at cs.uiuc.edu Thu Oct 23 18:27:01 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu Oct 23 18:27:01 2003 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp Message-ID: <200310232326.SAA21747@zion.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: UnpackTraceFunction.cpp updated: 1.3 -> 1.4 --- Log message: Share struct AllocInfo with the SPARC register allocator. Rename insertCopy to insertCopyMachineInstrs, and update its comment. Add stub for a new function called insertBranchMachineInstrs. Add pseudocode for getRegisterAllocatedForValue. Change the type of containsReturnInstruction, and update its comment. Update insertLiveVariableCopies() to reflect the above. --- Diffs of the changes: (+38 -25) Index: reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp diff -u reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp:1.3 reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp:1.4 --- reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp:1.3 Sat Oct 18 01:30:37 2003 +++ reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp Thu Oct 23 18:26:20 2003 @@ -6,6 +6,7 @@ // //===-----------------------------------------------------------------------===// +#include "../../../../lib/CodeGen/RegAlloc/AllocInfo.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstr.h" @@ -15,18 +16,20 @@ // FIXME: following decl should be shared with TraceToFunction.cpp in a header typedef std::set LiveVariableSet; -struct AllocInfo { - // FIXME: this should be the same as what you see in PhyRegAlloc.cpp - // but with equality/inequality operators defined appropriately. - bool operator== (const AllocInfo &X) const { return false; /* FIXME */ } - bool operator!= (const AllocInfo &X) const { return !(*this == X); } -}; - -/// Insert a machine instruction for the current architecture, that +/// Insert (a) machine instruction(s) for the current architecture, that /// copies the value in Source to the location specified by Target, at /// the beginning of B. /// -void insertCopy (AllocInfo &Source, AllocInfo &Target, MachineBasicBlock &B) { +void insertCopyMachineInstrs (AllocInfo &Source, AllocInfo &Target, + MachineBasicBlock &B) { + // FIXME: not yet implemented +} + +/// Emit the same sequence of MachineInstrs that +/// replaceMachineCodeForFunction() would emit, to branch from the end +/// of B to TargetAddr. +/// +void insertBranchMachineInstrs (void *TargetAddr, MachineBasicBlock &B) { // FIXME: not yet implemented } @@ -35,15 +38,29 @@ /// AllocInfo getRegisterAllocatedForValue (Function *F, Value *V) { AllocInfo AI; - // FIXME: not yet implemented +#ifdef PSEUDOCODE + assert (F has been code-generated); + if (F was compiled by llc) { + get the saved PhyRegAlloc state for F out of the Module of F; + } else { + PhyRegAlloc must have put the saved state for F somewhere where we can + get at it here; + } + get the AllocInfo for V from the saved PhyRegAlloc state for F; +#endif return AI; } /// Returns a pointer to the return instruction in B, if B contains one, -/// or null otherwise. +/// or null otherwise. FIXME: SPARC target-specific. /// -MachineInstr *containsReturnInstruction (MachineBasicBlock &B) { - // FIXME: not yet implemented +const MachineInstr *containsReturnInstruction (MachineBasicBlock &B) { + for (MachineBasicBlock::const_reverse_iterator i = B.rbegin (), + e = B.rend (); i != e; ++i) { + const MachineInstr *MI = *i; + if (MI->getOpcode () == /* SparcV9::JMPLRETi */) + return MI; + } return 0; } @@ -71,7 +88,12 @@ // Modify EXIT MachineBasicBlocks of MF for (MachineFunction::iterator I = MF.begin (), E = MF.end (); I != E; ++I) { MachineBasicBlock &B = *I; - if (MachineInstr *RI = containsReturnInstruction (B)) { + if (const MachineInstr *RI = containsReturnInstruction (B)) { + void *ReturnAddress; +#ifdef PSEUDOCODE + Let ReturnAddress be the address in memory of the compiled code + for the MachineBasicBlock in MatrixF that RI would have returned to; +#endif // Erase the contents of B while (!B.empty ()) { MachineBasicBlock::iterator MBBI = B.begin (); @@ -85,18 +107,9 @@ AllocInfo Source = getRegisterAllocatedForValue (TraceF, V); AllocInfo Target = getRegisterAllocatedForValue (MatrixF, V); if (Source != Target) - insertCopy (Source, Target, B); - } -#ifdef PSEUDOCODE - Let RBB be the address in memory of the MachineBasicBlock in MatrixF - that RI would have returned to; - if (RBB is within the range of a Branch Always) { - Create a new "Branch Always" MachineInstr MI, which branches to RBB; - Insert MI at the end of the MachineBasicBlock B; - } else { - Use nifty "insert far call" code in SparcV9CodeEmitter; + insertCopyMachineInstrs (Source, Target, B); } -#endif + insertBranchMachineInstrs (ReturnAddress, B); } } } From criswell at cs.uiuc.edu Thu Oct 23 19:50:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Oct 23 19:50:01 2003 Subject: [llvm-commits] [release_1] CVS: llvm/test/Regression/BugPoint/misopt-basictest.ll Message-ID: <200310240049.TAA12082@choi.cs.uiuc.edu> Changes in directory llvm/test/Regression/BugPoint: misopt-basictest.ll updated: 1.2 -> 1.2.4.1 --- Log message: Fixed the syntax for Solaris /bin/sh. In pre-historic times, you couldn't assign and export a variable at the same time in /bin/sh. Solaris still can't. --- Diffs of the changes: (+2 -1) Index: llvm/test/Regression/BugPoint/misopt-basictest.ll diff -u llvm/test/Regression/BugPoint/misopt-basictest.ll:1.2 llvm/test/Regression/BugPoint/misopt-basictest.ll:1.2.4.1 --- llvm/test/Regression/BugPoint/misopt-basictest.ll:1.2 Fri Aug 1 18:29:59 2003 +++ llvm/test/Regression/BugPoint/misopt-basictest.ll Thu Oct 23 19:49:47 2003 @@ -1,4 +1,5 @@ -; RUN: export PATH=/usr/bin:/bin/:${PATH} +; RUN: PATH=/usr/bin:/bin/:${PATH} +; RUN: export PATH ; RUN: bugpoint %s -dce -bugpoint-deletecalls -simplifycfg %.LC0 = internal global [13 x sbyte] c"Hello World\0A\00" From criswell at cs.uiuc.edu Thu Oct 23 19:55:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Oct 23 19:55:01 2003 Subject: [llvm-commits] [release_1] CVS: llvm/README.txt Message-ID: <200310240054.TAA12117@choi.cs.uiuc.edu> Changes in directory llvm: README.txt updated: 1.3.2.1 -> 1.3.2.2 --- Log message: Updated the design guide to be a newer paper on LLVM. --- Diffs of the changes: (+3 -2) Index: llvm/README.txt diff -u llvm/README.txt:1.3.2.1 llvm/README.txt:1.3.2.2 --- llvm/README.txt:1.3.2.1 Thu Oct 23 15:03:38 2003 +++ llvm/README.txt Thu Oct 23 19:54:03 2003 @@ -34,8 +34,9 @@ LLVM Design: - The LLVM Instruction Set and Compilation Strategy: - http://llvm.cs.uiuc.edu/pubs/2002-08-09-LLVMCompilationStrategy.html + LLVM: A Compilation Framework for Lifelong Program Analysis & + Transformation + http://llvm.cs.uiuc.edu/pubs/2003-09-30-LifelongOptimizationTR.html LLVM User Guides: From criswell at cs.uiuc.edu Thu Oct 23 20:18:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Oct 23 20:18:01 2003 Subject: [llvm-commits] [release_1] CVS: llvm/test/QMTest/expectations.qmr Message-ID: <200310240117.UAA12179@choi.cs.uiuc.edu> Changes in directory llvm/test/QMTest: expectations.qmr updated: 1.4 -> 1.4.2.1 --- Log message: Updated for newly passing tests. This must've gotten lost when creating the release_1 branch. --- Diffs of the changes: (+1 -1) Index: llvm/test/QMTest/expectations.qmr diff -u llvm/test/QMTest/expectations.qmr:1.4 llvm/test/QMTest/expectations.qmr:1.4.2.1 --- llvm/test/QMTest/expectations.qmr:1.4 Thu Oct 23 10:53:48 2003 +++ llvm/test/QMTest/expectations.qmr Thu Oct 23 20:17:41 2003 @@ -3,13 +3,13 @@ qoq}q(U _Result__kindqUtestqU_Result__outcomeqUPASSqU_Result__annotationsq}U _Result__idq U0Regression.Assembler.2002-08-16-ConstExprInlinedq U_Result__contextq (cqm.test.context Context -q o}q (U_Context__propertiesq}U_Context__temporariesq}ubub.(hoq}q(hhhhh}h U(Regression.Transforms.PruneEH.simpletestqh (h o}q(h}h}ubub.(hoq}q(hhhhh}h U/Regression.CBackend.2002-08-19-HardConstantExprqh (h o}q(h}h}ubub.(hoq}q(hhhhh}h URegression.Jello.test-shiftqh (h o}q(h}h}ubub.(hoq}q(hhhUFAILqh}h U.Regression.Transforms.CorrelatedExprs.looptestqh (h o}q (h}h}ubub.(hoq!}q"(hhhhh}h U-Regression.Linker.2003-08-23-GlobalVarLinkingq#h (h o}q$(h}h}ubub.(hoq%}q&(hhhhh}h U?Regression.Transforms.Inline.2003-09-22-PHINodesInExceptionDestq'h (h o}q((h}h}ubub.(hoq)}q*(hhhhh}h U,Regression.CFrontend.2003-02-12-NonlocalGotoq+h (h o}q,(h}h}ubub.(hoq-}q.(hhhhh}h U2Regression.Transforms.FunctionResolve.retmismatch1q/h (h o}q0(h}h}ubub.(hoq1}q2(hhhhh}h U8Regression.Transforms.ADCE.2003-01-22-PredecessorProblemq3h (h o}q4(h}h}ubub.(hoq5}q6(hhhhh}h U=Regression.Transforms.LevelRaise.2002-10-08-! VarArgCallInfLoopq7h (h o}q8(h}h}ubub.(hoq9}q:(hhhhh}h U5Regression.CFrontend.2003-07-22-ArrayAccessTypeSafetyq;h (h o}q<(h}h}ubub.(hoq=}q>(hhhhh}h U8Regression.C++Frontend.2003-09-29-ArgumentNumberMismatchq?h (h o}q@(h}h}ubub.(hoqA}qB(hhhhh}h U+Regression.CFrontend.2002-09-19-StarInLabelqCh (h o}qD(h}h}ubub.(hoqE}qF(hhhhh}h U.Regression.CFrontend.2003-08-23-LocalUnionTestqGh (h o}qH(h}h}ubub.(hoqI}qJ(hhhhh}h U-Regression.C++Frontend.2003-08-28-SaveExprBugqKh (h o}qL(h}h}ubub.(hoqM}qN(hhhhh}h U"Regression.Jello.2003-06-05-PHIBugqOh (h o}qP(h}h}ubub.(hoqQ}qR(hhhhh}h U/Regression.Linker.2003-04-26-NullPtrLinkProblemqSh (h o}qT(h}h}ubub.(hoqU}qV(hhhhh}h U)Regression.Transforms.Reassociate.subtestqWh (h o}qX(h}h}ubub.(hoqY}qZ(hhhhh}h U)Regression.Linker.2002-08-20-ConstantExprq[h (h o}q\(h}h}ubub.(hoq]}q^(hhhhh}h U=Regression.Transforms.Reassociate.2002-05-15-AgressiveSubMoveq_h (h o}q`(h}h}ubub.(! hoqa}qb(hhhhh}h UARegression.Transforms.CorrelatedExprs.2002-10- 07-DominatorProblemqch (h o}qd(h}h}ubub.(hoqe}qf(hhhhh}h U3Regression.Transforms.PiNodeInserter.substitutetestqgh (h o}qh(h}h}ubub.(hoqi}qj(hhhhh}h U4Regression.Transforms.SCCP.2003-08-26-InvokeHandlingqkh (h o}ql(h}h}ubub.(hoqm}qn(hhhhh}h U$Regression.Jello.2003-01-04-LoopTestqoh (h o}qp(h}h}ubub.(hoqq}qr(hhhhh}h U1Regression.Assembler.2002-04-04-PureVirtMethCall2qsh (h o}qt(h}h}ubub.(hoqu}qv(hhhhh}h U)Regression.CFrontend.2002-07-14-MiscTestsqwh (h o}qx(h}h}ubub.(hoqy}qz(hhhhh}h U(hhhhh}h U Regression.Reoptimizer.ticm.ticmq?h (h o}q@(h}h}ubub.(hoqA}qB(hhhhh}h U8Regression.C++Frontend.2003-09-29-ArgumentNumberMismatchqCh (h o}qD(h}h}ubub.(hoqE}qF(hhhhh}h U+Regression.CFrontend.2002-09-19-StarInLabelqGh (h o}qH(h}h}ubub.(hoqI}qJ(hhhhh}h U.Regression.CFrontend.2003-08-23-LocalUnionTestqKh (h o}qL(h}h}ubub.(hoqM}qN(hhhhh}h U/Regression.Linker.2003-04-26-NullPtrLinkProblemqOh (h o}qP(h}h}ubub.(hoqQ}qR(hhhhh}h U)Regression.Transforms.Reassociate.subtestqSh (h o}qT(h}h}ubub.(hoqU}qV(hhhhh}h U)Regression.Linker.2002-08-20-ConstantExprqWh (h o}qX(h}h}ubub.(hoqY}qZ(hhhhh}h U=Regression.Transforms.Reassociate.2002-05-15-AgressiveSubMoveq[h (h o}q\(h}h}ubub.(hoq]}q^(hhhhh}h UARegression.Transforms.CorrelatedExprs.2002-10-07-DominatorProblemq_! h (h o}q`(h}h}ubub.(hoqa}qb(hhhhh}h U3Regression.Transforms.Pi NodeInserter.substitutetestqch (h o}qd(h}h}ubub.(hoqe}qf(hhhhh}h U4Regression.Transforms.SCCP.2003-08-26-InvokeHandlingqgh (h o}qh(h}h}ubub.(hoqi}qj(hhhhh}h U-Regression.CFrontend.2002-02-18-64bitConstantqkh (h o}ql(h}h}ubub.(hoqm}qn(hhhhh}h U1Regression.Assembler.2002-04-04-PureVirtMethCall2qoh (h o}qp(h}h}ubub.(hoqq}qr(hhhhh}h U(Regression.Reoptimizer.BinInterface.testqsh (h o}qt(h}h}ubub.(hoqu}qv(hhhhh}h U Changes in directory llvm-www/releases: download.html updated: 1.2 -> 1.3 --- Log message: Clarified the name of components. Added the source for the GCC front end. --- Diffs of the changes: (+11 -3) Index: llvm-www/releases/download.html diff -u llvm-www/releases/download.html:1.2 llvm-www/releases/download.html:1.3 --- llvm-www/releases/download.html:1.2 Thu Oct 23 14:43:52 2003 +++ llvm-www/releases/download.html Thu Oct 23 21:05:34 2003 @@ -30,9 +30,17 @@

    From criswell at cs.uiuc.edu Thu Oct 23 21:06:16 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Oct 23 21:06:16 2003 Subject: [llvm-commits] CVS: llvm-www/releases/1.0/cfrontend-src.tar.gz Message-ID: <200310240205.VAA12402@choi.cs.uiuc.edu> Changes in directory llvm-www/releases/1.0: cfrontend-src.tar.gz added (r1.1) --- Log message: Source code for LLVM GCC front end. --- Diffs of the changes: (+0 -0) Index: llvm-www/releases/1.0/cfrontend-src.tar.gz From vadve at cs.uiuc.edu Thu Oct 23 21:37:02 2003 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Thu Oct 23 21:37:02 2003 Subject: [llvm-commits] CVS: llvm/README.txt Message-ID: <200310240236.VAA08596@psmith.cs.uiuc.edu> Changes in directory llvm: README.txt updated: 1.3 -> 1.4 --- Log message: Organized in 4 parts. The last two are the same as before: LLVM Docs and Mailing Lists. The first two are ""Getting Started" and "Getting Help." --- Diffs of the changes: (+76 -53) Index: llvm/README.txt diff -u llvm/README.txt:1.3 llvm/README.txt:1.4 --- llvm/README.txt:1.3 Fri Oct 17 16:10:57 2003 +++ llvm/README.txt Thu Oct 23 21:36:15 2003 @@ -1,32 +1,62 @@ + The LLVM Compiler Infrastructure + http://llvm.cs.uiuc.edu + Welcome to LLVM! +----------------- +This file is intended to do four things: +(1) help you get started using LLVM; +(2) tell you how to get questions about LLVM answered; +(3) tell you where to find documentation for different kinds of questions; and +(4) tell you about three LLVM-related mailing lists. + + +Getting Started with LLVM +------------------------- + +(1) For license information: + llvm/LICENSE.txt + +(2) Installing and compiling LLVM: + llvm/docs/GettingStarted.html -This file provides the location of all important LLVM documentation. In -particular, you should read the license information and the installation -directions before you begin using LLVM. +(3) Learn about features and limitations of this release: + llvm/docs/ReleaseNotes.html -After that, there are several technical references that will help you use LLVM. -Consult them as necessary. +(4) Learn how to write a pass within the LLVM system: + llvm/docs/WritingAnLLVMPass.html -Finally, you can find information on how to communicate with the LLVM -developers and LLVM community. This is of primary interest if you wish to -submit a bug, supply a patch, or just keep current with what's going on with -LLVM. +(5) Learn how to start a new development project using LLVM, where your + new source code can live anywhere (outside or inside the LLVM tree), + while using LLVM header files and libraries: + llvm/docs/Projects.html -Introductory Literature: - LLVM Home Page: - http://llvm.cs.uiuc.edu +Getting Help with LLVM +---------------------- - License Information: - llvm/LICENSE.txt +(1) If you have questions or development problems not answered in the + documentation, send e-mail to llvmdev at cs.uiuc.edu. This mailing list is + monitored by all the people in the LLVM group at Illinois, and you should + expect prompt first responses. + +(2) To report a bug, submit a bug report as described in the document: + http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html + +(3) We now use Bugzilla to track bugs, so you can check the status of + previous bugs at: + - Release Notes: - llvm/docs/ReleaseNotes.html -LLVM Design: +LLVM Documentation +------------------ - The LLVM Instruction Set and Compilation Strategy: - http://llvm.cs.uiuc.edu/pubs/2002-08-09-LLVMCompilationStrategy.html +All the documents mentioned below except the design overview tech report +are include as part of the LLVM release (in llvm/docs/*): + +LLVM Design Overview: + LLVM : A Compilation Framework for Lifelong Program Analysis + and Transformation: + http://llvm.cs.uiuc.edu/pubs/2003-09-30-LifelongOptimizationTR.html LLVM User Guides: @@ -59,7 +89,7 @@ Coding Standards: llvm/docs/CodingStandards.html -LLVM Community: +Other LLVM Resources: Submitting a Bug: http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html @@ -70,37 +100,30 @@ Creating a new LLVM Project: llvm/docs/Projects.html - Mailing Lists: - There are several mailing lists providing LLVM users with - information: - - o LLVM Announcements List: - http://mail.cs.uiuc.edu/mailman/listinfo/llvm-announce - - This is a low volume list that provides - important announcements regarding LLVM. It is - primarily intended to announce new releases, - major updates to the software, etc. This list - is highly recommended for anyone that uses LLVM. - - - o LLVM Developers List: - http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev - - This list is for people who want to be included - in technical discussions of LLVM. People post - to this list when they have questions about - writing code for or using the LLVM tools. It - is low volume. - - o LLVM Commits List - http://mail.cs.uiuc.edu/mailman/listinfo/llvm-commits - - This list contains all commit messages that are - made when LLVM developers commit code changes - to the CVS archive. It is useful for those who - want to stay on the bleeding edge of LLVM - development. - - This list is very high volume. +Mailing Lists +-------------- +There are three mailing lists for providing LLVM users with information: + +(1) LLVM Announcements List: + http://mail.cs.uiuc.edu/mailman/listinfo/llvm-announce + + This is a low volume list that provides important announcements regarding + LLVM. It is primarily intended to announce new releases, major updates to + the software, etc. This list is highly recommended for anyone that uses + LLVM. + +(2) LLVM Developers List: + http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev + + This list is for people who want to be included in technical discussions + of LLVM. People post to this list when they have questions about writing + code for or using the LLVM tools. It is relatively low volume. + +(3) LLVM Commits List + http://mail.cs.uiuc.edu/mailman/listinfo/llvm-commits + + This list contains all commit messages that are made when LLVM developers + commit code changes to the CVS archive. It is useful for those who want to + stay on the bleeding edge of LLVM development. This list is very high + volume. From criswell at cs.uiuc.edu Thu Oct 23 22:03:00 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Oct 23 22:03:00 2003 Subject: [llvm-commits] [release_1] CVS: llvm/README.txt Message-ID: <200310240302.WAA27571@choi.cs.uiuc.edu> Changes in directory llvm: README.txt updated: 1.3.2.2 -> 1.3.2.3 --- Log message: Merged in revision 1.4, adjusting tabs to spaces to keep indentation correct. --- Diffs of the changes: (+75 -62) Index: llvm/README.txt diff -u llvm/README.txt:1.3.2.2 llvm/README.txt:1.3.2.3 --- llvm/README.txt:1.3.2.2 Thu Oct 23 19:54:03 2003 +++ llvm/README.txt Thu Oct 23 22:02:32 2003 @@ -1,42 +1,62 @@ -##===----------------------------------------------------------------------===## -# -# 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. -# -##===----------------------------------------------------------------------===## + The LLVM Compiler Infrastructure + http://llvm.cs.uiuc.edu Welcome to LLVM! +----------------- +This file is intended to do four things: +(1) help you get started using LLVM; +(2) tell you how to get questions about LLVM answered; +(3) tell you where to find documentation for different kinds of questions; and +(4) tell you about three LLVM-related mailing lists. -This file provides the location of all important LLVM documentation. In -particular, you should read the license information and the installation -directions before you begin using LLVM. -After that, there are several technical references that will help you use LLVM. -Consult them as necessary. +Getting Started with LLVM +------------------------- -Finally, you can find information on how to communicate with the LLVM -developers and LLVM community. This is of primary interest if you wish to -submit a bug, supply a patch, or just keep current with what's going on with -LLVM. +(1) For license information: + llvm/LICENSE.txt -Introductory Literature: +(2) Installing and compiling LLVM: + llvm/docs/GettingStarted.html - LLVM Home Page: - http://llvm.cs.uiuc.edu +(3) Learn about features and limitations of this release: + llvm/docs/ReleaseNotes.html - License Information: - llvm/LICENSE.txt +(4) Learn how to write a pass within the LLVM system: + llvm/docs/WritingAnLLVMPass.html - Release Notes: - llvm/docs/ReleaseNotes.html +(5) Learn how to start a new development project using LLVM, where your + new source code can live anywhere (outside or inside the LLVM tree), + while using LLVM header files and libraries: + llvm/docs/Projects.html -LLVM Design: - LLVM: A Compilation Framework for Lifelong Program Analysis & - Transformation - http://llvm.cs.uiuc.edu/pubs/2003-09-30-LifelongOptimizationTR.html +Getting Help with LLVM +---------------------- + +(1) If you have questions or development problems not answered in the + documentation, send e-mail to llvmdev at cs.uiuc.edu. This mailing list is + monitored by all the people in the LLVM group at Illinois, and you should + expect prompt first responses. + +(2) To report a bug, submit a bug report as described in the document: + http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html + +(3) We now use Bugzilla to track bugs, so you can check the status of + previous bugs at: + + + +LLVM Documentation +------------------ + +All the documents mentioned below except the design overview tech report +are include as part of the LLVM release (in llvm/docs/*): + +LLVM Design Overview: + LLVM : A Compilation Framework for Lifelong Program Analysis + and Transformation: + http://llvm.cs.uiuc.edu/pubs/2003-09-30-LifelongOptimizationTR.html LLVM User Guides: @@ -69,7 +89,7 @@ Coding Standards: llvm/docs/CodingStandards.html -LLVM Community: +Other LLVM Resources: Submitting a Bug: http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html @@ -80,37 +100,30 @@ Creating a new LLVM Project: llvm/docs/Projects.html - Mailing Lists: - There are several mailing lists providing LLVM users with - information: - - o LLVM Announcements List: - http://mail.cs.uiuc.edu/mailman/listinfo/llvm-announce - - This is a low volume list that provides - important announcements regarding LLVM. It is - primarily intended to announce new releases, - major updates to the software, etc. This list - is highly recommended for anyone that uses LLVM. - - - o LLVM Developers List: - http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev - - This list is for people who want to be included - in technical discussions of LLVM. People post - to this list when they have questions about - writing code for or using the LLVM tools. It - is low volume. - - o LLVM Commits List - http://mail.cs.uiuc.edu/mailman/listinfo/llvm-commits - - This list contains all commit messages that are - made when LLVM developers commit code changes - to the CVS archive. It is useful for those who - want to stay on the bleeding edge of LLVM - development. - - This list is very high volume. +Mailing Lists +-------------- +There are three mailing lists for providing LLVM users with information: + +(1) LLVM Announcements List: + http://mail.cs.uiuc.edu/mailman/listinfo/llvm-announce + + This is a low volume list that provides important announcements regarding + LLVM. It is primarily intended to announce new releases, major updates to + the software, etc. This list is highly recommended for anyone that uses + LLVM. + +(2) LLVM Developers List: + http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev + + This list is for people who want to be included in technical discussions + of LLVM. People post to this list when they have questions about writing + code for or using the LLVM tools. It is relatively low volume. + +(3) LLVM Commits List + http://mail.cs.uiuc.edu/mailman/listinfo/llvm-commits + + This list contains all commit messages that are made when LLVM developers + commit code changes to the CVS archive. It is useful for those who want to + stay on the bleeding edge of LLVM development. This list is very high + volume. From gaeke at cs.uiuc.edu Thu Oct 23 22:56:01 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu Oct 23 22:56:01 2003 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/JIT/VM.cpp Message-ID: <200310240355.WAA25002@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/JIT: VM.cpp updated: 1.11 -> 1.12 --- Log message: Destroy MachineFunction for any Function that we are about to recompile and relink. This keeps it from failing an assertion when it goes and tries to construct a new MachineFunction for that Function. --- Diffs of the changes: (+2 -0) Index: llvm/lib/ExecutionEngine/JIT/VM.cpp diff -u llvm/lib/ExecutionEngine/JIT/VM.cpp:1.11 llvm/lib/ExecutionEngine/JIT/VM.cpp:1.12 --- llvm/lib/ExecutionEngine/JIT/VM.cpp:1.11 Mon Oct 20 14:43:16 2003 +++ llvm/lib/ExecutionEngine/JIT/VM.cpp Thu Oct 23 22:55:37 2003 @@ -15,6 +15,7 @@ #include "VM.h" #include "llvm/Function.h" #include "llvm/ModuleProvider.h" +#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/Target/TargetMachine.h" @@ -91,6 +92,7 @@ void *OldAddr = Addr; Addr = 0; + MachineFunction::destruct (F); runJITOnFunction (F); assert(Addr && "Code generation didn't add function to GlobalAddress table!"); TM.replaceMachineCodeForFunction (OldAddr, Addr); From lattner at cs.uiuc.edu Thu Oct 23 23:04:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 23:04:01 2003 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200310240403.XAA25051@zion.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.11 -> 1.12 --- Log message: Update list of passes and buglist. --- Diffs of the changes: (+10 -1) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.11 llvm/docs/ReleaseNotes.html:1.12 --- llvm/docs/ReleaseNotes.html:1.11 Wed Oct 22 13:19:08 2003 +++ llvm/docs/ReleaseNotes.html Thu Oct 23 23:03:19 2003 @@ -64,7 +64,10 @@ The default optimizer sequence used by the C/C++ front-ends is:

      +
    1. CFG simplification (-simplifycfg)
    2. Interprocedural dead code elimination (-globaldce) +
    3. Interprocedural constant propagation (-ipconstprop) +
    4. Dead argument elimination (-deadargelim)
    5. Exception handling pruning (-prune-eh)
    6. Function inlining (-inline)
    7. Instruction combining (-instcombine) @@ -94,6 +97,7 @@
      1. Global constant merging (-constmerge)
      2. [optional] Internalization [which marks most functions and global variables static] (-internalize) +
      3. Interprocedural constant propagation (-ipconstprop)
      4. Interprocedural dead argument elimination (-deadargelim)
      5. Instruction combining (-instcombine)
      6. CFG simplification (-simplifycfg) @@ -103,7 +107,8 @@ At this time, LLVM is known to work properly with SPEC CPU 2000, the Olden benchmarks, and the Ptrdist benchmarks among many other programs. Note however that the Sparc and X86 backends do not currently support exception throwing or -long jumping. For these programs you must use the C backend.

        +long jumping (including 253.perlbmk in SPEC). For these programs you must use +the C backend.

        @@ -357,6 +362,10 @@

      7. Initializers for global variables cannot include special floating point numbers like Not-A-Number or Infinity.

        + +

      8. Zero arg vararg functions are not +supported. This should not affect LLVM produced by the C or C++ +frontends.

      9. The code produces by the C back-end has only been tested with the Sun CC and GCC compilers. It is possible that it will have to be adjusted to support other From lattner at cs.uiuc.edu Thu Oct 23 23:59:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 23 23:59:01 2003 Subject: [llvm-commits] CVS: llvm-www/releases/1.0/announcement.txt Message-ID: <200310240458.XAA25232@zion.cs.uiuc.edu> Changes in directory llvm-www/releases/1.0: announcement.txt added (r1.1) --- Log message: Make the announcement live in CVS --- Diffs of the changes: (+66 -0) Index: llvm-www/releases/1.0/announcement.txt diff -c /dev/null llvm-www/releases/1.0/announcement.txt:1.1 *** /dev/null Thu Oct 23 23:58:35 2003 --- llvm-www/releases/1.0/announcement.txt Thu Oct 23 23:58:25 2003 *************** *** 0 **** --- 1,66 ---- + LLVM Compiler Infrastructure -- Release 1.0 + http://llvm.cs.uiuc.edu (*) + + We are pleased to announce the public release of the LLVM Compiler + Infrastructure under a non-restrictive open source license. + + WHAT IS LLVM? + LLVM is a new infrastructure designed for compile-time, link-time, runtime, + and "idle-time" optimization of programs from arbitrary programming + languages. LLVM is written in C++ and has been developed over the past 3 + years at the University of Illinois. It currently supports compilation of + C and C++ programs, using front-ends derived from GCC 3.4. New front-ends + are being written for Java bytecode and O-Caml. + + WHOM MIGHT THIS RELEASE BE USEFUL? + o Compiler researchers interested in compile-time, link-time + (interprocedural) and runtime transformations for C and C++ programs. + o Virtual machine researchers/developers interested in a portable, + language-independent instruction set and compilation framework. + o Architecture researchers interested in compiler/hardware techniques. + o Security researchers interested in static analysis or instrumentation. + o Instructors (or anyone else) interested in a system for quick + prototyping of compiler transformations. + + HOW LONG DOES IT TAKE TO GET STARTED WITH LLVM? + + We have found that new users can install LLVM and write their first LLVM + pass in hours, and start sophisticated projects using LLVM within days. + + WHY IS LLVM USEFUL? + LLVM uses a low-level, RISC-like, language-independent representation to + analyze and optimize programs. Key features include explicit control + flow, dataflow (SSA), and a language-independent type system that can + capture the _operational behavior_ of high-level languages. The LLVM + representation is low-level enough to represent arbitrary application and + system code, yet is powerful enough to support aggressive "high-level" + transformations. The LLVM infrastructure uses this representation to + allow these optimizations to occur at compile-time, link-time and runtime. + + WHAT IS INCLUDED IN THIS RELEASE? + Release 1.0 is intended to be a fully functional release of our compiler + system for C and C++. As such, it includes the following: + o Front-ends for C and C++ based on GCC 3.4, supporting the full + ANSI-standard C and C++ languages, plus many GCC extensions. + o A wide range of global scalar optimizations + o A link-time interprocedural optimization framework, with a rich + set of analyses and transformations, including sophisticated + whole-program pointer analysis and call graph construction. + o Native code generators for x86 and Sparc + o A JIT code generation system for x86 and Sparc + o A C back-end, useful for testing and to support other targets + o A test framework with a number of benchmark codes and some applications + o APIs and debugging tools to simplify rapid development + + WHAT IS NOT INCLUDED IN THIS RELEASE? + Some components are not yet implemented in LLVM, including array dependence + analysis, dependence-based transformations, profiling support, and a + trace-based dynamic optimization system. The native code generators are + not yet competitive with vendor compilers in performance. + + HOW DO I GET IT? + Please see: http://llvm.cs.uiuc.edu/releases (*) + + ------- + (*) Hosted by apache compiled to LLVM and running on the x86 JIT + From brukman at cs.uiuc.edu Fri Oct 24 00:39:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Oct 24 00:39:01 2003 Subject: [llvm-commits] CVS: llvm-www/releases/1.0/announcement.txt Message-ID: <200310240538.AAA30049@zion.cs.uiuc.edu> Changes in directory llvm-www/releases/1.0: announcement.txt updated: 1.1 -> 1.2 --- Log message: http://www.ocaml.org calls it "O'Caml" and I think we should, too. --- Diffs of the changes: (+1 -1) Index: llvm-www/releases/1.0/announcement.txt diff -u llvm-www/releases/1.0/announcement.txt:1.1 llvm-www/releases/1.0/announcement.txt:1.2 --- llvm-www/releases/1.0/announcement.txt:1.1 Thu Oct 23 23:58:25 2003 +++ llvm-www/releases/1.0/announcement.txt Fri Oct 24 00:38:10 2003 @@ -10,7 +10,7 @@ languages. LLVM is written in C++ and has been developed over the past 3 years at the University of Illinois. It currently supports compilation of C and C++ programs, using front-ends derived from GCC 3.4. New front-ends - are being written for Java bytecode and O-Caml. + are being written for Java bytecode and O'Caml. WHOM MIGHT THIS RELEASE BE USEFUL? o Compiler researchers interested in compile-time, link-time From alkis at cs.uiuc.edu Fri Oct 24 01:08:03 2003 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri Oct 24 01:08:03 2003 Subject: [llvm-commits] [regalloc_linearscan] CVS: llvm/include/llvm/CodeGen/LiveIntervals.h Message-ID: <200310240606.BAA04170@morpheus.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: LiveIntervals.h added (r1.1.2.1) --- Log message: Add live interval analysis pass --- Diffs of the changes: (+95 -0) Index: llvm/include/llvm/CodeGen/LiveIntervals.h diff -c /dev/null llvm/include/llvm/CodeGen/LiveIntervals.h:1.1.2.1 *** /dev/null Fri Oct 24 01:06:57 2003 --- llvm/include/llvm/CodeGen/LiveIntervals.h Fri Oct 24 01:06:46 2003 *************** *** 0 **** --- 1,95 ---- + //===-- llvm/CodeGen/LiveInterval.h - Live Interval Analysis ---*- C++ -*-===// + // + // This file implements the LiveInterval analysis pass. Given some + // numbering of each the machine instructions (in this implemenation + // depth-first order) an interval [i, j] is said to be a live interval + // for register v if there is no instruction with number j' > j such + // that v is live at j' abd there is no instruction with number i' < i + // such that v is live at i'. + // + //===----------------------------------------------------------------------===// + + #ifndef LLVM_CODEGEN_LIVEINTERVALS_H + #define LLVM_CODEGEN_LIVEINTERVALS_H + + #include "llvm/CodeGen/MachineFunctionPass.h" + #include "llvm/CodeGen/MachineBasicBlock.h" + #include + + class LiveVariables; + class MRegisterInfo; + + class LiveIntervals : public MachineFunctionPass { + public: + struct Interval { + unsigned reg; // the register of this interval + unsigned start; // the start instruction (def) + unsigned end; // the end instruction (last use) + + Interval(unsigned r, unsigned b, unsigned e) + : reg(r), start(b), end(e) { + + } + }; + + struct StartPointComp { + bool operator()(const Interval& lhs, const Interval& rhs) { + return lhs.start < rhs.start; + } + }; + + struct EndPointComp { + bool operator()(const Interval& lhs, const Interval& rhs) { + return lhs.end < rhs.end; + } + }; + + private: + MachineFunction* _mf; + const TargetMachine* _tm; + const MRegisterInfo* _mri; + MachineBasicBlock* _currentMbb; + MachineBasicBlock::iterator _currentInstr; + LiveVariables* _lv; + + typedef std::vector MBBPtrs; + MBBPtrs _mbbOrder; + + typedef std::map Instr2IndexMap; + Instr2IndexMap _i2iMap; + + typedef std::vector Intervals; + Intervals _intervals; + + typedef std::map Reg2IntervalMap; + + public: + virtual void getAnalysisUsage(AnalysisUsage &AU) const; + + private: + /// runOnMachineFunction - pass entry point + bool runOnMachineFunction(MachineFunction&); + + /// computeIntervals - compute live intervals + void computeIntervals(); + + /// handleRegisterDef - update intervals for a register def + void handleRegisterDef(Reg2IntervalMap& r2iMap, unsigned i, unsigned reg); + + /// handleRegisterKill - update intervals for a register kill + void handleRegisterKill(Reg2IntervalMap& r2iMap, unsigned i, unsigned reg); + }; + + inline bool operator==(const LiveIntervals::Interval& lhs, + const LiveIntervals::Interval& rhs) { + return lhs.reg == rhs.reg; + } + + inline std::ostream& operator<<(std::ostream& os, + const LiveIntervals::Interval& i) { + return os << "[ %reg" << i.reg << ", " + << i.start << ", " << i.end << "]"; + } + + + #endif From alkis at cs.uiuc.edu Fri Oct 24 01:08:19 2003 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri Oct 24 01:08:19 2003 Subject: [llvm-commits] [regalloc_linearscan] CVS: llvm/lib/CodeGen/LiveIntervals.cpp Passes.cpp RegAllocLinearScan.cpp Message-ID: <200310240606.BAA04183@morpheus.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveIntervals.cpp added (r1.1.2.1) Passes.cpp updated: 1.1.2.1 -> 1.1.2.2 RegAllocLinearScan.cpp updated: 1.1.2.3 -> 1.1.2.4 --- Log message: Add live interval analysis pass --- Diffs of the changes: (+575 -48) Index: llvm/lib/CodeGen/LiveIntervals.cpp diff -c /dev/null llvm/lib/CodeGen/LiveIntervals.cpp:1.1.2.1 *** /dev/null Fri Oct 24 01:06:57 2003 --- llvm/lib/CodeGen/LiveIntervals.cpp Fri Oct 24 01:06:47 2003 *************** *** 0 **** --- 1,208 ---- + //===-- LiveIntervals.cpp - Linear Scan register allocator --------------===// + // + // 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 LiveInterval analysis pass which is used + // by the Linear Scan Register allocator. This pass linearizes the + // basic blocks of the function in DFS order and uses the + // LiveVariables pass to conservatively compute live intervals for + // each virtual and physical register. + // + //===--------------------------------------------------------------------===// + + #define DEBUG_TYPE "liveintervals" + #include "llvm/CodeGen/LiveIntervals.h" + #include "llvm/Function.h" + #include "llvm/CodeGen/LiveVariables.h" + #include "llvm/CodeGen/MachineFrameInfo.h" + #include "llvm/CodeGen/MachineFunctionPass.h" + #include "llvm/CodeGen/MachineInstr.h" + #include "llvm/CodeGen/Passes.h" + #include "llvm/CodeGen/SSARegMap.h" + #include "llvm/Target/MRegisterInfo.h" + #include "llvm/Target/TargetInstrInfo.h" + #include "llvm/Target/TargetMachine.h" + #include "llvm/Target/TargetRegInfo.h" + #include "llvm/Support/CFG.h" + #include "Support/Debug.h" + #include "Support/DepthFirstIterator.h" + #include "Support/Statistic.h" + #include + + namespace { + RegisterAnalysis X("liveintervals", + "Live Interval Analysis"); + + Statistic<> numIntervals("liveintervals", "Number of intervals"); + }; + + void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const + { + AU.setPreservesAll(); + AU.addRequired(); + MachineFunctionPass::getAnalysisUsage(AU); + } + + /// runOnMachineFunction - Register allocate the whole function + /// + bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) { + DEBUG(std::cerr << "Machine Function\n"); + _mf = &fn; + _tm = &fn.getTarget(); + _mri = _tm->getRegisterInfo(); + _lv = &getAnalysis(); + + // create a mapping from BasicBlock* to MachineBasicBlock* + typedef std::map BB2MBBMap; + BB2MBBMap bb2mbbMap; + for (MachineFunction::iterator mbb = _mf->begin(), mbbEnd = _mf->end(); + mbb != mbbEnd; ++mbb) { + bool inserted = bb2mbbMap.insert( + std::make_pair(mbb->getBasicBlock(), &*mbb)).second; + assert(inserted && "multiple BasicBlock -> MachineBasicBlock mappings"); + } + + // add MachineBasicBlocks in depth first order + _mbbOrder.clear(); + _mbbOrder.reserve(bb2mbbMap.size()); + const BasicBlock* entry = _mf->getFunction()->begin(); + for (df_iterator + bb = df_begin(entry), bbEnd = df_end(entry); + bb != bbEnd; ++bb) { + MachineBasicBlock* mbb = bb2mbbMap.find(*bb)->second; + _mbbOrder.push_back(mbb); + assert(mbb && "MachineBasicBlock for BasicBlock cannot be null"); + } + + _i2iMap.clear(); + + computeIntervals(); + + return true; + } + + namespace { + void printRegName(const MRegisterInfo* mri, int reg) { + DEBUG( + if (reg < MRegisterInfo::FirstVirtualRegister) + std::cerr << mri->getName(reg); + else + std::cerr << '%' << reg); + } + } + + void LiveIntervals::handleRegisterDef(Reg2IntervalMap& r2iMap, + unsigned i, + unsigned reg) + { + DEBUG(std::cerr << "\t\t\t\tregister: "; printRegName(_mri, reg)); + + assert((reg < MRegisterInfo::FirstVirtualRegister || + r2iMap.find(reg) == r2iMap.end()) && + "multiple definitions of virtual register"); + // initialize intervals to [index, inf] - be conservative! + _intervals.push_back( + Interval(reg, i, std::numeric_limits::max())); + // update last live interval for this register + r2iMap[reg] = _intervals.size() - 1; + + DEBUG(std::cerr << " -> ADD interval " << _intervals.back() << '\n'); + } + + void LiveIntervals::handleRegisterKill(Reg2IntervalMap& r2iMap, + unsigned i, + unsigned reg) + { + DEBUG(std::cerr << "\t\t\t\tregister: "; printRegName(_mri, reg)); + + Reg2IntervalMap::iterator ri = r2iMap.find(reg); + assert(ri != r2iMap.end() + && "did not find live interval for killed register"); + Interval& interval = _intervals[ri->second]; + // if this is a later kill remark the end here - be conservative! + interval.end = i; + + DEBUG(std::cerr << " -> END interval " << interval << '\n'); + } + + /// computeIntervals - computes the live intervals for virtual + /// registers. for some ordering of the machine instructions [1,N] a + /// live interval is an interval [i, j] where 1 <= i <= j <= N for + /// which a variable is live + void LiveIntervals::computeIntervals() + { + DEBUG(std::cerr << "computing live intervals:\n"); + + // register -> last live interval index + Reg2IntervalMap r2iMap; + + unsigned index = 0; + for (MBBPtrs::iterator it = _mbbOrder.begin(), itEnd = _mbbOrder.end(); + it != itEnd; ++it) { + MachineBasicBlock* mbb = *it; + DEBUG(std::cerr << "machine basic block: " << mbb); + for (MachineBasicBlock::iterator mi = mbb->begin(), miEnd = mbb->end(); + mi != miEnd; ++index, ++mi) { + MachineInstr* instr = *mi; + const TargetInstrDescriptor& tid = + _tm->getInstrInfo().get(instr->getOpcode()); + _i2iMap.insert(std::make_pair(instr, index)); + DEBUG(std::cerr << "\t\tinstruction[" << index << "]: " + << *instr << '\n'); + + DEBUG(std::cerr << "\t\t\thandling implicit definitions:\n"); + for (const unsigned* id = tid.ImplicitDefs; *id; ++id) { + unsigned reg = *id; + handleRegisterDef(r2iMap, index, reg); + } + + DEBUG(std::cerr << "\t\t\thandling kills:\n"); + for (LiveVariables::killed_iterator + ki = _lv->killed_begin(instr), + kiEnd = _lv->killed_end(instr); + ki != kiEnd; ++ki) { + unsigned reg = ki->second; + handleRegisterKill(r2iMap, index, reg); + } + + DEBUG(std::cerr << "\t\t\thandling definitions:\n"); + for (int i = instr->getNumOperands() - 1; i >= 0; --i) { + MachineOperand& mop = instr->getOperand(i); + + if (!mop.isRegister()) + continue; + + // mark start and end points + unsigned reg = mop.getAllocatedRegNum(); + if (mop.opIsDefOnly() || mop.opIsDefAndUse()) { + handleRegisterDef(r2iMap, index, reg); + } + } + } + + // kill all physical registers in the end of each basic block + for (Intervals::iterator it = + _intervals.begin(), itEnd = _intervals.end(); + it != itEnd; ++it) { + unsigned reg = it->reg; + if (reg < MRegisterInfo::FirstVirtualRegister) { + handleRegisterKill(r2iMap, index, reg); + } + } + } + + // sort the live intervals in increasing start point + sort(_intervals.begin(), _intervals.end(), StartPointComp()); + + DEBUG( + for(Intervals::iterator + it = _intervals.begin(), itEnd = _intervals.end(); + it != itEnd; ++it) { + std::cerr << *it << '\n'; + }); + } Index: llvm/lib/CodeGen/Passes.cpp diff -u llvm/lib/CodeGen/Passes.cpp:1.1.2.1 llvm/lib/CodeGen/Passes.cpp:1.1.2.2 --- llvm/lib/CodeGen/Passes.cpp:1.1.2.1 Thu Oct 2 12:17:02 2003 +++ llvm/lib/CodeGen/Passes.cpp Fri Oct 24 01:06:47 2003 @@ -15,9 +15,9 @@ RegAlloc("regalloc", cl::desc("Register allocator to use: (default = simple)"), cl::Prefix, - cl::values(clEnumVal(simple, " simple register allocator"), - clEnumVal(local, " local register allocator"), - clEnumVal(local, " linear-scan global register allocator"), + cl::values(clEnumVal(simple, " simple register allocator"), + clEnumVal(local, " local register allocator"), + clEnumVal(linearscan, " linear-scan global register allocator"), 0), cl::init(local)); } Index: llvm/lib/CodeGen/RegAllocLinearScan.cpp diff -u llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.1.2.3 llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.1.2.4 --- llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.1.2.3 Thu Oct 2 02:26:01 2003 +++ llvm/lib/CodeGen/RegAllocLinearScan.cpp Fri Oct 24 01:06:47 2003 @@ -1,71 +1,390 @@ //===-- RegAllocLinearScan.cpp - Linear Scan register allocator ---------===// // -// This file implements a linear scan register allocator.. +// This file implements a linear scan register allocator. // //===--------------------------------------------------------------------===// #define DEBUG_TYPE "regalloc" -#include "llvm/CodeGen/Passes.h" +#include "llvm/Function.h" +#include "llvm/CodeGen/LiveIntervals.h" +#include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/CodeGen/SSARegMap.h" #include "llvm/Target/MRegisterInfo.h" +#include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetRegInfo.h" +#include "llvm/Support/CFG.h" #include "Support/Debug.h" +#include "Support/DepthFirstIterator.h" #include "Support/Statistic.h" #include namespace { - Statistic<> NumSpilled ("ra-linearscan", "Number of registers spilled"); - Statistic<> NumReloaded("ra-linearscan", "Number of registers reloaded"); + Statistic<> numSpilled ("ra-linearscan", "Number of registers spilled"); + Statistic<> numReloaded("ra-linearscan", "Number of registers reloaded"); + + class RA : public MachineFunctionPass { + private: + MachineFunction* _mf; + const TargetMachine* _tm; + const TargetRegInfo* _tri; + const MRegisterInfo* _mri; + MachineBasicBlock* _currentMbb; + MachineBasicBlock::iterator _currentInstr; + + LiveIntervals* _li; + + typedef std::map Instr2IndexMap; + Instr2IndexMap _i2iMap; + + typedef std::vector Phys2VirtMap; + Phys2VirtMap _p2vMap; + + typedef std::map Virt2PhysMap; + Virt2PhysMap _v2pMap; + + typedef std::map Virt2StackSlotMap; + Virt2StackSlotMap _v2ssMap; + + public: + virtual const char* getPassName() const { + return "Linear Scan Register Allocator"; + } + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequiredID(PHIEliminationID); + AU.addRequired(); + MachineFunctionPass::getAnalysisUsage(AU); + } + + private: + /// runOnMachineFunction - Register allocate the whole function + bool runOnMachineFunction(MachineFunction&); + + /// expireOldIntervals - in each iteration of the linear scan + /// loop, expire the old intervals; that is the registers that + /// are killed +// void expireOldIntervals(Intervals::iterator li); + + /// spillAtInterval - choose and spill at the specified + /// interval. Currently we spill using a heuristic: the active + /// interval that ends last +// void spillAtInterval(Intervals::iterator li); + + /// computeIntervals - computes the live intervals for + /// virtual registers + void computeIntervals(); + + /// getFreeReg - return a free register for this virtual + /// register if we have one, otherwise return 0 + unsigned getFreeReg(unsigned virtReg); + + /// physRegAvailable - returns true if the specifed physical + /// register is available + bool physRegAvailable(unsigned physReg); + + /// findOrCreateStackSlot - returns the offset of the + /// specified register on the stack allocating space if + /// necessary + int findOrCreateStackSlot(unsigned virtReg); + + /// spillVirtReg - spills the virtual register + void spillVirtReg(unsigned virtReg, unsigned physReg); + + /// loadPhysReg - loads to the physical register the value of + /// the virtual register specifed + void loadPhysReg(unsigned physReg, unsigned virtReg); + }; +} + +/// runOnMachineFunction - Register allocate the whole function +/// +bool RA::runOnMachineFunction(MachineFunction &fn) { + DEBUG(std::cerr << "Machine Function\n"); + _mf = &fn; + _tm = &fn.getTarget(); + _tri = &_tm->getRegInfo(); + _mri = _tm->getRegisterInfo(); + _li = &getAnalysis(); + _p2vMap.resize(_mri->getNumRegs()); + _p2vMap.clear(); + _v2pMap.clear(); + _v2ssMap.clear(); + +// computeIntervals(); + +// // liner scan algorithm +// for (Intervals::iterator li = _intervals.begin(), liEnd = _intervals.end(); +// li != liEnd; ++li) { +// // FIXME: find a more efficient way to keep track of the +// // iterator on the current instruction +// MachineInstr* mi = _instrOrdering[li->start].first; +// _currentMbb = _instrOrdering[li->start].second; +// _currentInstr = find(_currentMbb->begin(), _currentMbb->end(), mi); +// assert(_currentInstr != _currentMbb->end() && +// "Cannot find instruction in basic block"); +// // check if this interval is for a physical or a virtual register +// if (li->mop->isVirtualRegister()) { +// expireOldIntervals(li); +// if (unsigned physReg = getFreeReg(li->mop->getAllocatedRegNum())) { +// loadPhysReg(physReg, li->mop->getAllocatedRegNum()); +// } +// else { +// spillAtInterval(li); +// } +// } +// else { +// // spill register if it is used +// // mark register as used +// } +// } - class RA : public MachineFunctionPass { - private: - MachineFunction *MF; - const TargetMachine *TM; - const MRegisterInfo *RegInfo; - - // StackSlotForVirtReg - Maps virtual regs to the frame index where these - // values are spilled. - std::map StackSlotForVirtReg; - - // Virt2PhysRegMap - This map contains entries for each virtual register - // that is currently available in a physical register. - // - std::map Virt2PhysRegMap; - - // Phys2VirtRegMap - This map contains entries for each physical register - // that currently maps a virtual register.. - // - std::map Phys2VirtRegMap; - - public: - virtual const char* getPassName() const { - return "Linear Scan Register Allocator"; + return true; +} + +/// computeIntervals - computes the live intervals for virtual +/// registers. for some ordering of the machine instructions [1,N] a +/// live interval is an interval [i, j] where 1 <= i <= j <= N for +/// which a variable is live +void RA::computeIntervals() +{ + DEBUG(std::cerr << "\tcomputing live intervals:\n"); + + // create a mapping from BasicBlock* to MachineBasicBlock* + typedef std::map BB2MBBMap; + BB2MBBMap bb2mbbMap; + for (MachineFunction::iterator mbb = _mf->begin(), mbbEnd = _mf->end(); + mbb != mbbEnd; ++mbb) { + bool inserted = bb2mbbMap.insert( + std::make_pair(mbb->getBasicBlock(), &*mbb)).second; + assert(inserted && "multiple BasicBlock -> MachineBasicBlock mappings"); } - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequiredID(PHIEliminationID); - MachineFunctionPass::getAnalysisUsage(AU); + + // depth first ordering for the instructions (use depth first + // ordering of BasicBlocks, map to MachineBasicBlocks and + // sequentially order the instructions in each block + const BasicBlock* entry = _mf->getFunction()->begin(); + + // register -> live interval index + typedef std::map Reg2IntervalMap; + Reg2IntervalMap r2iMap; + + unsigned index = 0; +// for (df_iterator +// bb = df_begin(entry), bbEnd = df_end(entry); +// bb != bbEnd; ++bb) { +// MachineBasicBlock* mbb = bb2mbbMap.find(*bb)->second; +// assert(mbb && "MachineBasicBlock for BasicBlock cannot be null"); + +// for (MachineBasicBlock::iterator mi = mbb->begin(), miEnd = mbb->end(); +// mi != miEnd; ++index, ++mi) { +// MachineInstr* instr = *mi; +// const TargetInstrDescriptor& tid = +// _tm->getInstrInfo().get(instr->getOpcode()); +// _i2iMap.insert(std::make_pair(instr, index)); +// DEBUG(std::cerr << "\t\tinstruction[" << index << "]: " << *instr << '\n'); +// for (const unsigned* id =tid.ImplicitDefs; *id; ++id) { +// unsigned reg = *id; +// assert(r2iMap.find(reg) == r2iMap.end() && +// "multiple definitions of virtual register"); +// // initialize intervals to [index, inf] +// _intervals.push_back( +// Interval(reg, +// index, +// std::numeric_limits::max())); +// r2iMap.insert(std::make_pair(reg, _intervals.size() - 1)); +// DEBUG(std::cerr << "\t\t\tadded interval for register " +// << _tri->getUnifiedRegName(reg) +// << ": " << _intervals.back() << '\n'); +// } + +// for (int i = instr->getNumOperands() - 1; i >= 0; --i) { +// MachineOperand& mop = instr->getOperand(i); + +// if (!mop.isRegister()) +// continue; + +// // mark start and end points +// if (mop.opIsDefOnly() || mop.opIsDefAndUse()) { +// Intervals::iterator li; +// unsigned reg = mop.getAllocatedRegNum(); +// assert(r2iMap.find(reg) == r2iMap.end() && +// "multiple definitions of virtual register"); +// // initialize intervals to [index, inf] +// _intervals.push_back( +// Interval(reg, +// index, +// std::numeric_limits::max())); +// r2iMap.insert(std::make_pair(reg, _intervals.size() - 1)); +// DEBUG(std::cerr << "\t\t\tadded interval for register " +// << _tri->getUnifiedRegName(reg) +// << ": " << _intervals.back() << '\n'); +// } +// } + +// for (LiveVariables::killed_iterator +// ki = _lv->killed_begin(instr), +// kiEnd = _lv->killed_end(instr); +// ki != kiEnd; ++ki) { +// unsigned reg = ki->second; +// DEBUG(std::cerr << "\t\t\tmarking end of interval for register " << _tri->getUnifiedRegName(reg) << '\n'); +// Reg2IntervalMap::iterator ri = r2iMap.find(reg); +// assert(ri != r2iMap.end() +// && "did not find interval for killed register"); +// Interval& interval = _intervals[ri->second]; +// assert(interval.end > index +// && "attempt to mark killed an already killed variable"); +// interval.end = index; +// } +// } + +// // kill all physical registers in the end of each basic block +// for (Intervals::iterator it = +// _intervals.begin(), itEnd = _intervals.end(); +// it != itEnd; ++it) { +// if (it->reg < MRegisterInfo::FirstVirtualRegister) { +// Reg2IntervalMap::iterator ri = r2iMap.find(it->reg); +// assert(ri != r2iMap.end() +// && "did not find interval for killed register"); +// Interval& interval = _intervals[ri->second]; +// assert(interval.end > index +// && "attempt to mark killed an already killed variable"); +// interval.end = index; +// } +// } +// } + +// // sort the live intervals in increasing start point +// sort(_intervals.begin(), _intervals.end(), StartPointComp()); + +// DEBUG( +// for(Intervals::iterator +// it = _intervals.begin(), itEnd = _intervals.end(); +// it != itEnd; ++it) { +// std::cerr << *it << '\n'; +// }); +} + +//// expireOldIntervals - expire the old intervals +//// +// void RA::expireOldIntervals(Intervals::iterator li) +// { +// // the active list is sorted on increasing end point +// IntervalPtrs::iterator lip = _active.begin(); +// for (IntervalPtrs::iterator lipEnd = _active.end(); +// lip != lipEnd && (*lip)->end < li->start; +// ++lip) { +// unsigned reg = li->reg; +// // if it is a virtual register +// if (reg >= MRegisterInfo::FirstVirtualRegister) { +// Virt2PhysMap::iterator it = _v2pMap.find(reg); +// assert(it != _v2pMap.end()); +// reg = it->second; +// _v2pMap.erase(it); +// } +// assert(_p2vMap[reg] != 0); +// _p2vMap[reg] = 0; +// } +// _active.erase(_active.begin(), lip); +// } + +//// spillAtInterval - chooses and spills a register for this +//// interval. The heuristic here is the register with the last end +//// point thus it can be either the last of the active list or the +//// current one +//// +// void RA::spillAtInterval(Intervals::iterator li) +// { +// assert(!_active.empty() && "active set cannot be empty when choosing a register to spill"); +// Interval* toSpill = _active.back(); +// // if last in active is ending after the current spill it and add +// // current to active +// if (toSpill->end > li->end) { +// // spill register toSpill->mop->getAllocatedRegNum(); +// _active.pop_back(); +// for(IntervalPtrs::iterator it = _active.begin(), itEnd = _active.end(); +// it != itEnd; ++it) { +// if ((*it)->end > li->end) { +// _active.insert(it, &*li); +// } +// } +// } +// // spill the current +// else { +// // spill register li->mop->getAllocatedRegNum() +// } +// } + +bool RA::physRegAvailable(unsigned physReg) +{ + if (_p2vMap[physReg]) { + return false; } - private: - /// runOnMachineFunction - Register allocate the whole function - bool runOnMachineFunction(MachineFunction &Fn); - }; + // if it aliases other registers it is still not free + for (const unsigned* as = _mri->getAliasSet(physReg); *as; ++as) { + if (_p2vMap[*as]) { + return false; + } + } + + return true; } -/// runOnMachineFunction - Register allocate the whole function -/// -bool RA::runOnMachineFunction(MachineFunction &Fn) { - DEBUG(std::cerr << "Machine Function " << "\n"); - MF = &Fn; - TM = &Fn.getTarget(); - RegInfo = TM->getRegisterInfo(); +unsigned RA::getFreeReg(unsigned virtReg) +{ + const TargetRegisterClass* rc = _mf->getSSARegMap()->getRegClass(virtReg); + TargetRegisterClass::iterator reg = rc->allocation_order_begin(*_mf); + TargetRegisterClass::iterator regEnd = rc->allocation_order_end(*_mf); + + for (; reg != regEnd; ++reg) { + if (physRegAvailable(*reg)) { + assert(*reg != 0 && "Cannot use register!"); + return *reg; // Found an unused register! + } + } + + return 0; +} - // compute live intervals - // liner scan algorithm +int RA::findOrCreateStackSlot(unsigned virtReg) +{ + // use lower_bound so that we can do a O(1) insert later if necessary + Virt2StackSlotMap::iterator it = _v2ssMap.lower_bound(virtReg); + if (it != _v2ssMap.end() && it->first == virtReg) { + return it->second; + } + const TargetRegisterClass* rc = _mf->getSSARegMap()->getRegClass(virtReg); + int frameIndex = _mf->getFrameInfo()->CreateStackObject(rc); + + _v2ssMap.insert(it, std::make_pair(virtReg, frameIndex)); + + return frameIndex; +} + +void RA::spillVirtReg(unsigned virtReg, unsigned physReg) +{ + const TargetRegisterClass* rc = _mf->getSSARegMap()->getRegClass(virtReg); + int frameIndex = findOrCreateStackSlot(virtReg); + ++numSpilled; + _mri->storeRegToStackSlot(*_currentMbb, _currentInstr, + physReg, frameIndex, rc); +} - return true; +void RA::loadPhysReg(unsigned physReg, unsigned virtReg) +{ + const TargetRegisterClass* rc = _mf->getSSARegMap()->getRegClass(virtReg); + int frameIndex = findOrCreateStackSlot(virtReg); + ++numReloaded; + _mri->loadRegFromStackSlot(*_currentMbb, _currentInstr, + physReg, frameIndex, rc); + _v2pMap[virtReg] = physReg; + _p2vMap[physReg] = virtReg; } FunctionPass *createLinearScanRegisterAllocator() { - return new RA(); + return new RA(); } From criswell at cs.uiuc.edu Fri Oct 24 08:25:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Oct 24 08:25:01 2003 Subject: [llvm-commits] [release_1] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200310241324.IAA28692@choi.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.11.2.1 -> 1.11.2.2 --- Log message: Merged in revision 1.12. --- Diffs of the changes: (+10 -3) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.11.2.1 llvm/docs/ReleaseNotes.html:1.11.2.2 --- llvm/docs/ReleaseNotes.html:1.11.2.1 Thu Oct 23 15:23:01 2003 +++ llvm/docs/ReleaseNotes.html Fri Oct 24 08:24:02 2003 @@ -64,7 +64,10 @@ The default optimizer sequence used by the C/C++ front-ends is:

          +
        1. CFG simplification (-simplifycfg)
        2. Interprocedural dead code elimination (-globaldce) +
        3. Interprocedural constant propagation (-ipconstprop) +
        4. Dead argument elimination (-deadargelim)
        5. Exception handling pruning (-prune-eh)
        6. Function inlining (-inline)
        7. Instruction combining (-instcombine) @@ -94,6 +97,7 @@
          1. Global constant merging (-constmerge)
          2. [optional] Internalization [which marks most functions and global variables static] (-internalize) +
          3. Interprocedural constant propagation (-ipconstprop)
          4. Interprocedural dead argument elimination (-deadargelim)
          5. Instruction combining (-instcombine)
          6. CFG simplification (-simplifycfg) @@ -103,7 +107,8 @@ At this time, LLVM is known to work properly with SPEC CPU 2000, the Olden benchmarks, and the Ptrdist benchmarks among many other programs. Note however that the Sparc and X86 backends do not currently support exception throwing or -long jumping. For these programs you must use the C backend.

            +long jumping (including 253.perlbmk in SPEC). For these programs you must use +the C backend.

            @@ -358,6 +363,10 @@

          7. Initializers for global variables cannot include special floating point numbers like Not-A-Number or Infinity.

            +

          8. Zero arg vararg functions are not +supported. This should not affect LLVM produced by the C or C++ +frontends.

            +

          9. The code produces by the C back-end has only been tested with the Sun CC and GCC compilers. It is possible that it will have to be adjusted to support other C compilers.

            @@ -389,8 +398,6 @@


            Maintained By: The LLVM Team
            -The LLVM Compiler Infrastructure -
            Last modified: Mon Oct 20 14:04:51 CDT 2003 From criswell at cs.uiuc.edu Fri Oct 24 08:29:00 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Oct 24 08:29:00 2003 Subject: [llvm-commits] [release_1] CVS: llvm/lib/Analysis/IPA/FindUsedTypes.cpp Message-ID: <200310241328.IAA28727@choi.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: FindUsedTypes.cpp updated: 1.20 -> 1.20.2.1 --- Log message: Merged revision 1.21. --- Diffs of the changes: (+11 -0) Index: llvm/lib/Analysis/IPA/FindUsedTypes.cpp diff -u llvm/lib/Analysis/IPA/FindUsedTypes.cpp:1.20 llvm/lib/Analysis/IPA/FindUsedTypes.cpp:1.20.2.1 --- llvm/lib/Analysis/IPA/FindUsedTypes.cpp:1.20 Mon Oct 20 14:43:08 2003 +++ llvm/lib/Analysis/IPA/FindUsedTypes.cpp Fri Oct 24 08:28:12 2003 @@ -41,12 +41,22 @@ IncorporateType(*I); } +void FindUsedTypes::IncorporateSymbolTable(const SymbolTable &ST) { + SymbolTable::const_iterator TI = ST.find(Type::TypeTy); + if (TI == ST.end()) return; // No named types + + for (SymbolTable::type_const_iterator I = TI->second.begin(), + E = TI->second.end(); I != E; ++I) + IncorporateType(cast(I->second)); +} // run - This incorporates all types used by the specified module // bool FindUsedTypes::run(Module &m) { UsedTypes.clear(); // reset if run multiple times... + IncorporateSymbolTable(m.getSymbolTable()); + // Loop over global variables, incorporating their types for (Module::const_giterator I = m.gbegin(), E = m.gend(); I != E; ++I) IncorporateType(I->getType()); @@ -54,6 +64,7 @@ for (Module::iterator MI = m.begin(), ME = m.end(); MI != ME; ++MI) { IncorporateType(MI->getType()); const Function &F = *MI; + IncorporateSymbolTable(F.getSymbolTable()); // Loop over all of the instructions in the function, adding their return // type as well as the types of their operands. From criswell at cs.uiuc.edu Fri Oct 24 08:43:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Oct 24 08:43:01 2003 Subject: [llvm-commits] [release_1] CVS: llvm/include/llvm/Analysis/FindUsedTypes.h Message-ID: <200310241342.IAA23048@choi.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: FindUsedTypes.h updated: 1.18 -> 1.18.2.1 --- Log message: Merged revision 1.19. --- Diffs of the changes: (+4 -0) Index: llvm/include/llvm/Analysis/FindUsedTypes.h diff -u llvm/include/llvm/Analysis/FindUsedTypes.h:1.18 llvm/include/llvm/Analysis/FindUsedTypes.h:1.18.2.1 --- llvm/include/llvm/Analysis/FindUsedTypes.h:1.18 Mon Oct 20 15:19:18 2003 +++ llvm/include/llvm/Analysis/FindUsedTypes.h Fri Oct 24 08:42:44 2003 @@ -39,6 +39,10 @@ /// void IncorporateType(const Type *Ty); + /// IncorporateSymbolTable - Include any named types. + /// + void IncorporateSymbolTable(const SymbolTable &ST); + public: /// run - This incorporates all types used by the specified module bool run(Module &M); From criswell at cs.uiuc.edu Fri Oct 24 09:26:05 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Oct 24 09:26:05 2003 Subject: [llvm-commits] [release_1] CVS: llvm/test/Makefile Message-ID: <200310241425.JAA28373@choi.cs.uiuc.edu> Changes in directory llvm/test: Makefile updated: 1.47 -> 1.47.2.1 --- Log message: Made QMTest run first to ensure that it runs. --- Diffs of the changes: (+6 -1) Index: llvm/test/Makefile diff -u llvm/test/Makefile:1.47 llvm/test/Makefile:1.47.2.1 --- llvm/test/Makefile:1.47 Thu Oct 23 09:11:53 2003 +++ llvm/test/Makefile Fri Oct 24 09:25:06 2003 @@ -1,11 +1,16 @@ LEVEL = .. DIRS = Programs -include Makefile.tests # # Make QMTest the default for testing features and regressions +# Do this first to force QMTest to run first # all:: qmtest + +# +# Include other test rules +# +include Makefile.tests # # New QMTest functionality: From criswell at cs.uiuc.edu Fri Oct 24 09:38:02 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Oct 24 09:38:02 2003 Subject: [llvm-commits] [release_1] CVS: llvm/README.txt Message-ID: <200310241437.JAA28421@choi.cs.uiuc.edu> Changes in directory llvm: README.txt updated: 1.3.2.3 -> 1.3.2.4 --- Log message: Added brief information on how to query filed bugs via BugZilla. Changed all tabs to spaces to ensure that nice LLVM look and feel. --- Diffs of the changes: (+39 -39) Index: llvm/README.txt diff -u llvm/README.txt:1.3.2.3 llvm/README.txt:1.3.2.4 --- llvm/README.txt:1.3.2.3 Thu Oct 23 22:02:32 2003 +++ llvm/README.txt Fri Oct 24 09:37:26 2003 @@ -14,21 +14,21 @@ ------------------------- (1) For license information: - llvm/LICENSE.txt + llvm/LICENSE.txt (2) Installing and compiling LLVM: - llvm/docs/GettingStarted.html + llvm/docs/GettingStarted.html (3) Learn about features and limitations of this release: - llvm/docs/ReleaseNotes.html + llvm/docs/ReleaseNotes.html (4) Learn how to write a pass within the LLVM system: - llvm/docs/WritingAnLLVMPass.html + llvm/docs/WritingAnLLVMPass.html (5) Learn how to start a new development project using LLVM, where your new source code can live anywhere (outside or inside the LLVM tree), while using LLVM header files and libraries: - llvm/docs/Projects.html + llvm/docs/Projects.html Getting Help with LLVM @@ -40,65 +40,65 @@ expect prompt first responses. (2) To report a bug, submit a bug report as described in the document: - http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html + http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html (3) We now use Bugzilla to track bugs, so you can check the status of previous bugs at: - + http://llvm.cs.uiuc.edu/bugs/query.cgi LLVM Documentation ------------------ All the documents mentioned below except the design overview tech report -are include as part of the LLVM release (in llvm/docs/*): +are included as part of the LLVM release (in llvm/docs/*): LLVM Design Overview: - LLVM : A Compilation Framework for Lifelong Program Analysis - and Transformation: - http://llvm.cs.uiuc.edu/pubs/2003-09-30-LifelongOptimizationTR.html + LLVM : A Compilation Framework for Lifelong Program Analysis + and Transformation: + http://llvm.cs.uiuc.edu/pubs/2003-09-30-LifelongOptimizationTR.html LLVM User Guides: - Download and Installation Instructions: - llvm/docs/GettingStarted.html + Download and Installation Instructions: + llvm/docs/GettingStarted.html - LLVM Command Guide: - llvm/docs/CommandGuide/CommandGuide.html + LLVM Command Guide: + llvm/docs/CommandGuide/CommandGuide.html - LLVM Assembly Language: - llvm/docs/LangRef.html + LLVM Assembly Language: + llvm/docs/LangRef.html - LLVM Test Suite Guide: - llvm/docs/TestingGuide.html + LLVM Test Suite Guide: + llvm/docs/TestingGuide.html LLVM Programming Documentation: - LLVM Programmers Manual: - llvm/docs/ProgrammersManual.html + LLVM Programmers Manual: + llvm/docs/ProgrammersManual.html - Writing an LLVM Pass: - llvm/docs/WritingAnLLVMPass.html + Writing an LLVM Pass: + llvm/docs/WritingAnLLVMPass.html - Alias Analysis in LLVM: - llvm/docs/AliasAnalysis.html + Alias Analysis in LLVM: + llvm/docs/AliasAnalysis.html - Command Line Library: - llvm/docs/CommandLine.html + Command Line Library: + llvm/docs/CommandLine.html - Coding Standards: - llvm/docs/CodingStandards.html + Coding Standards: + llvm/docs/CodingStandards.html Other LLVM Resources: - Submitting a Bug: - http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html + Submitting a Bug: + http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html - Open Projects: - llvm/docs/OpenProjects.html + Open Projects: + llvm/docs/OpenProjects.html - Creating a new LLVM Project: - llvm/docs/Projects.html + Creating a new LLVM Project: + llvm/docs/Projects.html Mailing Lists -------------- @@ -122,8 +122,8 @@ (3) LLVM Commits List http://mail.cs.uiuc.edu/mailman/listinfo/llvm-commits - This list contains all commit messages that are made when LLVM developers - commit code changes to the CVS archive. It is useful for those who want to - stay on the bleeding edge of LLVM development. This list is very high - volume. + This list contains all commit messages that are made when LLVM developers + commit code changes to the CVS archive. It is useful for those who want to + stay on the bleeding edge of LLVM development. This list is very high + volume. From criswell at cs.uiuc.edu Fri Oct 24 10:37:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Oct 24 10:37:01 2003 Subject: [llvm-commits] [release_1] CVS: llvm/docs/GettingStarted.html Message-ID: <200310241536.KAA28660@choi.cs.uiuc.edu> Changes in directory llvm/docs: GettingStarted.html updated: 1.41.2.3 -> 1.41.2.4 --- Log message: Removed the reference to llvm-request since the source code will be available for downloading. --- Diffs of the changes: (+1 -2) Index: llvm/docs/GettingStarted.html diff -u llvm/docs/GettingStarted.html:1.41.2.3 llvm/docs/GettingStarted.html:1.41.2.4 --- llvm/docs/GettingStarted.html:1.41.2.3 Thu Oct 23 17:15:14 2003 +++ llvm/docs/GettingStarted.html Fri Oct 24 10:36:38 2003 @@ -209,8 +209,7 @@ native code may not work on your platform.

            The GCC front end is not very portable at the moment. If you want to get - it to work on another platform, you can always request - a copy of the source + it to work on another platform, you can download a copy of the source and try to compile it on your platform.

            From criswell at cs.uiuc.edu Fri Oct 24 10:41:02 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Oct 24 10:41:02 2003 Subject: [llvm-commits] CVS: llvm-www/releases/1.0/cfrontend.sparc.tar.gz cfrontend.x86.tar.gz llvm.tar.gz Message-ID: <200310241540.KAA28744@choi.cs.uiuc.edu> Changes in directory llvm-www/releases/1.0: cfrontend.sparc.tar.gz updated: 1.2 -> 1.3 cfrontend.x86.tar.gz updated: 1.1 -> 1.2 llvm.tar.gz updated: 1.2 -> 1.3 --- Log message: Releease candidates 3, I think. Removed llvm-request from GCC front end since the source will be available. Updated docs and code in LLVM. --- Diffs of the changes: (+0 -0) Index: llvm-www/releases/1.0/cfrontend.sparc.tar.gz Index: llvm-www/releases/1.0/cfrontend.x86.tar.gz Index: llvm-www/releases/1.0/llvm.tar.gz From vadve at cs.uiuc.edu Fri Oct 24 10:42:00 2003 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Fri Oct 24 10:42:00 2003 Subject: [llvm-commits] CVS: llvm-www/www-index.html Message-ID: <200310241541.KAA16446@psmith.cs.uiuc.edu> Changes in directory llvm-www: www-index.html updated: 1.63 -> 1.64 --- Log message: Edited home page before release. Main changes are: funding, current projects, and updated the note about which overview document to read. --- Diffs of the changes: (+56 -40) Index: llvm-www/www-index.html diff -u llvm-www/www-index.html:1.63 llvm-www/www-index.html:1.64 --- llvm-www/www-index.html:1.63 Tue Oct 21 15:28:17 2003 +++ llvm-www/www-index.html Fri Oct 24 10:41:29 2003 @@ -32,13 +32,15 @@ program. LLVM supports effective optimization at compile time, link-time (particularly interprocedural), run-time and offline (i.e., after software is - installed), while maintaining compatibility with + installed), while remaining transparent to developers + and maintaining compatibility with existing build scripts.

          10. A virtual instruction set - LLVM is a low-level object code representation that uses simple RISC-like - instructions, but provides high-level type and dataflow + instructions, but provides rich (but + language-independent) type and dataflow (SSA) information about operands. This combination enables sophisticated transformations on object code, while remaining light-weight enough to be attached to @@ -163,8 +165,8 @@ We are working towards a public release of the LLVM - infrastructure, and hope to have a distribution available the - first week of October 2003. We expect to include a C front-end, beta + infrastructure, and hope to have a distribution available in + October 2003. We expect to include a C front-end, a C++ front-end, Sparc and X86 code generators (in both Static and JIT forms), and a mid-level optimizer in this release. This release will be covered under the Center for Circuits, Systems and - Software (C2S2).

            + href="http://www.gigascale.org/">Gigascale Systems Research + Center (GSRC).

            @@ -269,12 +271,12 @@ LLVM Design:

              -
            • - The LLVM Instruction Set and Compilation Strategy - - Describes the high level picture of the LLVM instruction - set and compilation system. This should be the first - document you read to get an overview of LLVM.
            • - +
            • + LLVM: A Compilation Framework for Lifelong Program + Analysis & Transformation: + - Describes the LLVM instruction set and compilation + strategy. This should be the first document you read to + get an overview of LLVM.
            • LLVM Reference Manual - Defines the LLVM intermediate representation, the assembly @@ -382,34 +384,48 @@ The LLVM infrastructure underlies many ongoing - research projects in our group. Here are some of - the projects currently active:
                -
              • Macroscopic data structure - analysis and transformations: - Analyzing and optimizing entire linked - data structures, including logical data - structure graphs, automatic pool - allocation for individual heap-based data - structures, and transparent pointer - compression.
              • -
              • Runtime optimization on - general-purpose processors: - Optimizing native code during - execution, using LLVM-to-native-code - mapping information.
              • -
              • SAFECode - project - : Language and - compiler support for ensuring memory - safety of embedded code through static - analysis.
              • -
              • Virtual Processor - Architectures: Using a - virtual instruction set (such as a - variant of LLVM) to hide hardware - processor architectures (or architectural - components) from user-level code.
              • -

              + research projects in our group. Some key additional + components of the system that are being developed in these + projects include: +

            • Automatic Pool Allocation:: + A fully automatic program transformation that introduces + region-based memory management in a novel manner: + it partitions the heap into separate regions for distinct + instances of logical data structures (such as a tree or + a hash table). This transformation can enable better + compiler-based memory management for program data structures. +
            • +
            • A Software Scheme for Online + Tracing: We have developed a tracing scheme that + identifies frequently executed program paths at runtime, + and optionally extracts these paths into a software-managed + trace cache. This technique uses an offline LLVM + transformation, plus a runtime instrumentation library + that currently only works for Sparc code. A key novel aspect + of our approach is that our scheme generates both native code + traces and the corresponding traces of LLVM code. +
            • +
            • Transparent runtime optimization on + general-purpose processors: + We are developing a transparent trace-based runtime + optimization system that operates on LLVM traces at runtime, + using the software tracing mechanism and trace cache above. +
            • + Other research projects in our group based on LLVM include: + +
            • SAFECode: + SAFECode is a compiler-based system for enforcing program + safety, which informally means that an untrusted code segment + or module will not corrupt the memory state of its host + process. SAFECode uses a type-safe subset of LLVM as its code + representation, and is able to enforce memory safety for a + type-safe C programs without requiring garbage + collection. +
            • +
            • Virtual Processor Architectures: + Using a virtual instruction set (such as a variant of LLVM) to + hide hardware processor architectures (or architectural + components) from user-level code.

            From vadve at cs.uiuc.edu Fri Oct 24 10:44:01 2003 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Fri Oct 24 10:44:01 2003 Subject: [llvm-commits] CVS: llvm-www/www-index.html Message-ID: <200310241543.KAA16471@psmith.cs.uiuc.edu> Changes in directory llvm-www: www-index.html updated: 1.64 -> 1.65 --- Log message: Shortened project descriptions and fixed formatting bug. --- Diffs of the changes: (+6 -14) Index: llvm-www/www-index.html diff -u llvm-www/www-index.html:1.64 llvm-www/www-index.html:1.65 --- llvm-www/www-index.html:1.64 Fri Oct 24 10:41:29 2003 +++ llvm-www/www-index.html Fri Oct 24 10:43:32 2003 @@ -392,18 +392,13 @@ region-based memory management in a novel manner: it partitions the heap into separate regions for distinct instances of logical data structures (such as a tree or - a hash table). This transformation can enable better - compiler-based memory management for program data structures. + a hash table).

          11. A Software Scheme for Online Tracing: We have developed a tracing scheme that identifies frequently executed program paths at runtime, and optionally extracts these paths into a software-managed - trace cache. This technique uses an offline LLVM - transformation, plus a runtime instrumentation library - that currently only works for Sparc code. A key novel aspect - of our approach is that our scheme generates both native code - traces and the corresponding traces of LLVM code. + trace cache. This currently only works for Sparc code.
          12. Transparent runtime optimization on general-purpose processors: @@ -411,17 +406,14 @@ optimization system that operates on LLVM traces at runtime, using the software tracing mechanism and trace cache above.
          13. + Other research projects in our group based on LLVM include:
          14. SAFECode: SAFECode is a compiler-based system for enforcing program - safety, which informally means that an untrusted code segment - or module will not corrupt the memory state of its host - process. SAFECode uses a type-safe subset of LLVM as its code - representation, and is able to enforce memory safety for a - type-safe C programs without requiring garbage - collection. -
          15. + safety. SAFECode uses a type-safe subset of LLVM as its code + representation. +
          16. Virtual Processor Architectures: Using a virtual instruction set (such as a variant of LLVM) to hide hardware processor architectures (or architectural From vadve at cs.uiuc.edu Fri Oct 24 10:45:07 2003 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Fri Oct 24 10:45:07 2003 Subject: [llvm-commits] CVS: llvm-www/www-index.html Message-ID: <200310241544.KAA16490@psmith.cs.uiuc.edu> Changes in directory llvm-www: www-index.html updated: 1.65 -> 1.66 --- Log message: *** empty log message *** --- Diffs of the changes: (+2 -0) Index: llvm-www/www-index.html diff -u llvm-www/www-index.html:1.65 llvm-www/www-index.html:1.66 --- llvm-www/www-index.html:1.65 Fri Oct 24 10:43:32 2003 +++ llvm-www/www-index.html Fri Oct 24 10:44:18 2003 @@ -407,6 +407,8 @@ using the software tracing mechanism and trace cache above.
          17. + + Other research projects in our group based on LLVM include:
          18. SAFECode: From vadve at cs.uiuc.edu Fri Oct 24 10:47:01 2003 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Fri Oct 24 10:47:01 2003 Subject: [llvm-commits] CVS: llvm-www/www-index.html Message-ID: <200310241546.KAA16513@psmith.cs.uiuc.edu> Changes in directory llvm-www: www-index.html updated: 1.66 -> 1.67 --- Log message: Still fixing formatting issues... --- Diffs of the changes: (+1 -1) Index: llvm-www/www-index.html diff -u llvm-www/www-index.html:1.66 llvm-www/www-index.html:1.67 --- llvm-www/www-index.html:1.66 Fri Oct 24 10:44:18 2003 +++ llvm-www/www-index.html Fri Oct 24 10:46:29 2003 @@ -409,8 +409,8 @@ - Other research projects in our group based on LLVM include: + Other research projects in our group based on LLVM include:
          19. SAFECode: SAFECode is a compiler-based system for enforcing program safety. SAFECode uses a type-safe subset of LLVM as its code From alkis at cs.uiuc.edu Fri Oct 24 10:50:02 2003 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri Oct 24 10:50:02 2003 Subject: [llvm-commits] [regalloc_linearscan] CVS: llvm/include/llvm/CodeGen/LiveIntervals.h Message-ID: <200310241549.KAA04506@morpheus.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: LiveIntervals.h updated: 1.1.2.1 -> 1.1.2.2 --- Log message: Added copyright and fix typo in comments. --- Diffs of the changes: (+9 -2) Index: llvm/include/llvm/CodeGen/LiveIntervals.h diff -u llvm/include/llvm/CodeGen/LiveIntervals.h:1.1.2.1 llvm/include/llvm/CodeGen/LiveIntervals.h:1.1.2.2 --- llvm/include/llvm/CodeGen/LiveIntervals.h:1.1.2.1 Fri Oct 24 01:06:46 2003 +++ llvm/include/llvm/CodeGen/LiveIntervals.h Fri Oct 24 10:49:24 2003 @@ -1,7 +1,14 @@ -//===-- llvm/CodeGen/LiveInterval.h - Live Interval Analysis ---*- C++ -*-===// +//===-- llvm/CodeGen/LiveInterval.h - Live Interval Analysis ----*- C++ -*-===// +// +// 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 LiveInterval analysis pass. Given some -// numbering of each the machine instructions (in this implemenation +// numbering of each the machine instructions (in this implemention // depth-first order) an interval [i, j] is said to be a live interval // for register v if there is no instruction with number j' > j such // that v is live at j' abd there is no instruction with number i' < i From alkis at cs.uiuc.edu Fri Oct 24 10:51:01 2003 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri Oct 24 10:51:01 2003 Subject: [llvm-commits] [regalloc_linearscan] CVS: llvm/lib/CodeGen/RegAllocLinearScan.cpp Message-ID: <200310241550.KAA04528@morpheus.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocLinearScan.cpp updated: 1.1.2.4 -> 1.1.2.5 --- Log message: Add copyright and make file compile. --- Diffs of the changes: (+8 -5) Index: llvm/lib/CodeGen/RegAllocLinearScan.cpp diff -u llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.1.2.4 llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.1.2.5 --- llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.1.2.4 Fri Oct 24 01:06:47 2003 +++ llvm/lib/CodeGen/RegAllocLinearScan.cpp Fri Oct 24 10:50:04 2003 @@ -1,9 +1,14 @@ -//===-- RegAllocLinearScan.cpp - Linear Scan register allocator ---------===// +//===-- RegAllocLinearScan.cpp - Linear Scan register allocator -----------===// +// +// 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 a linear scan register allocator. // -//===--------------------------------------------------------------------===// - +//===----------------------------------------------------------------------===// #define DEBUG_TYPE "regalloc" #include "llvm/Function.h" #include "llvm/CodeGen/LiveIntervals.h" @@ -55,7 +60,6 @@ } virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequiredID(PHIEliminationID); AU.addRequired(); MachineFunctionPass::getAnalysisUsage(AU); } @@ -109,7 +113,6 @@ _tri = &_tm->getRegInfo(); _mri = _tm->getRegisterInfo(); _li = &getAnalysis(); - _p2vMap.resize(_mri->getNumRegs()); _p2vMap.clear(); _v2pMap.clear(); _v2ssMap.clear(); From alkis at cs.uiuc.edu Fri Oct 24 10:58:01 2003 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri Oct 24 10:58:01 2003 Subject: [llvm-commits] [regalloc_linearscan] CVS: llvm/lib/CodeGen/RegAllocLinearScan.cpp LiveIntervals.cpp Message-ID: <200310241557.KAA04606@morpheus.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocLinearScan.cpp updated: 1.1.2.5 -> 1.1.2.6 LiveIntervals.cpp updated: 1.1.2.1 -> 1.1.2.2 --- Log message: Comment fixes. --- Diffs of the changes: (+7 -5) Index: llvm/lib/CodeGen/RegAllocLinearScan.cpp diff -u llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.1.2.5 llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.1.2.6 --- llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.1.2.5 Fri Oct 24 10:50:04 2003 +++ llvm/lib/CodeGen/RegAllocLinearScan.cpp Fri Oct 24 10:57:32 2003 @@ -5,7 +5,8 @@ // 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 a linear scan register allocator. // //===----------------------------------------------------------------------===// Index: llvm/lib/CodeGen/LiveIntervals.cpp diff -u llvm/lib/CodeGen/LiveIntervals.cpp:1.1.2.1 llvm/lib/CodeGen/LiveIntervals.cpp:1.1.2.2 --- llvm/lib/CodeGen/LiveIntervals.cpp:1.1.2.1 Fri Oct 24 01:06:47 2003 +++ llvm/lib/CodeGen/LiveIntervals.cpp Fri Oct 24 10:57:33 2003 @@ -1,11 +1,11 @@ -//===-- LiveIntervals.cpp - Linear Scan register allocator --------------===// +//===-- LiveIntervals.cpp - Live Interval Analysis ------------------------===// // // 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 LiveInterval analysis pass which is used // by the Linear Scan Register allocator. This pass linearizes the @@ -13,7 +13,7 @@ // LiveVariables pass to conservatively compute live intervals for // each virtual and physical register. // -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// #define DEBUG_TYPE "liveintervals" #include "llvm/CodeGen/LiveIntervals.h" @@ -43,8 +43,9 @@ void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); + AU.addPreserved(); AU.addRequired(); + AU.addRequiredID(PHIEliminationID); MachineFunctionPass::getAnalysisUsage(AU); } From lattner at cs.uiuc.edu Fri Oct 24 11:03:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Oct 24 11:03:01 2003 Subject: [llvm-commits] CVS: llvm/docs/CFEBuildInstrs.html Message-ID: <200310241602.LAA12185@zion.cs.uiuc.edu> Changes in directory llvm/docs: CFEBuildInstrs.html updated: 1.3 -> 1.4 --- Log message: Add note about multilibs. THis should go into the 1.0 release if possible --- Diffs of the changes: (+6 -1) Index: llvm/docs/CFEBuildInstrs.html diff -u llvm/docs/CFEBuildInstrs.html:1.3 llvm/docs/CFEBuildInstrs.html:1.4 --- llvm/docs/CFEBuildInstrs.html:1.3 Wed Oct 22 22:55:23 2003 +++ llvm/docs/CFEBuildInstrs.html Fri Oct 24 11:02:34 2003 @@ -105,6 +105,11 @@
          20. No inline assembly for position independent code. At the LLVM level, everything is position independent.
          21. We handle .init and .fini differently.
          22. +
          23. You may have to disable multilib support in your target. Using multilib + support causes the GCC compiler driver to add a lot of "-L" + options to the link line, which do not relate to LLVM and confuse + gccld. To disable multilibs, delete any + MULTILIB_OPTIONS lines from your target files.
          24. Did we mention that we don't support inline assembly? You'll probably have to add some fixinclude hacks to disable it in the system headers.
          25. @@ -149,7 +154,7 @@
            Brian Gaeke
            -Last modified: $Date: 2003/10/23 03:55:23 $ +Last modified: $Date: 2003/10/24 16:02:34 $
            From criswell at cs.uiuc.edu Fri Oct 24 11:20:03 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Oct 24 11:20:03 2003 Subject: [llvm-commits] [release_1] CVS: llvm/docs/index.html Message-ID: <200310241619.LAA28971@choi.cs.uiuc.edu> Changes in directory llvm/docs: index.html added (r1.1.2.1) --- Log message: HTML version of README.txt --- Diffs of the changes: (+242 -0) Index: llvm/docs/index.html diff -c /dev/null llvm/docs/index.html:1.1.2.1 *** /dev/null Fri Oct 24 11:19:21 2003 --- llvm/docs/index.html Fri Oct 24 11:19:11 2003 *************** *** 0 **** --- 1,242 ---- + + + The LLVM Compiler Infrastructure + + + + +
            +

            + The LLVM Compiler Infrastructure +
            + http://llvm.cs.uiuc.edu +

            +
            + +
            + +

            + Welcome to LLVM! +

            + This file is intended to do four things: +
              +
            1. + help you get started using LLVM; +
            2. + +
            3. + tell you how to get questions about LLVM answered; +
            4. + +
            5. + tell you where to find documentation for different kinds of questions; and +
            6. + +
            7. + tell you about three LLVM-related mailing lists. +
            8. +
            + + +
            + +

            + Getting Started with LLVM +

            + +
            +
            + For license information: +
            + llvm/LICENSE.txt + +
            + Installing and compiling LLVM: +
            + llvm/docs/GettingStarted.html + +
            + Learn about features and limitations of this release: +
            + llvm/docs/ReleaseNotes.html + +
            + Learn how to write a pass within the LLVM system: +
            + llvm/docs/WritingAnLLVMPass.html + +
            + Learn how to start a new development project using LLVM, where your +
            + new source code can live anywhere (outside or inside the LLVM tree), + while using LLVM header files and libraries: + llvm/docs/Projects.html +
            + +
            + +

            + Getting Help with LLVM +

            + +
              +
            1. + If you have questions or development problems not answered in the + documentation, send e-mail to llvmdev at cs.uiuc.edu. This mailing list is + monitored by all the people in the LLVM group at Illinois, and you should + expect prompt first responses. +
            2. + +
            3. + To report a bug, submit a bug report as described in the document: + http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html +
            4. + +
            5. + We now use Bugzilla to track bugs, so you can check the status of + previous bugs at: + + http://llvm.cs.uiuc.edu/bugs/query.cgi +
            6. +
            + +
            + +

            + LLVM Documentation +

            + + All the documents mentioned below except the design overview tech report + are included as part of the LLVM release (in llvm/docs/*): + +

            + LLVM Design Overview: +

            + +
            +
            + LLVM : A Compilation Framework for Lifelong Program Analysis + and Transformation: +
            + http://llvm.cs.uiuc.edu/pubs/2003-09-30-LifelongOptimizationTR.html + +
            + +

            + LLVM User Guides: +

            + +
            +
            + Download and Installation Instructions: +
            + llvm/docs/GettingStarted.html + +
            + LLVM Command Guide: +
            + llvm/docs/CommandGuide/CommandGuide.html + +
            + LLVM Assembly Language: +
            + llvm/docs/LangRef.html + +
            + LLVM Test Suite Guide: +
            + llvm/docs/TestingGuide.html +
            + +

            + LLVM Programming Documentation: +

            + +
            +
            + LLVM Programmers Manual: +
            + llvm/docs/ProgrammersManual.html + +
            + Writing an LLVM Pass: +
            + llvm/docs/WritingAnLLVMPass.html + +
            + Alias Analysis in LLVM: +
            + llvm/docs/AliasAnalysis.html + +
            + Command Line Library: +
            + llvm/docs/CommandLine.html + +
            + Coding Standards: +
            + llvm/docs/CodingStandards.html +
            + +

            + Other LLVM Resources: +

            + +
            +
            + Submitting a Bug: +
            + http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html + +
            + Open Projects: +
            + llvm/docs/OpenProjects.html + +
            + Creating a new LLVM Project: +
            + llvm/docs/Projects.html +
            + +
            + +

            + Mailing Lists +

            + There are three mailing lists for providing LLVM users with information: + +
              +
            1. LLVM Announcements List:
              + http://mail.cs.uiuc.edu/mailman/listinfo/llvm-announce + +

              + This is a low volume list that provides important announcements regarding + LLVM. It is primarily intended to announce new releases, major updates to + the software, etc. This list is highly recommended for anyone that uses + LLVM. +

              + +
            2. LLVM Developers List:
              + http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev + +

              + This list is for people who want to be included in technical discussions + of LLVM. People post to this list when they have questions about writing + code for or using the LLVM tools. It is relatively low volume. +

              + +
            3. LLVM Commits List
              + http://mail.cs.uiuc.edu/mailman/listinfo/llvm-commits + +

              + This list contains all commit messages that are made when LLVM developers + commit code changes to the CVS archive. It is useful for those who want to + stay on the bleeding edge of LLVM development. This list is very high + volume. +

              +
            + + + From brukman at cs.uiuc.edu Fri Oct 24 11:26:03 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Oct 24 11:26:03 2003 Subject: [llvm-commits] CVS: llvm-www/releases/1.0/announcement.txt Message-ID: <200310241625.LAA17279@zion.cs.uiuc.edu> Changes in directory llvm-www/releases/1.0: announcement.txt updated: 1.2 -> 1.3 --- Log message: According to Vikram, CAML is actually distinct from O'Caml. --- Diffs of the changes: (+1 -1) Index: llvm-www/releases/1.0/announcement.txt diff -u llvm-www/releases/1.0/announcement.txt:1.2 llvm-www/releases/1.0/announcement.txt:1.3 --- llvm-www/releases/1.0/announcement.txt:1.2 Fri Oct 24 00:38:10 2003 +++ llvm-www/releases/1.0/announcement.txt Fri Oct 24 11:25:14 2003 @@ -10,7 +10,7 @@ languages. LLVM is written in C++ and has been developed over the past 3 years at the University of Illinois. It currently supports compilation of C and C++ programs, using front-ends derived from GCC 3.4. New front-ends - are being written for Java bytecode and O'Caml. + are being written for Java bytecode and CAML. WHOM MIGHT THIS RELEASE BE USEFUL? o Compiler researchers interested in compile-time, link-time From lattner at cs.uiuc.edu Fri Oct 24 11:39:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Oct 24 11:39:01 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/Makefile.programs Message-ID: <200310241638.LAA18089@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs: Makefile.programs updated: 1.97 -> 1.98 --- Log message: Clean up ALL report files --- Diffs of the changes: (+1 -1) Index: llvm/test/Programs/Makefile.programs diff -u llvm/test/Programs/Makefile.programs:1.97 llvm/test/Programs/Makefile.programs:1.98 --- llvm/test/Programs/Makefile.programs:1.97 Sun Oct 19 16:44:15 2003 +++ llvm/test/Programs/Makefile.programs Fri Oct 24 11:38:34 2003 @@ -477,4 +477,4 @@ endif clean:: - rm -f report.*.raw.out report.*.txt + rm -f report.*.raw.out report.*.txt report.*.html report.*.tex From criswell at cs.uiuc.edu Fri Oct 24 11:50:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Oct 24 11:50:01 2003 Subject: [llvm-commits] [release_1] CVS: llvm/docs/index.html Message-ID: <200310241649.LAA29072@choi.cs.uiuc.edu> Changes in directory llvm/docs: index.html updated: 1.1.2.1 -> 1.1.2.2 --- Log message: Fixed the name of the Command Guide index. Made everything into hyperlinks. --- Diffs of the changes: (+49 -26) Index: llvm/docs/index.html diff -u llvm/docs/index.html:1.1.2.1 llvm/docs/index.html:1.1.2.2 --- llvm/docs/index.html:1.1.2.1 Fri Oct 24 11:19:11 2003 +++ llvm/docs/index.html Fri Oct 24 11:49:29 2003 @@ -48,29 +48,33 @@
            For license information:
            - llvm/LICENSE.txt + llvm/LICENSE.TXT +

            Installing and compiling LLVM:
            - llvm/docs/GettingStarted.html + llvm/docs/GettingStarted.html +

            Learn about features and limitations of this release:
            - llvm/docs/ReleaseNotes.html + llvm/docs/ReleaseNotes.html +

            Learn how to write a pass within the LLVM system:
            - llvm/docs/WritingAnLLVMPass.html + llvm/docs/WritingAnLLVMPass.html +

            Learn how to start a new development project using LLVM, where your + new source code can live anywhere (outside or inside the LLVM tree), + while using LLVM header files and libraries:
            - new source code can live anywhere (outside or inside the LLVM tree), - while using LLVM header files and libraries: - llvm/docs/Projects.html + llvm/docs/Projects.html
            @@ -83,13 +87,14 @@
          26. If you have questions or development problems not answered in the documentation, send e-mail to llvmdev at cs.uiuc.edu. This mailing list is - monitored by all the people in the LLVM group at Illinois, and you should - expect prompt first responses. + monitored by all the people in the LLVM group at Illinois, and you + should expect prompt first responses.
          27. To report a bug, submit a bug report as described in the document: - http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html + + http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html
          28. @@ -118,7 +123,8 @@ LLVM : A Compilation Framework for Lifelong Program Analysis and Transformation:
            - http://llvm.cs.uiuc.edu/pubs/2003-09-30-LifelongOptimizationTR.html + + http://llvm.cs.uiuc.edu/pubs/2003-09-30-LifelongOptimizationTR.html @@ -130,22 +136,27 @@
            Download and Installation Instructions:
            - llvm/docs/GettingStarted.html + llvm/docs/GettingStarted.html +

            LLVM Command Guide:
            - llvm/docs/CommandGuide/CommandGuide.html + + llvm/docs/CommandGuide/index.html +

            LLVM Assembly Language:
            - llvm/docs/LangRef.html + llvm/docs/LangRef.html +

            LLVM Test Suite Guide:
            - llvm/docs/TestingGuide.html + llvm/docs/TestingGuide.html +

            @@ -156,27 +167,32 @@
            LLVM Programmers Manual:
            - llvm/docs/ProgrammersManual.html + llvm/docs/ProgrammersManual.html +

            Writing an LLVM Pass:
            - llvm/docs/WritingAnLLVMPass.html + llvm/docs/WritingAnLLVMPass.html +

            Alias Analysis in LLVM:
            - llvm/docs/AliasAnalysis.html + llvm/docs/AliasAnalysis.html +

            Command Line Library:
            - llvm/docs/CommandLine.html + llvm/docs/CommandLine.html +

            Coding Standards:
            - llvm/docs/CodingStandards.html + llvm/docs/CodingStandards.html +

            @@ -187,17 +203,21 @@
            Submitting a Bug:
            - http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html + + http://llvm.cs.uiuc.edu/docs/HowToSubmitABug.html +

            Open Projects:
            - llvm/docs/OpenProjects.html + llvm/docs/OpenProjects.html +

            Creating a new LLVM Project:
            - llvm/docs/Projects.html + llvm/docs/Projects.html +


            @@ -209,7 +229,8 @@
            1. LLVM Announcements List:
              - http://mail.cs.uiuc.edu/mailman/listinfo/llvm-announce + + http://mail.cs.uiuc.edu/mailman/listinfo/llvm-announce

              This is a low volume list that provides important announcements regarding @@ -219,7 +240,8 @@

            2. LLVM Developers List:
              - http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev + + http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev

              This list is for people who want to be included in technical discussions @@ -228,7 +250,8 @@

            3. LLVM Commits List
              - http://mail.cs.uiuc.edu/mailman/listinfo/llvm-commits + + http://mail.cs.uiuc.edu/mailman/listinfo/llvm-commits

              This list contains all commit messages that are made when LLVM developers From criswell at cs.uiuc.edu Fri Oct 24 11:50:16 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Oct 24 11:50:16 2003 Subject: [llvm-commits] [release_1] CVS: llvm/README.txt Message-ID: <200310241649.LAA29086@choi.cs.uiuc.edu> Changes in directory llvm: README.txt updated: 1.3.2.4 -> 1.3.2.5 --- Log message: Fixed the name of the Command Guide index. --- Diffs of the changes: (+1 -1) Index: llvm/README.txt diff -u llvm/README.txt:1.3.2.4 llvm/README.txt:1.3.2.5 --- llvm/README.txt:1.3.2.4 Fri Oct 24 09:37:26 2003 +++ llvm/README.txt Fri Oct 24 11:49:42 2003 @@ -64,7 +64,7 @@ llvm/docs/GettingStarted.html LLVM Command Guide: - llvm/docs/CommandGuide/CommandGuide.html + llvm/docs/CommandGuide/index.html LLVM Assembly Language: llvm/docs/LangRef.html From brukman at cs.uiuc.edu Fri Oct 24 12:36:02 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Oct 24 12:36:02 2003 Subject: [llvm-commits] CVS: llvm/docs/llvm.css Message-ID: <200310241735.MAA09162@zion.cs.uiuc.edu> Changes in directory llvm/docs: llvm.css updated: 1.1 -> 1.2 --- Log message: * Made into valid CSS that W3C accepts * Added document subsubsection styles for usage in documentation --- Diffs of the changes: (+19 -4) Index: llvm/docs/llvm.css diff -u llvm/docs/llvm.css:1.1 llvm/docs/llvm.css:1.2 --- llvm/docs/llvm.css:1.1 Wed Oct 22 18:23:49 2003 +++ llvm/docs/llvm.css Fri Oct 24 12:34:50 2003 @@ -3,7 +3,7 @@ */ /* Common styles */ -.body { text: black; background: white; margin: 0 0 0 0 } +.body { color: black; background: white; margin: 0 0 0 0 } /* * Documentation @@ -16,12 +16,27 @@ } .doc_title { text-align: left; font-size: 25pt } -.doc_section { text-align: center; font-size: 22pt } +.doc_section { text-align: center; font-size: 22pt; } .doc_subsection { background: #441188; width: 50%; - text-align: left; font-size: 12pt; padding: 4 4 4 22 } + text-align: left; font-size: 12pt; padding: 4pt 4pt 4pt 4pt; + margin: 1.5em 0.5em 1.5em 0.5em } + +/* In the future, the 2nd level subsection style may want to become this: +.doc_subsubsection { margin: 1.5em 0.5em 1.5 0.5em; + font-weight: bold; font-style: oblique; + border-bottom: 2px dotted #999999 } +*/ + +/* However, to be consistent with the rest of current documentation which is not + all yet using stylesheets, we try to emulate the former layout. */ +.doc_subsubsection { margin: 1.5em 0.5em 1.5em 0.5em; + font-weight: bold; + border-top: 2px solid #cecece } + .doc_text { text-align: left; padding-left: 20pt } /* Publications */ -.pub_title { font-family: "Georgia,Palatino,Times,Roman"; font-size: 24pt; +.pub_title { font-family: "Georgia,Palatino,Times,Roman"; + font-size: 24pt; text-align: center } .pub_author { font-size: 14pt; text-align: center } From criswell at cs.uiuc.edu Fri Oct 24 12:44:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Oct 24 12:44:01 2003 Subject: [llvm-commits] CVS: llvm-www/releases/1.0/cfrontend.sparc.tar.gz llvm.tar.gz Message-ID: <200310241743.MAA29313@choi.cs.uiuc.edu> Changes in directory llvm-www/releases/1.0: cfrontend.sparc.tar.gz updated: 1.3 -> 1.4 llvm.tar.gz updated: 1.3 -> 1.4 --- Log message: Updated LLVM with new documentation. Updated GCC front end for Sparc with new fix. --- Diffs of the changes: (+0 -0) Index: llvm-www/releases/1.0/cfrontend.sparc.tar.gz Index: llvm-www/releases/1.0/llvm.tar.gz From criswell at cs.uiuc.edu Fri Oct 24 12:49:02 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Oct 24 12:49:02 2003 Subject: [llvm-commits] CVS: llvm-www/releases/1.0/cfrontend-src.tar.gz Message-ID: <200310241748.MAA29394@choi.cs.uiuc.edu> Changes in directory llvm-www/releases/1.0: cfrontend-src.tar.gz updated: 1.1 -> 1.2 --- Log message: Updated the source for the GCC Sparc fix. --- Diffs of the changes: (+0 -0) Index: llvm-www/releases/1.0/cfrontend-src.tar.gz From brukman at cs.uiuc.edu Fri Oct 24 12:57:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Oct 24 12:57:01 2003 Subject: [llvm-commits] CVS: llvm/docs/llvm.css Message-ID: <200310241756.MAA14241@zion.cs.uiuc.edu> Changes in directory llvm/docs: llvm.css updated: 1.2 -> 1.3 --- Log message: Add a style for document footers. --- Diffs of the changes: (+3 -1) Index: llvm/docs/llvm.css diff -u llvm/docs/llvm.css:1.2 llvm/docs/llvm.css:1.3 --- llvm/docs/llvm.css:1.2 Fri Oct 24 12:34:50 2003 +++ llvm/docs/llvm.css Fri Oct 24 12:56:09 2003 @@ -33,7 +33,9 @@ font-weight: bold; border-top: 2px solid #cecece } -.doc_text { text-align: left; padding-left: 20pt } +.doc_text { text-align: left; padding-left: 20pt } + +.doc_footer { text-align: left; padding: 0 0 0 0; font-size 12pt } /* Publications */ .pub_title { font-family: "Georgia,Palatino,Times,Roman"; From brukman at cs.uiuc.edu Fri Oct 24 12:58:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Oct 24 12:58:01 2003 Subject: [llvm-commits] CVS: llvm/docs/CodingStandards.html Message-ID: <200310241757.MAA18970@zion.cs.uiuc.edu> Changes in directory llvm/docs: CodingStandards.html updated: 1.12 -> 1.13 --- Log message: * Use HTML 4.01 Strict DTD * Stop using UTF-8, the webserver sends out iso-8859-1 anyway * Use style sheets and

              s instead of tags * Stop using

          29. Style Issues
            1. The High Level Issues
                -
              1. A Public Header File is a Module -
              2. #include as Little as Possible -
              3. Keep "internal" Headers Private -
              +
            2. A Public Header File is a + Module
            3. +
            4. #include as Little as Possible
            5. +
            6. Keep "internal" Headers + Private
            7. +
          30. The Low Level Issues
              -
            1. Assert Liberally -
            2. Prefer Preincrement -
            3. Avoid endl -
            4. Exploit C++ to its Fullest -
            -
          31. Writing Iterators -
          -
        8. See Also -

        +

      10. Assert Liberally
      11. +
      12. Prefer Preincrement
      13. +
      14. Avoid endl
      15. +
      16. Exploit C++ to its Fullest
      17. +
    8. +
    9. Writing Iterators
    10. +
  • +
  • See Also
  • + -
    -Introduction -
    -Mechanical Source Issues -
       -Source Code Formatting -


    Commenting

      + -Comments are one critical part of readability and maintainability. Everyone +
      + +

      Comments are one critical part of readability and maintainability. Everyone knows they should comment, so should you. :) Although we all should probably comment our code more than we do, there are a few very critical places that -documentation is very useful:

      +documentation is very useful:

        -

      1. File Headers
      2. -Every source file should have a header on it that describes the basic purpose of -the file. If a file does not have a header, it should not be checked into CVS. -Most source trees will probably have a standard file header format. The -standard format for the LLVM source tree looks like this:

        +

      3. File Headers

        + +

        Every source file should have a header on it that +describes the basic purpose of the file. If a file does not have a header, it +should not be checked into CVS. Most source trees will probably have a standard +file header format. The standard format for the LLVM source tree looks like +this:

         //===-- llvm/Instruction.h - Instruction class definition -------*- C++ -*-===//
        @@ -109,399 +130,487 @@
         //===----------------------------------------------------------------------===//
         
        -A few things to note about this particular format. The "-*- C++ -*-" -string on the first line is there to tell Emacs that the source file is a C++ -file, not a C file (Emacs assumes .h files are C files by default [Note that tag -this is not necessary in .cpp files]). The name of the file is also on the -first line, along with a very short description of the purpose of the file. -This is important when printing out code and flipping though lots of pages.

        +

        A few things to note about this particular format. The "-*- C++ +-*-" string on the first line is there to tell Emacs that the source file +is a C++ file, not a C file (Emacs assumes .h files are C files by default [Note +that tag this is not necessary in .cpp files]). The name of the file is also on +the first line, along with a very short description of the purpose of the file. +This is important when printing out code and flipping though lots of pages.

        -The main body of the description does not have to be very long in most cases. +

        The main body of the description does not have to be very long in most cases. Here it's only two lines. If an algorithm is being implemented or something tricky is going on, a reference to the paper where it is published should be -included, as well as any notes or "gotchas" in the code to watch out for.

        +included, as well as any notes or "gotchas" in the code to watch out for.

        +
      4. -

      5. Class overviews
      6. +
      7. Class overviews

        -Classes are one fundemental part of a good object oriented design. As such, a -class definition should have a comment block that explains what the class is +

        Classes are one fundemental part of a good object oriented design. As such, +a class definition should have a comment block that explains what the class is used for... if it's not obvious. If it's so completely obvious your grandma could figure it out, it's probably safe to leave it out. Naming classes -something sane goes a long ways towards avoiding writing documentation. :)

        +something sane goes a long ways towards avoiding writing documentation. :)

        +
      8. -

      9. Method information
      10. +
      11. Method information

        -Methods defined in a class (as well as any global functions) should also be +

        Methods defined in a class (as well as any global functions) should also be documented properly. A quick note about what it does any a description of the borderline behaviour is all that is necessary here (unless something particularly tricky or insideous is going on). The hope is that people can figure out how to use your interfaces without reading the code itself... that is -the goal metric.

        +the goal metric.

        + +

        Good things to talk about here are what happens when something unexpected +happens: does the method return null? Abort? Format your hard disk?

        -Good things to talk about here are what happens when something unexpected -happens: does the method return null? Abort? Format your hard disk?

        +

      +
      -


    Comment Formatting

      + -In general, prefer C++ style (//) comments. They take less space, +
      + +

      In general, prefer C++ style (//) comments. They take less space, require less typing, don't have nesting problems, etc. There are a few cases -when it is useful to use C style (/* */) comments however:

      +when it is useful to use C style (/* */) comments however:

        -
      1. When writing a C code: Obviously if you are writing C code, use C style -comments. :) -
      2. When writing a header file that may be #included by a C source file. -
      3. When writing a source file that is used by a tool that only accepts C style -comments. -

      +

    • When writing a C code: Obviously if you are writing C code, use C style + comments. :)
    • +
    • When writing a header file that may be #included by a C source file.
    • +
    • When writing a source file that is used by a tool that only accepts C + style comments.
    • + -To comment out a large block of code, use #if 0 and #endif. -These nest properly and are better behaved in general than C style comments.

      +

      To comment out a large block of code, use #if 0 and #endif. +These nest properly and are better behaved in general than C style comments.

      + +
      -


    #include Style


    Source Code Width

      + + +
      -Write your code to fit within 80 columns of text. This helps those of us who like to print out code and look at your code in an xterm without resizing it. +

      Write your code to fit within 80 columns of text. This helps those of us who +like to print out code and look at your code in an xterm without resizing +it.

      +
      -


    Use Spaces Instead of Tabs

      + -In all cases, prefer spaces to tabs in source files. People have different +
      + +

      In all cases, prefer spaces to tabs in source files. People have different prefered indentation levels, and different styles of indentation that they like... this is fine. What isn't is that different editors/viewers expand tabs out to different tab stops. This can cause your code to look completely -unreadable, and it is not worth dealing with.

      +unreadable, and it is not worth dealing with.

      -As always, follow the Golden Rule above: follow the +

      As always, follow the Golden Rule above: follow the style of existing code if your are modifying and extending it. If you like four spaces of indentation, DO NOT do that in the middle of a chunk of code with two spaces of indentation. Also, do not reindent a whole source file: it -makes for incredible diffs that are absolutely worthless.

      +makes for incredible diffs that are absolutely worthless.

      +
      -


    Indent Code Consistently

      + -Okay, your first year of programming you were told that indentation is -important. If you didn't believe and internalize this then, now is the time. -Just do it.

      +

      +

      Okay, your first year of programming you were told that indentation is +important. If you didn't believe and internalize this then, now is the time. +Just do it.

      +
      -
       -Compiler Issues -


    Treat Compiler Warnings Like Errors

      + -If your code has compiler warnings in it, something is wrong: you aren't casting -values correctly, your have "questionable" constructs in your code, or you are -doing something legitimately wrong. Compiler warnings can cover up legitimate -errors in output and make dealing with a translation unit difficult.

      +

      -It is not possible to prevent all warnings from all compilers, nor is it +

      If your code has compiler warnings in it, something is wrong: you aren't +casting values correctly, your have "questionable" constructs in your code, or +you are doing something legitimately wrong. Compiler warnings can cover up +legitimate errors in output and make dealing with a translation unit +difficult.

      + +

      It is not possible to prevent all warnings from all compilers, nor is it desirable. Instead, pick a standard compiler (like gcc) that provides a good thorough set of warnings, and stick to them. At least in the case of gcc, it is possible to work around any spurious errors by changing the syntax of the code slightly. For example, an warning that annoys me occurs when -I write code like this:

      +I write code like this:

         if (V = getValue()) {
           ..
         }
      -

      + -gcc will warn me that I probably want to use the == operator, -and that I probably mistyped it. In most cases, I haven't, and I really don't -want the spurious errors. To fix this particular problem, I rewrite the code -like this:

      +

      gcc will warn me that I probably want to use the == +operator, and that I probably mistyped it. In most cases, I haven't, and I +really don't want the spurious errors. To fix this particular problem, I +rewrite the code like this:

         if ((V = getValue())) {
           ..
         }
      -

      + -...which shuts gcc up. Any gcc warning that annoys you can be -fixed by massaging the code appropriately.

      +

      ...which shuts gcc up. Any gcc warning that annoys you can +be fixed by massaging the code appropriately.

      -These are the gcc warnings that I prefer to enable: -Wall -Winline --W -Wwrite-strings -Wno-unused

      +

      These are the gcc warnings that I prefer to enable: -Wall +-Winline -W -Wwrite-strings -Wno-unused

      +
      -


    Which C++ features can I use?

      + -Compilers are finally catching up to the C++ standard. Most compilers implement -most features, so you can use just about any features that you would like. In -the LLVM source tree, I have chosen to not use these features:

      +

      + +

      Compilers are finally catching up to the C++ standard. Most compilers +implement most features, so you can use just about any features that you would +like. In the LLVM source tree, I have chosen to not use these features:

        -
      1. Exceptions: Exceptions are very useful for error reporting and handling +
      2. Exceptions: Exceptions are very useful for error reporting and handling exceptional conditions. I do not use them in LLVM because they do have an associated performance impact (by restricting restructuring of code), and parts -of LLVM are designed for performance critical purposes.

        +of LLVM are designed for performance critical purposes.

        -Just like most of the rules in this document, this isn't a hard and fast +

        Just like most of the rules in this document, this isn't a hard and fast requirement. Exceptions are used in the Parser, because it simplifies error reporting significantly, and the LLVM parser is not at all in the -critical path.

        +critical path.

        +
      3. RTTI: RTTI has a large cost in terms of executable size, and compilers are not yet very good at stomping out "dead" class information blocks. Because of -this, typeinfo and dynamic cast are not used. -

      +this, typeinfo and dynamic cast are not used. + -Other features, such as templates (without partial specialization) can be used -freely. The general goal is to have clear, consise, performant code... if a -technique assists with that then use it.

      +

      Other features, such as templates (without partial specialization) can be +used freely. The general goal is to have clear, consise, performant code... if +a technique assists with that then use it.

      +
      -


    Write Portable Code

      + -In almost all cases, it is possible and within reason to write completely -portable code. If there are cases where it isn't possible to write portable -code, isolate it behind a well defined (and well documented) interface.

      +

      -In practice, this means that you shouldn't assume much about the host compiler, -including its support for "high tech" features like partial specialization of -templates. In fact, Visual C++ 6 could be an important target for our work in -the future, and we don't want to have to rewrite all of our code to support -it.

      +

      In almost all cases, it is possible and within reason to write completely +portable code. If there are cases where it isn't possible to write portable +code, isolate it behind a well defined (and well documented) interface.

      +

      In practice, this means that you shouldn't assume much about the host +compiler, including its support for "high tech" features like partial +specialization of templates. In fact, Visual C++ 6 could be an important target +for our work in the future, and we don't want to have to rewrite all of our code +to support it.

      +
      -
    -Style Issues -
       -The High Level Issues -


    A Public Header File is a Module

      + + +
      -C++ doesn't do too well in the modularity department. There is no real +

      C++ doesn't do too well in the modularity department. There is no real encapsulation or data hiding (unless you use expensive protocol classes), but it is what we have to work with. When you write a public header file (in the LLVM source tree, they live in the top level "include" directory), you are defining a -module of functionality.

      +module of functionality.

      -Ideally, modules should be completely independent of each other, and their +

      Ideally, modules should be completely independent of each other, and their header files should only include the absolute minimum number of headers possible. A module is not just a class, a function, or a namespace: it's a collection of these that defines an interface. This interface may be several functions, classes or data structures, but the important issue is how they work -together.

      +together.

      -In general, a module should be implemented with one or more .cpp files. -Each of these .cpp files should include the header that defines their -interface first. This ensure that all of the dependences of the module header -have been properly added to the module header itself, and are not implicit. -System headers should be included after user headers for a translation unit.

      +

      In general, a module should be implemented with one or more .cpp +files. Each of these .cpp files should include the header that defines +their interface first. This ensure that all of the dependences of the module +header have been properly added to the module header itself, and are not +implicit. System headers should be included after user headers for a +translation unit.

      +
      -


    #include as Little as Possible

      + -#include hurts compile time performance. Don't do it unless you have -to, especially in header files.

      +

      -But wait, sometimes you need to have the definition of a class to use it, or to -inherit from it. In these cases go ahead and #include that header file. Be +

      #include hurts compile time performance. Don't do it unless you +have to, especially in header files.

      + +

      But wait, sometimes you need to have the definition of a class to use it, or +to inherit from it. In these cases go ahead and #include that header file. Be aware however that there are many cases where you don't need to have the full definition of a class. If you are using a pointer or reference to a class, you don't need the header file. If you are simply returning a class instance from a prototyped function or method, you don't need it. In fact, for most cases, you simply don't need the definition of a class... and not #include'ing -speeds up compilation.

      +speeds up compilation.

      -It is easy to try to go too overboard on this recommendation, however. You +

      It is easy to try to go too overboard on this recommendation, however. You must include all of the header files that you are using, either directly or indirectly (through another header file). To make sure that you don't accidently forget to include a header file in your module header, make sure to include your module header first in the implementation file (as mentioned above). This way there won't be any hidden dependencies that you'll find out -about later...

      +about later...

      +
      -


    Keep "internal" Headers Private

      + + +
      -Many modules have a complex implementation that causes them to use more than one -implementation (.cpp) file. It is often tempting to put the internal -communication interface (helper classes, extra functions, etc) in the public -module header file. Don't do this. :)

      +

      Many modules have a complex implementation that causes them to use more than +one implementation (.cpp) file. It is often tempting to put the +internal communication interface (helper classes, extra functions, etc) in the +public module header file. Don't do this. :)

      -If you really need to do something like this, put a private header file in the -same directory as the source files, and include it locally. This ensures that -your private interface remains private and undisturbed by outsiders.

      +

      If you really need to do something like this, put a private header file in +the same directory as the source files, and include it locally. This ensures +that your private interface remains private and undisturbed by outsiders.

      -Note however, that it's okay to put extra implementation methods a public class -itself... just make them private (or protected), and all is well.

      +

      Note however, that it's okay to put extra implementation methods a public +class itself... just make them private (or protected), and all is well.

      +
      -
       -The Low Level Issues -


    Assert Liberally

      + + +
      -Use the "assert" function to its fullest. Check all of your +

      Use the "assert" function to its fullest. Check all of your preconditions and assumptions, you never know when a bug (not neccesarily even yours) might be caught early by an assertion, which reduces debugging time dramatically. The "<cassert>" header file is probably already included by the header files you are using, so it doesn't cost anything to use -it.

      +it.

      -To further assist with debugging, make sure to put some kind of error message in -the assertion statement (which is printed if the assertion is tripped). This +

      To further assist with debugging, make sure to put some kind of error message +in the assertion statement (which is printed if the assertion is tripped). This helps the poor debugging make sense of why an assertion is being made and -enforced, and hopefully what to do about it. Here is one complete example:

      +enforced, and hopefully what to do about it. Here is one complete example:

         inline Value *getOperand(unsigned i) { 
      -    assert(i < Operands.size() && "getOperand() out of range!");
      +    assert(i < Operands.size() && "getOperand() out of range!");
           return Operands[i]; 
         }
       
      -Here are some examples: +

      Here are some examples:

      -  assert(Ty->isPointerType() && "Can't allocate a non pointer type!");
      +  assert(Ty->isPointerType() && "Can't allocate a non pointer type!");
       
      -  assert((Opcode == Shl || Opcode == Shr) && "ShiftInst Opcode invalid!");
      +  assert((Opcode == Shl || Opcode == Shr) && "ShiftInst Opcode invalid!");
       
      -  assert(idx < getNumSuccessors() && "Successor # out of range!");
      +  assert(idx < getNumSuccessors() && "Successor # out of range!");
       
      -  assert(V1.getType() == V2.getType() && "Constant types must be identical!");
      +  assert(V1.getType() == V2.getType() && "Constant types must be identical!");
       
      -  assert(isa<PHINode>(Succ->front()) && "Only works on PHId BBs!");
      -

      + assert(isa<PHINode>(Succ->front()) && "Only works on PHId BBs!"); + + +

      You get the idea...

      -You get the idea...

      +

      -


    Prefer Preincrement

      + + +
      -Hard fast rule: Preincrement (++X) may be no slower than postincrement (X++) and -could very well be a lot faster than it. Use preincrementation whenever -possible.

      +

      Hard fast rule: Preincrement (++X) may be no slower than postincrement (X++) +and could very well be a lot faster than it. Use preincrementation whenever +possible.

      -The semantics of postincrement include making a copy of the value being +

      The semantics of postincrement include making a copy of the value being incremented, returning it, and then preincrementing the "work value". For primitive types, this isn't a big deal... but for iterators, it can be a huge issue (for example, some iterators contains stack and set objects in them... copying an iterator could invoke the copy ctor's of these as well). In general, -get in the habit of always using preincrement, and you won't have a problem.

      +get in the habit of always using preincrement, and you won't have a problem.

      + +
      -


    Avoid endl

      + + +
      -The endl modifier, when used with iostreams outputs a newline to the +

      The endl modifier, when used with iostreams outputs a newline to the output stream specified. In addition to doing this, however, it also flushes -the output stream. In other words, these are equivalent:

      +the output stream. In other words, these are equivalent:

      -  cout << endl;
      -  cout << "\n" << flush;
      +  cout << endl;
      +  cout << "\n" << flush;
       
      -Most of the time, you probably have no reason to flush the output stream, so it's better to use a literal "\n".

      +

      Most of the time, you probably have no reason to flush the output stream, so +it's better to use a literal "\n".

      +
      -


    Exploit C++ to its Fullest

      + -C++ is a powerful language. With a firm grasp on its capabilities, you can make +
      + +

      C++ is a powerful language. With a firm grasp on its capabilities, you can make write effective, consise, readable and maintainable code all at the same time. By staying consistent, you reduce the amount of special cases that need to be remembered. Reducing the total number of lines of code you write is a good way -to avoid documentation, and avoid giving bugs a place to hide.

      +to avoid documentation, and avoid giving bugs a place to hide.

      -For these reasons, come to know and love the contents of your local +

      For these reasons, come to know and love the contents of your local <algorithm> header file. Know about <functional> and what it can do -for you. C++ is just a tool that wants you to master it. :)

      - +for you. C++ is just a tool that wants you to master it. :)

      +
      -
       -Writing Iterators -
      + + +
      -Here's a pretty good summary of how to write your own data structure iterators +

      Here's a pretty good summary of how to write your own data structure iterators in a way that is compatible with the STL, and with a lot of other code out there -(slightly edited by Chris):

      +(slightly edited by Chris):

      -From: Ross Smith 
      +From: Ross Smith <ross.s at ihug.co.nz>
       Newsgroups: comp.lang.c++.moderated
       Subject: Writing iterators (was: Re: Non-template functions that take iterators)
       Date: 28 Jun 2001 12:07:10 -0400
       
       Andre Majorel wrote:
      -> Any pointers handy on "writing STL-compatible iterators for
      -> dummies ?"
      +> Any pointers handy on "writing STL-compatible iterators for
      +> dummies ?"
       
       I'll give it a try...
       
      @@ -550,7 +659,7 @@
                 friend class container;
                 public:
                   const value_type& operator*() const;
      -            const value_type* operator->() const;
      +            const value_type* operator->() const;
                   const_iterator& operator++();
                   const_iterator operator++(int);
                   friend bool operator==(const_iterator lhs,
      @@ -585,7 +694,7 @@
           }
       
         const container::value_type*
      -    container::const_iterator::operator->() const {
      +    container::const_iterator::operator->() const {
             return &**this;
           }
       
      @@ -599,7 +708,7 @@
       might choose the "lazy" approach and only generate the actual value
       when one of the dereferencing operators is called.
       
      -The operator->() function is just boilerplate around a call to
      +The operator->() function is just boilerplate around a call to
       operator*().
       
         container::const_iterator&
      @@ -663,7 +772,7 @@
                 friend class container::const_iterator;
                 public:
                   value_type& operator*() const;
      -            value_type* operator->() const;
      +            value_type* operator->() const;
                   iterator& operator++();
                   iterator operator++(int);
                   friend bool operator==(iterator lhs, iterator rhs);
      @@ -678,7 +787,7 @@
                   const_iterator();
                   const_iterator(const iterator& i);
                   const value_type& operator*() const;
      -            const value_type* operator->() const;
      +            const value_type* operator->() const;
                   const_iterator& operator++();
                   const_iterator operator++(int);
                   friend bool operator==(const_iterator lhs,
      @@ -805,35 +914,44 @@
       Ross Smith <ross.s at ihug.co.nz> The Internet Group, Auckland, New Zealand
       
      +
      -
    -See Also -
      + -A lot of these comments and recommendations have been culled for other sources. -Two particularly important books for our work are:

      +

      + +

      A lot of these comments and recommendations have been culled for other +sources. Two particularly important books for our work are:

        -
      1. Effective C++ by Scott Meyers. There is an online version of the book (only some chapters though) available as well. -
      2. Large-Scale C++ Software Design by John Lakos -

      -If you get some free time, and you haven't read them: do so, you might learn -something. :) +

    • Effective +C++ by Scott Meyers. There is an online version of the book (only some +chapters though) available as well.
    • +
    • Large-Scale C++ +Software Design by John Lakos
    • + + + +

      If you get some free time, and you haven't read them: do so, you might learn +something. :)

      + +
      - -

    - -
    Chris Lattner
    - - -Last modified: Sun Oct 12 22:12:43 CDT 2003 - -
    - + + + + + From brukman at cs.uiuc.edu Fri Oct 24 13:07:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Oct 24 13:07:01 2003 Subject: [llvm-commits] CVS: llvm/docs/AliasAnalysis.html Message-ID: <200310241806.NAA13303@zion.cs.uiuc.edu> Changes in directory llvm/docs: AliasAnalysis.html updated: 1.7 -> 1.8 --- Log message: This is now valid HTML 4.01 Strict. --- Diffs of the changes: (+154 -165) Index: llvm/docs/AliasAnalysis.html diff -u llvm/docs/AliasAnalysis.html:1.7 llvm/docs/AliasAnalysis.html:1.8 --- llvm/docs/AliasAnalysis.html:1.7 Wed Oct 22 21:29:42 2003 +++ llvm/docs/AliasAnalysis.html Fri Oct 24 13:06:11 2003 @@ -1,8 +1,8 @@ - + - - + Alias Analysis Infrastructure in LLVM @@ -15,40 +15,41 @@
    1. Introduction
    2. -
    3. AliasAnalysis Overview
    4. +
    5. AliasAnalysis Overview +
    6. -
    7. Writing a new AliasAnalysis Implementation
    8. +
    9. Writing a new AliasAnalysis Implementation +
    10. -
    11. Using AliasAnalysis results
    12. +
    13. Using AliasAnalysis results -
    14. Helpful alias analysis related tools
    15. + + +
    16. Helpful alias analysis related tools - - -

      Written by Chris Lattner

      +
    +
    +

    Written by Chris Lattner

    +
    @@ -113,17 +114,15 @@
    -

    -Most importantly, the AliasAnalysis class provides several methods which are + +

    Most importantly, the AliasAnalysis class provides several methods which are used to query whether or not pointers alias, whether function calls can modify -or read memory, etc. -

    -

    -Representing memory objects as a starting address and a size is critically +or read memory, etc.

    + +

    Representing memory objects as a starting address and a size is critically important for precise Alias Analyses. For example, consider this (silly) C -code: -

    -

    +code:

    +
       int i;
       char C[2];
    @@ -134,15 +133,13 @@
         C[1] = A[9-i];        /* One byte store */
       }
     
    -

    -

    -In this case, the basicaa pass will disambiguate the stores to + +

    In this case, the basicaa pass will disambiguate the stores to C[0] and C[1] because they are accesses to two distinct locations one byte apart, and the accesses are each one byte. In this case, the LICM pass can use store motion to remove the stores from the loop. In -constrast, the following code: -

    -

    +constrast, the following code:

    +
       int i;
       char C[2];
    @@ -153,13 +150,12 @@
         C[1] = A[9-i];          /* One byte store */
       }
     
    -

    -

    -In this case, the two stores to C do alias each other, because the access to the -&C[0] element is a two byte access. If size information wasn't + +

    In this case, the two stores to C do alias each other, because the access to +the &C[0] element is a two byte access. If size information wasn't available in the query, even the first case would have to conservatively assume -that the accesses alias. -

    +that the accesses alias.

    +
    @@ -168,18 +164,17 @@
    -

    -An Alias Analysis implementation can return one of three responses: MustAlias, -MayAlias, and NoAlias. The No and May alias results are obvious: if the two -pointers may never equal each other, return NoAlias, if they might, return -MayAlias. -

    -

    -The Must Alias response is trickier though. In LLVM, the Must Alias response + +

    An Alias Analysis implementation can return one of three responses: +MustAlias, MayAlias, and NoAlias. The No and May alias results are obvious: if +the two pointers may never equal each other, return NoAlias, if they might, +return MayAlias.

    + +

    The Must Alias response is trickier though. In LLVM, the Must Alias response may only be returned if the two memory objects are guaranteed to always start at exactly the same location. If two memory objects overlap, but do not start at -the same location, MayAlias must be returned. -

    +the same location, MayAlias must be returned.

    +
    @@ -188,12 +183,12 @@
    -

    -The getModRefInfo methods return information about whether the + +

    The getModRefInfo methods return information about whether the execution of an instruction can read or modify a memory location. Mod/Ref information is always conservative: if an action may read a location, Ref -is returned. -

    +is returned.

    +
    @@ -203,13 +198,13 @@
    -

    -Writing a new alias analysis implementation for LLVM is quite straight-forward. -There are already several implementations that you can use for examples, and the -following information should help fill in any details. For a minimal example, -take a look at the no-aa -implementation. -

    + +

    Writing a new alias analysis implementation for LLVM is quite +straight-forward. There are already several implementations that you can use +for examples, and the following information should help fill in any details. +For a minimal example, take a look at the no-aa implementation.

    +
    @@ -218,13 +213,13 @@
    -

    -The first step to determining what type of LLVM -pass you need to use for your Alias Analysis. As is the case with most -other analyses and transformations, the answer should be fairly obvious from -what type of problem you are trying to solve: -

    -

    + +

    The first step to determining what type of LLVM pass you need to use for your Alias +Analysis. As is the case with most other analyses and transformations, the +answer should be fairly obvious from what type of problem you are trying to +solve:

    +
    1. If you require interprocedural analysis, it should be a Pass.
    2. @@ -233,13 +228,12 @@
    3. If you don't need to look at the program at all, subclass ImmutablePass.
    -

    -

    -In addition to the pass that you subclass, you should also inherit from the + +

    In addition to the pass that you subclass, you should also inherit from the AliasAnalysis interface, of course, and use the RegisterAnalysisGroup template to register as an implementation of -AliasAnalysis. -

    +AliasAnalysis.

    +
    @@ -248,31 +242,28 @@
    -

    -Your subclass of AliasAnalysis is required to invoke two methods on the + +

    Your subclass of AliasAnalysis is required to invoke two methods on the AliasAnalysis base class: getAnalysisUsage and InitializeAliasAnalysis. In particular, your implementation of getAnalysisUsage should explicitly call into the AliasAnalysis::getAnalysisUsage method in addition to doing any declaring any pass dependencies your pass has. Thus you should have something -like this: -

    -

    +like this:

    +
         void getAnalysisUsage(AnalysisUsage &AU) const {
           AliasAnalysis::getAnalysisUsage(AU);
           // declare your dependencies here.
         }
     
    -

    -

    -Additionally, your must invoke the InitializeAliasAnalysis method from -your analysis run method (run for a Pass, + +

    Additionally, your must invoke the InitializeAliasAnalysis method +from your analysis run method (run for a Pass, runOnFunction for a FunctionPass, runOnBasicBlock for a BasicBlockPass, or InitializeAliasAnalysis for an -ImmutablePass). For example (as part of a Pass): -

    -

    +ImmutablePass). For example (as part of a Pass):

    +
         bool run(Module &M) {
           InitializeAliasAnalysis(this);
    @@ -280,7 +271,7 @@
           return false;
         }
     
    -

    +
    @@ -289,13 +280,13 @@
    -

    -All of the AliasAnalysis virtual -methods default to providing conservatively correct information (returning "May" -Alias and "Mod/Ref" for alias and mod/ref queries respectively). Depending on -the capabilities of the analysis you are implementing, you just override the -interfaces you can improve. -

    + +

    All of the AliasAnalysis +virtual methods default to providing conservatively correct information +(returning "May" Alias and "Mod/Ref" for alias and mod/ref queries +respectively). Depending on the capabilities of the analysis you are +implementing, you just override the interfaces you can improve.

    +
    @@ -304,15 +295,15 @@
    -

    -With only two special exceptions (the basicaa and With only two special exceptions (the basicaa and no-aa passes) every alias analysis pass should chain to another alias analysis implementation (for example, you could specify "-basic-aa -ds-aa -andersens-aa -licm" to get the maximum benefit from the three alias analyses). To do this, simply "Require" AliasAnalysis in your getAnalysisUsage method, and if you need to return a conservative -MayAlias or Mod/Ref result, simply chain to a lower analysis. -

    +MayAlias or Mod/Ref result, simply chain to a lower analysis.

    +
    @@ -321,14 +312,14 @@
    -

    -From the LLVM perspective, the only thing you need to do to provide an efficient -alias analysis is to make sure that alias analysis queries are serviced -quickly. The actual calculation of the alias analysis results (the "run" -method) is only performed once, but many (perhaps duplicate) queries may be -performed. Because of this, try to move as much computation to the run method -as possible (within reason). -

    + +

    From the LLVM perspective, the only thing you need to do to provide an +efficient alias analysis is to make sure that alias analysis queries are +serviced quickly. The actual calculation of the alias analysis results (the +"run" method) is only performed once, but many (perhaps duplicate) queries may +be performed. Because of this, try to move as much computation to the run +method as possible (within reason).

    +
    @@ -338,10 +329,10 @@
    -

    -There are several different ways to use alias analysis results. In order of -preference, these are... -

    + +

    There are several different ways to use alias analysis results. In order of +preference, these are...

    +
    @@ -350,13 +341,13 @@
    -

    -The load-vn pass uses alias analysis to provide value numbering + +

    The load-vn pass uses alias analysis to provide value numbering information for load instructions. If your analysis or transformation can be modelled in a form that uses value numbering information, you don't have to do anything special to handle load instructions: just use the -load-vn pass, which uses alias analysis. -

    +load-vn pass, which uses alias analysis.

    +
    @@ -365,36 +356,33 @@
    -

    -Many transformations need information about alias sets that are active in -some scope, rather than information about pairwise aliasing. The Many transformations need information about alias sets that are active +in some scope, rather than information about pairwise aliasing. The AliasSetTracker class is used to efficiently build these Alias Sets from the pairwise alias analysis -information provided by the AliasAnalysis interface. -

    -

    -First you initialize the AliasSetTracker by use the "add" methods to +information provided by the AliasAnalysis interface.

    + +

    First you initialize the AliasSetTracker by use the "add" methods to add information about various potentially aliasing instructions in the scope you are interested in. Once all of the alias sets are completed, your pass should simply iterate through the constructed alias sets, using the AliasSetTracker -begin()/end() methods. -

    -

    -The AliasSets formed by the AliasSetTracker are guaranteed to -be disjoint, calculate mod/ref information for the set, and keep track of +begin()/end() methods.

    + +

    The AliasSets formed by the AliasSetTracker are guaranteed +to be disjoint, calculate mod/ref information for the set, and keep track of whether or not all of the pointers in the set are Must aliases. The AliasSetTracker also makes sure that sets are properly folded due to call -instructions, and can provide a list of pointers in each set. -

    -

    -As an example user of this, the Loop +instructions, and can provide a list of pointers in each set.

    + +

    As an example user of this, the Loop Invariant Code Motion pass uses AliasSetTrackers to build alias information about each loop nest. If an AliasSet in a loop is not modified, then all load instructions from that set may be hoisted out of the loop. If any alias sets are stored and are must alias sets, then the stores may be sunk to outside of the loop. Both of these transformations obviously only apply if the -pointer argument is loop-invariant. -

    +pointer argument is loop-invariant.

    +
    @@ -403,12 +391,12 @@
    -

    -As a last resort, your pass could use the AliasAnalysis interface directly to + +

    As a last resort, your pass could use the AliasAnalysis interface directly to service your pass. If you find the need to do this, please let me know so I can see if something new -needs to be added to LLVM. -

    +needs to be added to LLVM.

    +
    @@ -418,10 +406,11 @@
    -

    -If you're going to be working with the AliasAnalysis infrastructure, there are -several nice tools that may be useful for you and are worth knowing about... -

    + +

    If you're going to be working with the AliasAnalysis infrastructure, there +are several nice tools that may be useful for you and are worth knowing +about...

    +
    @@ -430,13 +419,13 @@
    -

    -The -no-aa analysis is just like what it sounds: an alias analysis that -never returns any useful information. This pass can be useful if you think that -alias analysis is doing something wrong and are trying to narrow down a problem. -If you don't specify an alias analysis, the default will be to use the -basicaa pass which does quite a bit of disambiguation on its own. -

    + +

    The -no-aa analysis is just like what it sounds: an alias analysis +that never returns any useful information. This pass can be useful if you think +that alias analysis is doing something wrong and are trying to narrow down a +problem. If you don't specify an alias analysis, the default will be to use the +basicaa pass which does quite a bit of disambiguation on its own.

    +
    @@ -446,12 +435,12 @@
    -

    -The -print-alias-sets pass is exposed as part of the analyze -tool to print out the Alias Sets formed by the The -print-alias-sets pass is exposed as part of the +analyze tool to print out the Alias Sets formed by the AliasSetTracker class. This is useful if you're using -the AliasSetTracker. -

    +the AliasSetTracker.

    +
    @@ -460,22 +449,20 @@
    -

    -The -count-aa pass is useful to see how many queries a particular pass -is making and what kinds of responses are returned by the alias analysis. An -example usage is: -

    -

    + +

    The -count-aa pass is useful to see how many queries a particular +pass is making and what kinds of responses are returned by the alias analysis. +An example usage is:

    +
       $ opt -basicaa -count-aa -ds-aa -count-aa -licm
     
    -

    -

    -Which will print out how many queries (and what responses are returned) by the --licm pass (of the -ds-aa pass) and how many queries are made -of the -basicaa pass by the -ds-aa pass. This can be useful -when evaluating an alias analysis for precision. -

    + +

    Which will print out how many queries (and what responses are returned) by +the -licm pass (of the -ds-aa pass) and how many queries are +made of the -basicaa pass by the -ds-aa pass. This can be +useful when evaluating an alias analysis for precision.

    +
    @@ -484,20 +471,22 @@
    -

    -The -aa-eval pass simply iterates through all pairs of pointers in a + +

    The -aa-eval pass simply iterates through all pairs of pointers in a function and asks an alias analysis whether or not the pointers alias. This gives an indication of the precision of the alias analysis. Statistics are printed.

    +
    -
    -
    Chris Lattner
    -Last modified: $Date: 2003/10/23 02:29:42 $ -
    +
    + From criswell at cs.uiuc.edu Fri Oct 24 13:07:22 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Oct 24 13:07:22 2003 Subject: [llvm-commits] [release_1] CVS: llvm/docs/CFEBuildInstrs.html Message-ID: <200310241806.NAA29489@choi.cs.uiuc.edu> Changes in directory llvm/docs: CFEBuildInstrs.html updated: 1.3.2.2 -> 1.3.2.3 --- Log message: Added note about multilib options. --- Diffs of the changes: (+6 -1) Index: llvm/docs/CFEBuildInstrs.html diff -u llvm/docs/CFEBuildInstrs.html:1.3.2.2 llvm/docs/CFEBuildInstrs.html:1.3.2.3 --- llvm/docs/CFEBuildInstrs.html:1.3.2.2 Thu Oct 23 17:15:14 2003 +++ llvm/docs/CFEBuildInstrs.html Fri Oct 24 13:06:42 2003 @@ -108,6 +108,11 @@
  • No inline assembly for position independent code. At the LLVM level, everything is position independent.
  • We handle .init and .fini differently.
  • +
  • You may have to disable multilib support in your target. Using multilib + support causes the GCC compiler driver to add a lot of "-L" + options to the link line, which do not relate to LLVM and confuse + gccld. To disable multilibs, delete any + MULTILIB_OPTIONS lines from your target files.
  • Did we mention that we don't support inline assembly? You'll probably have to add some fixinclude hacks to disable it in the system headers.
  • @@ -154,7 +159,7 @@
    Brian Gaeke
    The LLVM Compiler Infrastructure
    -Last modified: $Date: 2003/10/23 22:15:14 $ +Last modified: $Date: 2003/10/24 18:06:42 $
    From lattner at cs.uiuc.edu Fri Oct 24 13:10:03 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Oct 24 13:10:03 2003 Subject: [llvm-commits] CVS: llvm/tools/gccld/GenerateCode.cpp Message-ID: <200310241809.NAA13480@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccld: GenerateCode.cpp updated: 1.10 -> 1.11 --- Log message: Turn on the inliner by default at link-time --- Diffs of the changes: (+10 -0) Index: llvm/tools/gccld/GenerateCode.cpp diff -u llvm/tools/gccld/GenerateCode.cpp:1.10 llvm/tools/gccld/GenerateCode.cpp:1.11 --- llvm/tools/gccld/GenerateCode.cpp:1.10 Thu Oct 23 13:25:57 2003 +++ llvm/tools/gccld/GenerateCode.cpp Fri Oct 24 13:09:23 2003 @@ -22,6 +22,13 @@ #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/Linker.h" #include "Support/SystemUtils.h" +#include "Support/CommandLine.h" + +namespace { + cl::opt + DisableInline("disable-inlining", cl::desc("Do not run the inliner pass")); +} + /// GenerateBytecode - generates a bytecode file from the specified module. /// @@ -73,6 +80,9 @@ // Remove unused arguments from functions... Passes.add(createDeadArgEliminationPass()); + + if (!DisableInline) + Passes.add(createFunctionInliningPass()); // Inline small functions // The FuncResolve pass may leave cruft around if functions were prototyped // differently than they were defined. Remove this cruft. From lattner at cs.uiuc.edu Fri Oct 24 13:10:23 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Oct 24 13:10:23 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/Makefile.programs Message-ID: <200310241809.NAA13590@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs: Makefile.programs updated: 1.98 -> 1.99 --- Log message: For now, disable the link-time inliner for test/Programs --- Diffs of the changes: (+3 -3) Index: llvm/test/Programs/Makefile.programs diff -u llvm/test/Programs/Makefile.programs:1.98 llvm/test/Programs/Makefile.programs:1.99 --- llvm/test/Programs/Makefile.programs:1.98 Fri Oct 24 11:38:34 2003 +++ llvm/test/Programs/Makefile.programs Fri Oct 24 13:09:48 2003 @@ -194,7 +194,7 @@ $(PROGRAMS_TO_TEST:%=Output/%.llvm.bc): \ Output/%.llvm.bc: Output/%.linked.bc $(LGCCLDPROG) - $(LGCCLD) $(STATS) $< -lgcc -lc $(LIBS) crtend.o -o Output/$*.llvm + $(LGCCLD) -disable-inlining $(STATS) $< -lc $(LIBS) crtend.o -o Output/$*.llvm ifneq ($(OPTPASSES),) $(LOPT) -q $(OPTPASSES) < $@ > $@.tmp $(MV) -f $@.tmp $@ @@ -202,7 +202,7 @@ $(PROGRAMS_TO_TEST:%=Output/%.llvm): \ Output/%.llvm: Output/%.linked.bc $(LGCCLDPROG) - $(LGCCLD) $(STATS) $< -lgcc -lc $(LIBS) crtend.o -o Output/$*.llvm + $(LGCCLD) -disable-inlining $(STATS) $< -lc $(LIBS) crtend.o -o Output/$*.llvm ifneq ($(OPTPASSES),) $(LOPT) -q $(OPTPASSES) < $@ > $@.tmp $(MV) -f $@.tmp $@ @@ -215,7 +215,7 @@ sed 's/Pass Arguments: //' < $@.1 > $@ Output/gccld-pass-args: $(TOOLS)/gccld $(LLVMAS) < /dev/null > Output/gccld.test.bc - $(LGCCLD) Output/gccld.test.bc -o Output/gccld.test-out -debug-pass=Arguments > $@.1 2>&1 + $(LGCCLD) -disable-inlining Output/gccld.test.bc -o Output/gccld.test-out -debug-pass=Arguments > $@.1 2>&1 sed 's/Pass Arguments: //' < $@.1 > $@ From criswell at cs.uiuc.edu Fri Oct 24 13:12:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Oct 24 13:12:01 2003 Subject: [llvm-commits] CVS: llvm-www/releases/1.0/llvm.tar.gz Message-ID: <200310241811.NAA29571@choi.cs.uiuc.edu> Changes in directory llvm-www/releases/1.0: llvm.tar.gz updated: 1.4 -> 1.5 --- Log message: Updated CFE build guide. --- Diffs of the changes: (+0 -0) Index: llvm-www/releases/1.0/llvm.tar.gz From lattner at cs.uiuc.edu Fri Oct 24 13:16:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Oct 24 13:16:01 2003 Subject: [llvm-commits] CVS: poolalloc/test/TEST.poolalloc.Makefile Message-ID: <200310241815.NAA06866@zion.cs.uiuc.edu> Changes in directory poolalloc/test: TEST.poolalloc.Makefile updated: 1.3 -> 1.4 --- Log message: Clean up the program after poolallocation --- Diffs of the changes: (+1 -1) Index: poolalloc/test/TEST.poolalloc.Makefile diff -u poolalloc/test/TEST.poolalloc.Makefile:1.3 poolalloc/test/TEST.poolalloc.Makefile:1.4 --- poolalloc/test/TEST.poolalloc.Makefile:1.3 Tue Oct 21 15:41:49 2003 +++ poolalloc/test/TEST.poolalloc.Makefile Fri Oct 24 13:15:18 2003 @@ -24,7 +24,7 @@ # file $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).transformed.bc): \ Output/%.$(TEST).transformed.bc: Output/%.llvm.bc $(PA_SO) - -$(OPT_PA_STATS) -q -poolalloc $< -o $@ -f 2>&1 > $@.out + -$(OPT_PA_STATS) -q -poolalloc -deadargelim -globaldce $< -o $@ -f 2>&1 > $@.out # This rule compiles the new .bc file into a .c file using CBE $(PROGRAMS_TO_TEST:%=Output/%.poolalloc.cbe.c): \ From lattner at cs.uiuc.edu Fri Oct 24 13:16:18 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Oct 24 13:16:18 2003 Subject: [llvm-commits] CVS: poolalloc/lib/PoolAllocate/PoolAllocate.cpp Message-ID: <200310241815.NAA08305@zion.cs.uiuc.edu> Changes in directory poolalloc/lib/PoolAllocate: PoolAllocate.cpp updated: 1.23 -> 1.24 --- Log message: Make sure to keep exactly the same name in the rewritten program to make diff'ing easier --- Diffs of the changes: (+9 -11) Index: poolalloc/lib/PoolAllocate/PoolAllocate.cpp diff -u poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.23 poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.24 --- poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.23 Tue Oct 7 08:07:25 2003 +++ poolalloc/lib/PoolAllocate/PoolAllocate.cpp Fri Oct 24 13:15:37 2003 @@ -836,15 +836,15 @@ // NB: PH is zero even if the node is collapsed if (PH == 0) return; + std::string Name = MI.getName(); MI.setName(""); + // Insert a call to poolalloc Value *V; if (MI.isArrayAllocation()) - V = new CallInst(PAInfo.PoolAllocArray, - make_vector(PH, MI.getOperand(0), 0), - MI.getName(), &MI); + V = new CallInst(PAInfo.PoolAllocArray, make_vector(PH, MI.getOperand(0),0), + Name, &MI); else - V = new CallInst(PAInfo.PoolAlloc, make_vector(PH, 0), - MI.getName(), &MI); + V = new CallInst(PAInfo.PoolAlloc, make_vector(PH, 0), Name, &MI); //Added by Dinakar to store the type // std::cout << " In pool allocation for instruction \n"; @@ -867,9 +867,8 @@ Value *Casted = V; // Cast to the appropriate type if necessary - if (V->getType() != MI.getType()) { + if (V->getType() != MI.getType()) Casted = new CastInst(V, MI.getType(), V->getName(), &MI); - } // Update def-use info MI.replaceAllUsesWith(Casted); @@ -1009,8 +1008,7 @@ else assert(0 && "Function pointer cast not handled as called function\n"); } - } - + } } DSGraph &CallerG = G; @@ -1102,7 +1100,7 @@ // Add the rest of the arguments (the original arguments of the function)... Args.insert(Args.end(), CI.op_begin()+1, CI.op_end()); - std::string Name = CI.getName(); + std::string Name = CI.getName(); CI.setName(""); Value *NewCall; if (Args.size() > CI.getNumOperands() - 1) { @@ -1219,7 +1217,7 @@ // Add the rest of the arguments... Args.insert(Args.end(), CI.op_begin()+1, CI.op_end()); - std::string Name = CI.getName(); + std::string Name = CI.getName(); CI.setName(""); std::map::iterator CNewII; From lattner at cs.uiuc.edu Fri Oct 24 14:16:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Oct 24 14:16:01 2003 Subject: [llvm-commits] CVS: poolalloc/runtime/PoolAllocator/Makefile PoolAllocatorChained.cpp Message-ID: <200310241915.OAA03788@zion.cs.uiuc.edu> Changes in directory poolalloc/runtime/PoolAllocator: Makefile updated: 1.2 -> 1.3 PoolAllocatorChained.cpp updated: 1.5 -> 1.6 --- Log message: Convert the pool allocator to C++. It has horrible horrible scaling problems which must be fixed. --- Diffs of the changes: (+28 -21) Index: poolalloc/runtime/PoolAllocator/Makefile diff -u poolalloc/runtime/PoolAllocator/Makefile:1.2 poolalloc/runtime/PoolAllocator/Makefile:1.3 --- poolalloc/runtime/PoolAllocator/Makefile:1.2 Thu Aug 14 22:18:46 2003 +++ poolalloc/runtime/PoolAllocator/Makefile Fri Oct 24 14:15:04 2003 @@ -1,6 +1,8 @@ LEVEL = ../.. BYTECODE_LIBRARY=1 -DONT_BUILD_RELINKED=1 -LIBRARYNAME=poolalloc +LIBRARYNAME=poolalloc_rt include $(LEVEL)/Makefile.common + +# Always build optimized and debug versions +all:: $(LIBNAME_OBJO) $(LIBNAME_OBJG) \ No newline at end of file Index: poolalloc/runtime/PoolAllocator/PoolAllocatorChained.cpp diff -u poolalloc/runtime/PoolAllocator/PoolAllocatorChained.cpp:1.5 poolalloc/runtime/PoolAllocator/PoolAllocatorChained.cpp:1.6 --- poolalloc/runtime/PoolAllocator/PoolAllocatorChained.cpp:1.5 Tue Oct 21 14:11:19 2003 +++ poolalloc/runtime/PoolAllocator/PoolAllocatorChained.cpp Fri Oct 24 14:15:04 2003 @@ -5,6 +5,23 @@ #undef assert #define assert(X) +typedef struct PoolTy { + void *Data; + unsigned NodeSize; + unsigned FreeablePool; /* Set to false if the memory from this pool cannot be + freed before destroy*/ +} PoolTy; + +extern "C" { + void poolinit(PoolTy *Pool, unsigned NodeSize); + void poolmakeunfreeable(PoolTy *Pool); + void pooldestroy(PoolTy *Pool); + void *poolalloc(PoolTy *Pool); + void poolfree(PoolTy *Pool, char *Node); + void* poolallocarray(PoolTy* Pool, unsigned Size); +} + + /* In the current implementation, each slab in the pool has NODES_PER_SLAB * nodes unless the isSingleArray flag is set in which case it contains a @@ -13,25 +30,18 @@ */ #define NODES_PER_SLAB 512 -typedef struct PoolTy { - void *Data; - unsigned NodeSize; - unsigned FreeablePool; /* Set to false if the memory from this pool cannot be - freed before destroy*/ - -} PoolTy; - /* PoolSlab Structure - Hold NODES_PER_SLAB objects of the current node type. * Invariants: FirstUnused <= LastUsed+1 */ typedef struct PoolSlab { + struct PoolSlab *Next; + unsigned isSingleArray; /* If this slab is used for exactly one array */ + unsigned FirstUnused; /* First empty node in slab */ int LastUsed; /* Last allocated node in slab. -1 if slab is empty */ - struct PoolSlab *Next; unsigned char AllocatedBitVector[NODES_PER_SLAB/8]; unsigned char StartOfAllocation[NODES_PER_SLAB/8]; - unsigned isSingleArray; /* If this slab is used for exactly one array */ /* The array is allocated from the start to the end of the slab */ unsigned ArraySize; /* The size of the array allocated */ @@ -61,11 +71,10 @@ exit(1); } - Pool->NodeSize = NodeSize; + /* We must alway return unique pointers, even if they asked for 0 bytes */ + Pool->NodeSize = NodeSize ? NodeSize : 1; Pool->Data = 0; - Pool->FreeablePool = 1; - } void poolmakeunfreeable(PoolTy *Pool) { @@ -141,7 +150,7 @@ return 0; } -char *poolalloc(PoolTy *Pool) { +void *poolalloc(PoolTy *Pool) { unsigned NodeSize; PoolSlab *PS; void *Result; @@ -152,10 +161,6 @@ } NodeSize = Pool->NodeSize; - // Return if this pool has size 0 - if (NodeSize == 0) - return 0; - PS = (PoolSlab*)Pool->Data; if ((Result = FindSlabEntry(PS, NodeSize))) @@ -400,7 +405,7 @@ return 0; } -char* poolallocarray(PoolTy* Pool, unsigned Size) { +void* poolallocarray(PoolTy* Pool, unsigned Size) { unsigned NodeSize; PoolSlab *PS; void *Result; From lattner at cs.uiuc.edu Fri Oct 24 14:18:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Oct 24 14:18:02 2003 Subject: [llvm-commits] CVS: poolalloc/test/TEST.poolalloc.report Message-ID: <200310241917.OAA04513@zion.cs.uiuc.edu> Changes in directory poolalloc/test: TEST.poolalloc.report updated: 1.3 -> 1.4 --- Log message: Actually print out what the column header indicates --- Diffs of the changes: (+1 -1) Index: poolalloc/test/TEST.poolalloc.report diff -u poolalloc/test/TEST.poolalloc.report:1.3 poolalloc/test/TEST.poolalloc.report:1.4 --- poolalloc/test/TEST.poolalloc.report:1.3 Tue Oct 21 15:41:49 2003 +++ poolalloc/test/TEST.poolalloc.report Fri Oct 24 14:17:12 2003 @@ -11,7 +11,7 @@ my ($Cols, $Col) = @_; if ($Cols->[$Col-1] ne "*" and $Cols->[$Col-2] ne "*" and $Cols->[$Col-1] != "0") { - return 100.0*$Cols->[$Col-2]/$Cols->[$Col-1] . "%"; + return sprintf "%3.2f%%", ((100.0*$Cols->[$Col-2])/$Cols->[$Col-1] - 100.0); } else { return "n/a"; } From lattner at cs.uiuc.edu Fri Oct 24 14:19:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Oct 24 14:19:02 2003 Subject: [llvm-commits] CVS: poolalloc/test/TEST.poolalloc.Makefile Message-ID: <200310241918.OAA04681@zion.cs.uiuc.edu> Changes in directory poolalloc/test: TEST.poolalloc.Makefile updated: 1.4 -> 1.5 --- Log message: I have an idea: how about we actually run the pool allocated version of the code when we say we are going to! While we're at it, we can link in the release version of the pool allocator runtime. --- Diffs of the changes: (+10 -6) Index: poolalloc/test/TEST.poolalloc.Makefile diff -u poolalloc/test/TEST.poolalloc.Makefile:1.4 poolalloc/test/TEST.poolalloc.Makefile:1.5 --- poolalloc/test/TEST.poolalloc.Makefile:1.4 Fri Oct 24 13:15:18 2003 +++ poolalloc/test/TEST.poolalloc.Makefile Fri Oct 24 14:17:54 2003 @@ -9,9 +9,13 @@ PROGDIR := $(shell cd $(LEVEL)/test/Programs; pwd)/ RELDIR := $(subst $(PROGDIR),,$(CURDIR)) -# Pool allocator shared object and runtime library... -PA_SO := $(PROJECT_DIR)/lib/Debug/libpoolalloc.so -PA_RT := $(PROJECT_DIR)/lib/Bytecode/libpoolalloc.bc +# Pool allocator pass shared object +PA_SO := $(PROJECT_DIR)/lib/Debug/libpoolalloc.so + +# Pool allocator runtime library +PA_RT := $(PROJECT_DIR)/lib/Bytecode/libpoolalloc_rt.bc +PA_RT_O := $(PROJECT_DIR)/lib/Release/poolalloc_rt.o + # Command to run opt with the pool allocator pass loaded OPT_PA := $(LOPT) -load $(PA_SO) @@ -28,13 +32,13 @@ # This rule compiles the new .bc file into a .c file using CBE $(PROGRAMS_TO_TEST:%=Output/%.poolalloc.cbe.c): \ -Output/%.poolalloc.cbe.c: Output/%.llvm.bc $(LDIS) +Output/%.poolalloc.cbe.c: Output/%.$(TEST).transformed.bc $(LDIS) -$(LDIS) -c -f $< -o $@ # This rule compiles the .c file into an executable using $CC $(PROGRAMS_TO_TEST:%=Output/%.poolalloc.cbe): \ -Output/%.poolalloc.cbe: Output/%.poolalloc.cbe.c - -$(CC) $(CFLAGS) $< $(LLCLIBS) $(LDFLAGS) -o $@ +Output/%.poolalloc.cbe: Output/%.poolalloc.cbe.c $(PA_RT_O) + -$(CC) $(CFLAGS) $< $(PA_RT_O) $(LLCLIBS) $(LDFLAGS) -o $@ # This rule runs the generated executable, generating timing information $(PROGRAMS_TO_TEST:%=Output/%.poolalloc.out-cbe): \ From lattner at cs.uiuc.edu Fri Oct 24 14:43:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Oct 24 14:43:02 2003 Subject: [llvm-commits] CVS: poolalloc/runtime/PoolAllocator/PoolAllocatorChained.cpp Message-ID: <200310241942.OAA10109@zion.cs.uiuc.edu> Changes in directory poolalloc/runtime/PoolAllocator: PoolAllocatorChained.cpp updated: 1.6 -> 1.7 --- Log message: Convert to C++: some comment conversions, demacroification Convert error checks to use assertions --- Diffs of the changes: (+94 -134) Index: poolalloc/runtime/PoolAllocator/PoolAllocatorChained.cpp diff -u poolalloc/runtime/PoolAllocator/PoolAllocatorChained.cpp:1.6 poolalloc/runtime/PoolAllocator/PoolAllocatorChained.cpp:1.7 --- poolalloc/runtime/PoolAllocator/PoolAllocatorChained.cpp:1.6 Fri Oct 24 14:15:04 2003 +++ poolalloc/runtime/PoolAllocator/PoolAllocatorChained.cpp Fri Oct 24 14:41:51 2003 @@ -1,3 +1,18 @@ +//===- PoolAllocatorChained.cpp - Implementation of poolallocator runtime -===// +// +// 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 is one possible implementation of the LLVM pool allocator runtime +// library. +// +//===----------------------------------------------------------------------===// + +#include "PoolAllocator.h" #include #include #include @@ -5,24 +20,6 @@ #undef assert #define assert(X) -typedef struct PoolTy { - void *Data; - unsigned NodeSize; - unsigned FreeablePool; /* Set to false if the memory from this pool cannot be - freed before destroy*/ -} PoolTy; - -extern "C" { - void poolinit(PoolTy *Pool, unsigned NodeSize); - void poolmakeunfreeable(PoolTy *Pool); - void pooldestroy(PoolTy *Pool); - void *poolalloc(PoolTy *Pool); - void poolfree(PoolTy *Pool, char *Node); - void* poolallocarray(PoolTy* Pool, unsigned Size); -} - - - /* In the current implementation, each slab in the pool has NODES_PER_SLAB * nodes unless the isSingleArray flag is set in which case it contains a * single array of size ArraySize. Small arrays (size <= NODES_PER_SLAB) are @@ -47,29 +44,36 @@ char Data[1]; /* Buffer to hold data in this slab... variable sized */ -} PoolSlab; -#define NODE_ALLOCATED(POOLSLAB, NODENUM) \ - ((POOLSLAB)->AllocatedBitVector[(NODENUM) >> 3] & (1 << ((NODENUM) & 7))) -#define MARK_NODE_ALLOCATED(POOLSLAB, NODENUM) \ - (POOLSLAB)->AllocatedBitVector[(NODENUM) >> 3] |= 1 << ((NODENUM) & 7) -#define MARK_NODE_FREE(POOLSLAB, NODENUM) \ - (POOLSLAB)->AllocatedBitVector[(NODENUM) >> 3] &= ~(1 << ((NODENUM) & 7)) -#define ALLOCATION_BEGINS(POOLSLAB, NODENUM) \ - ((POOLSLAB)->StartOfAllocation[(NODENUM) >> 3] & (1 << ((NODENUM) & 7))) -#define SET_START_BIT(POOLSLAB, NODENUM) \ - (POOLSLAB)->StartOfAllocation[(NODENUM) >> 3] |= 1 << ((NODENUM) & 7) -#define CLEAR_START_BIT(POOLSLAB, NODENUM) \ - (POOLSLAB)->StartOfAllocation[(NODENUM) >> 3] &= ~(1 << ((NODENUM) & 7)) + bool isNodeAllocated(unsigned NodeNum) { + return AllocatedBitVector[NodeNum >> 3] & (1 << (NodeNum & 7)); + } + + void markNodeAllocated(unsigned NodeNum) { + AllocatedBitVector[NodeNum >> 3] |= 1 << (NodeNum & 7); + } + + void markNodeFree(unsigned NodeNum) { + AllocatedBitVector[NodeNum >> 3] &= ~(1 << (NodeNum & 7)); + } + + bool isStartOfAllocation(unsigned NodeNum) { + return StartOfAllocation[NodeNum >> 3] & (1 << (NodeNum & 7)); + } + + void setStartBit(unsigned NodeNum) { + StartOfAllocation[NodeNum >> 3] |= 1 << (NodeNum & 7); + } + void clearStartBit(unsigned NodeNum) { + StartOfAllocation[NodeNum >> 3] &= ~(1 << (NodeNum & 7)); + } +} PoolSlab; /* poolinit - Initialize a pool descriptor to empty */ void poolinit(PoolTy *Pool, unsigned NodeSize) { - if (!Pool) { - printf("Null pool pointer passed into poolinit!\n"); - exit(1); - } + assert(Pool && "Null pool pointer passed into poolinit!\n"); /* We must alway return unique pointers, even if they asked for 0 bytes */ Pool->NodeSize = NodeSize ? NodeSize : 1; @@ -78,11 +82,7 @@ } void poolmakeunfreeable(PoolTy *Pool) { - if (!Pool) { - printf("Null pool pointer passed in to poolmakeunfreeable!\n"); - exit(1); - } - + assert (Pool && "Null pool pointer passed in to poolmakeunfreeable!\n"); Pool->FreeablePool = 0; } @@ -90,10 +90,7 @@ */ void pooldestroy(PoolTy *Pool) { PoolSlab *PS; - if (!Pool) { - printf("Null pool pointer passed in to pooldestroy!\n"); - exit(1); - } + assert(Pool && "Null pool pointer passed in to pooldestroy!\n"); PS = (PoolSlab*)Pool->Data; while (PS) { @@ -115,8 +112,8 @@ /* Check to see if there are empty entries at the end of the slab... */ if (PS->LastUsed < NODES_PER_SLAB-1) { /* Mark the returned entry used */ - MARK_NODE_ALLOCATED(PS, PS->LastUsed+1); - SET_START_BIT(PS, PS->LastUsed+1); + PS->markNodeAllocated(PS->LastUsed+1); + PS->setStartBit(PS->LastUsed+1); /* If we are allocating out the first unused field, bump its index also */ if (PS->FirstUnused == (unsigned)PS->LastUsed+1) @@ -133,14 +130,14 @@ /* Successfully allocate out the first unused node */ unsigned Idx = PS->FirstUnused; - MARK_NODE_ALLOCATED(PS, Idx); - SET_START_BIT(PS, Idx); + PS->markNodeAllocated(Idx); + PS->setStartBit(Idx); /* Increment FirstUnused to point to the new first unused value... */ do { ++PS->FirstUnused; } while (PS->FirstUnused < NODES_PER_SLAB && - NODE_ALLOCATED(PS, PS->FirstUnused)); + PS->isNodeAllocated(PS->FirstUnused)); return &PS->Data[0] + Idx*NodeSize; } @@ -151,28 +148,19 @@ } void *poolalloc(PoolTy *Pool) { - unsigned NodeSize; - PoolSlab *PS; - void *Result; - - if (!Pool) { - printf("Null pool pointer passed in to poolalloc!\n"); - exit(1); - } + assert(Pool && "Null pool pointer passed in to poolalloc!\n"); - NodeSize = Pool->NodeSize; - PS = (PoolSlab*)Pool->Data; + unsigned NodeSize = Pool->NodeSize; + PoolSlab *PS = (PoolSlab*)Pool->Data; + void *Result; if ((Result = FindSlabEntry(PS, NodeSize))) return Result; /* Otherwise we must allocate a new slab and add it to the list */ PS = (PoolSlab*)malloc(sizeof(PoolSlab)+NodeSize*NODES_PER_SLAB-1); - if (!PS) { - printf("poolalloc: Could not allocate memory!"); - exit(1); - } + assert(PS && "poolalloc: Could not allocate memory!"); /* Initialize the slab to indicate that the first element is allocated */ PS->FirstUnused = 1; @@ -181,8 +169,8 @@ PS->isSingleArray = 0; PS->ArraySize = 0; - MARK_NODE_ALLOCATED(PS, 0); - SET_START_BIT(PS, 0); + PS->markNodeAllocated(0); + PS->setStartBit(0); /* Add the slab to the list... */ PS->Next = (PoolSlab*)Pool->Data; @@ -191,17 +179,14 @@ } void poolfree(PoolTy *Pool, char *Node) { - unsigned NodeSize, Idx; + assert(Pool && "Null pool pointer passed in to poolfree!\n"); + + unsigned Idx; PoolSlab *PS; PoolSlab **PPS; unsigned idxiter; - if (!Pool) { - printf("Null pool pointer passed in to poolfree!\n"); - exit(1); - } - - NodeSize = Pool->NodeSize; + unsigned NodeSize = Pool->NodeSize; // Return if this pool has size 0 if (NodeSize == 0) @@ -212,10 +197,8 @@ /* Search for the slab that contains this node... */ while (&PS->Data[0] > Node || &PS->Data[NodeSize*NODES_PER_SLAB-1] < Node) { - if (!PS) { - printf("poolfree: node being free'd not found in allocation pool specified!\n"); - exit(1); - } + assert(PS && "poolfree: node being free'd not found in allocation " + " pool specified!\n"); PPS = &PS->Next; PS = PS->Next; @@ -229,40 +212,31 @@ if (PS->isSingleArray) { /* If this slab is a SingleArray */ + assert(Idx == 0 && "poolfree: Attempt to free middle of allocated array\n"); + assert(PS->isNodeAllocated(0) && + "poolfree: Attempt to free node that is already freed\n"); - if (Idx != 0) { - printf("poolfree: Attempt to free middle of allocated array\n"); - exit(1); - } - if (!NODE_ALLOCATED(PS,0)) { - printf("poolfree: Attempt to free node that is already freed\n"); - exit(1); - } /* Mark this SingleArray slab as being free by just marking the first entry as free*/ - MARK_NODE_FREE(PS, 0); + PS->markNodeFree(0); } else { /* If this slab is not a SingleArray */ - - if (!ALLOCATION_BEGINS(PS, Idx)) { - printf("poolfree: Attempt to free middle of allocated array\n"); - exit(1); - } + assert(PS->isStartOfAllocation(Idx) && + "poolfree: Attempt to free middle of allocated array\n"); /* Free the first node */ - if (!NODE_ALLOCATED(PS, Idx)) { - printf("poolfree: Attempt to free node that is already freed\n"); - exit(1); - } - CLEAR_START_BIT(PS, Idx); - MARK_NODE_FREE(PS, Idx); + assert(PS->isNodeAllocated(Idx) && + "poolfree: Attempt to free node that is already freed\n"); + + PS->clearStartBit(Idx); + PS->markNodeFree(Idx); // Free all nodes idxiter = Idx + 1; - while (idxiter < NODES_PER_SLAB && (!ALLOCATION_BEGINS(PS,idxiter)) && - (NODE_ALLOCATED(PS, idxiter))) { - MARK_NODE_FREE(PS, idxiter); + while (idxiter < NODES_PER_SLAB && (!PS->isStartOfAllocation(idxiter)) && + (PS->isNodeAllocated(idxiter))) { + PS->markNodeFree(idxiter); ++idxiter; } @@ -282,7 +256,7 @@ /* FIXME, this should scan the allocated array an entire byte at a time * for performance! */ - } while (PS->LastUsed >= 0 && (!NODE_ALLOCATED(PS, PS->LastUsed))); + } while (PS->LastUsed >= 0 && (!PS->isNodeAllocated(PS->LastUsed))); assert(PS->FirstUnused <= PS->LastUsed+1 && "FirstUnused field was out of date!"); @@ -340,10 +314,10 @@ /* For large array allocation */ if (Size > NODES_PER_SLAB) { /* If this slab is a SingleArray that is free with size > Size, use it */ - if (PS->isSingleArray && !NODE_ALLOCATED(PS,0) && PS->ArraySize >= Size) { - /* Allocate the array in this slab */ - MARK_NODE_ALLOCATED(PS,0); /* In a single array, only the first node - needs to be marked */ + if (PS->isSingleArray && !PS->isNodeAllocated(0) &&PS->ArraySize >= Size){ + // Allocate the array in this slab + // In a single array, only the first node needs to be marked + PS->markNodeAllocated(0); return &PS->Data[0]; } else continue; @@ -354,9 +328,9 @@ /* Check to see if there are empty entries at the end of the slab... */ if (PS->LastUsed < (int)(NODES_PER_SLAB-Size)) { /* Mark the returned entry used and set the start bit*/ - SET_START_BIT(PS, PS->LastUsed + 1); + PS->setStartBit(PS->LastUsed + 1); for (i = PS->LastUsed + 1; i <= PS->LastUsed + Size; ++i) - MARK_NODE_ALLOCATED(PS, i); + PS->markNodeAllocated(i); /* If we are allocating out the first unused field, bump its index also */ if (PS->FirstUnused == (unsigned)PS->LastUsed+1) @@ -381,18 +355,18 @@ FirstUnused */ foundArray = 1; for (i = Idx; (i < Idx + Size) && foundArray; ++i) - if (NODE_ALLOCATED(PS, i)) + if (PS->isNodeAllocated(i)) foundArray = 0; if (foundArray) { /* Successfully allocate starting from the first unused node */ - SET_START_BIT(PS, Idx); + PS->setStartBit(Idx); for (i = Idx; i < Idx + Size; ++i) - MARK_NODE_ALLOCATED(PS, i); + PS->markNodeAllocated(i); PS->FirstUnused += Size; while (PS->FirstUnused < NODES_PER_SLAB && - NODE_ALLOCATED(PS, PS->FirstUnused)) { + PS->isNodeAllocated(PS->FirstUnused)) { ++PS->FirstUnused; } return &PS->Data[0] + Idx*NodeSize; @@ -406,24 +380,17 @@ } void* poolallocarray(PoolTy* Pool, unsigned Size) { - unsigned NodeSize; - PoolSlab *PS; - void *Result; - unsigned i; - - if (!Pool) { - printf("Null pool pointer passed to poolallocarray!\n"); - exit(1); - } + assert(Pool && "Null pool pointer passed into poolallocarray!\n"); - NodeSize = Pool->NodeSize; + unsigned NodeSize = Pool->NodeSize; // Return if this pool has size 0 if (NodeSize == 0) return 0; - PS = (PoolSlab*)Pool->Data; + PoolSlab *PS = (PoolSlab*)Pool->Data; + void *Result; if ((Result = FindSlabEntryArray(PS, NodeSize,Size))) return Result; @@ -431,19 +398,13 @@ if (Size > NODES_PER_SLAB) { /* Allocate a new slab of size Size */ PS = (PoolSlab*)malloc(sizeof(PoolSlab)+NodeSize*Size-1); - if (!PS) { - printf("poolallocarray: Could not allocate memory!\n"); - exit(1); - } + assert(PS && "poolallocarray: Could not allocate memory!\n"); PS->isSingleArray = 1; PS->ArraySize = Size; - MARK_NODE_ALLOCATED(PS, 0); + PS->markNodeAllocated(0); } else { PS = (PoolSlab*)malloc(sizeof(PoolSlab)+NodeSize*NODES_PER_SLAB-1); - if (!PS) { - printf("poolallocarray: Could not allocate memory!\n"); - exit(1); - } + assert(PS && "poolallocarray: Could not allocate memory!\n"); /* Initialize the slab to indicate that the first element is allocated */ PS->FirstUnused = Size; @@ -452,10 +413,9 @@ PS->isSingleArray = 0; PS->ArraySize = 0; - SET_START_BIT(PS, 0); - for (i = 0; i < Size; ++i) { - MARK_NODE_ALLOCATED(PS, i); - } + PS->setStartBit(0); + for (unsigned i = 0; i != Size; ++i) + PS->markNodeAllocated(i); } /* Add the slab to the list... */ From lattner at cs.uiuc.edu Fri Oct 24 14:45:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Oct 24 14:45:01 2003 Subject: [llvm-commits] CVS: poolalloc/runtime/PoolAllocator/PoolAllocator.h Message-ID: <200310241944.OAA10167@zion.cs.uiuc.edu> Changes in directory poolalloc/runtime/PoolAllocator: PoolAllocator.h added (r1.1) --- Log message: new header file --- Diffs of the changes: (+40 -0) Index: poolalloc/runtime/PoolAllocator/PoolAllocator.h diff -c /dev/null poolalloc/runtime/PoolAllocator/PoolAllocator.h:1.1 *** /dev/null Fri Oct 24 14:44:26 2003 --- poolalloc/runtime/PoolAllocator/PoolAllocator.h Fri Oct 24 14:44:16 2003 *************** *** 0 **** --- 1,40 ---- + //===- PoolAllocator.h - Pool allocator runtime interface 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 defines the interface which is implemented by the LLVM pool + // allocator runtime library. + // + //===----------------------------------------------------------------------===// + + #ifndef POOLALLOCATOR_RUNTIME_H + #define POOLALLOCATOR_RUNTIME_H + + typedef struct PoolTy { + // Data - An implementation specified data pointer. + void *Data; + + // NodeSize - Keep track of the object size tracked by this pool + unsigned NodeSize; + + // FreeablePool - Set to false if the memory from this pool cannot be freed + // before destroy. + // + unsigned FreeablePool; + } PoolTy; + + extern "C" { + void poolinit(PoolTy *Pool, unsigned NodeSize); + void poolmakeunfreeable(PoolTy *Pool); + void pooldestroy(PoolTy *Pool); + void *poolalloc(PoolTy *Pool); + void poolfree(PoolTy *Pool, char *Node); + void* poolallocarray(PoolTy* Pool, unsigned Size); + } + + #endif From lattner at cs.uiuc.edu Fri Oct 24 14:57:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Oct 24 14:57:01 2003 Subject: [llvm-commits] CVS: poolalloc/runtime/PoolAllocator/PoolAllocator.h PoolAllocatorChained.cpp Message-ID: <200310241956.OAA11520@zion.cs.uiuc.edu> Changes in directory poolalloc/runtime/PoolAllocator: PoolAllocator.h updated: 1.1 -> 1.2 PoolAllocatorChained.cpp updated: 1.7 -> 1.8 --- Log message: C++ commentify Rename Data -> Slabs in the pool structure so there is only one "Data" field --- Diffs of the changes: (+38 -39) Index: poolalloc/runtime/PoolAllocator/PoolAllocator.h diff -u poolalloc/runtime/PoolAllocator/PoolAllocator.h:1.1 poolalloc/runtime/PoolAllocator/PoolAllocator.h:1.2 --- poolalloc/runtime/PoolAllocator/PoolAllocator.h:1.1 Fri Oct 24 14:44:16 2003 +++ poolalloc/runtime/PoolAllocator/PoolAllocator.h Fri Oct 24 14:56:44 2003 @@ -1,4 +1,4 @@ -//===- PoolAllocator.h - Pool allocator runtime interface file ------------===// +//===- PoolAllocator.h - Pool allocator runtime interface file --*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -16,8 +16,8 @@ #define POOLALLOCATOR_RUNTIME_H typedef struct PoolTy { - // Data - An implementation specified data pointer. - void *Data; + // Slabs - An implementation specified data pointer. + void *Slabs; // NodeSize - Keep track of the object size tracked by this pool unsigned NodeSize; Index: poolalloc/runtime/PoolAllocator/PoolAllocatorChained.cpp diff -u poolalloc/runtime/PoolAllocator/PoolAllocatorChained.cpp:1.7 poolalloc/runtime/PoolAllocator/PoolAllocatorChained.cpp:1.8 --- poolalloc/runtime/PoolAllocator/PoolAllocatorChained.cpp:1.7 Fri Oct 24 14:41:51 2003 +++ poolalloc/runtime/PoolAllocator/PoolAllocatorChained.cpp Fri Oct 24 14:56:44 2003 @@ -70,14 +70,14 @@ } } PoolSlab; -/* poolinit - Initialize a pool descriptor to empty - */ +// poolinit - Initialize a pool descriptor to empty +// void poolinit(PoolTy *Pool, unsigned NodeSize) { assert(Pool && "Null pool pointer passed into poolinit!\n"); /* We must alway return unique pointers, even if they asked for 0 bytes */ Pool->NodeSize = NodeSize ? NodeSize : 1; - Pool->Data = 0; + Pool->Slabs = 0; Pool->FreeablePool = 1; } @@ -86,13 +86,13 @@ Pool->FreeablePool = 0; } -/* pooldestroy - Release all memory allocated for a pool - */ +// pooldestroy - Release all memory allocated for a pool +// void pooldestroy(PoolTy *Pool) { PoolSlab *PS; assert(Pool && "Null pool pointer passed in to pooldestroy!\n"); - PS = (PoolSlab*)Pool->Data; + PS = (PoolSlab*)Pool->Slabs; while (PS) { PoolSlab *Next = PS->Next; free(PS); @@ -101,39 +101,38 @@ } static void *FindSlabEntry(PoolSlab *PS, unsigned NodeSize) { - /* Loop through all of the slabs looking for one with an opening */ + // Loop through all of the slabs looking for one with an opening */ for (; PS; PS = PS->Next) { - - /* If the slab is a single array, go on to the next slab */ - /* Don't allocate single nodes in a SingleArray slab */ + // If the slab is a single array, go on to the next slab. Don't allocate + // single nodes in a SingleArray slab. if (PS->isSingleArray) continue; - /* Check to see if there are empty entries at the end of the slab... */ + // Check to see if there are empty entries at the end of the slab... if (PS->LastUsed < NODES_PER_SLAB-1) { - /* Mark the returned entry used */ + // Mark the returned entry used PS->markNodeAllocated(PS->LastUsed+1); PS->setStartBit(PS->LastUsed+1); - /* If we are allocating out the first unused field, bump its index also */ + // If we are allocating out the first unused field, bump its index also if (PS->FirstUnused == (unsigned)PS->LastUsed+1) PS->FirstUnused++; - /* Return the entry, increment LastUsed field. */ + // Return the entry, increment LastUsed field. return &PS->Data[0] + ++PS->LastUsed * NodeSize; } - /* If not, check to see if this node has a declared "FirstUnused" value that - * is less than the number of nodes allocated... - */ + // If not, check to see if this node has a declared "FirstUnused" value that + // is less than the number of nodes allocated... + // if (PS->FirstUnused < NODES_PER_SLAB) { - /* Successfully allocate out the first unused node */ + // Successfully allocate out the first unused node unsigned Idx = PS->FirstUnused; PS->markNodeAllocated(Idx); PS->setStartBit(Idx); - /* Increment FirstUnused to point to the new first unused value... */ + // Increment FirstUnused to point to the new first unused value... do { ++PS->FirstUnused; } while (PS->FirstUnused < NODES_PER_SLAB && @@ -143,7 +142,7 @@ } } - /* No empty nodes available, must grow # slabs! */ + // No empty nodes available, must grow # slabs! return 0; } @@ -151,7 +150,7 @@ assert(Pool && "Null pool pointer passed in to poolalloc!\n"); unsigned NodeSize = Pool->NodeSize; - PoolSlab *PS = (PoolSlab*)Pool->Data; + PoolSlab *PS = (PoolSlab*)Pool->Slabs; void *Result; if ((Result = FindSlabEntry(PS, NodeSize))) @@ -173,8 +172,8 @@ PS->setStartBit(0); /* Add the slab to the list... */ - PS->Next = (PoolSlab*)Pool->Data; - Pool->Data = PS; + PS->Next = (PoolSlab*)Pool->Slabs; + Pool->Slabs = PS; return &PS->Data[0]; } @@ -192,8 +191,8 @@ if (NodeSize == 0) return; - PS = (PoolSlab*)Pool->Data; - PPS = (PoolSlab**)&Pool->Data; + PS = (PoolSlab*)Pool->Slabs; + PPS = (PoolSlab**)&Pool->Slabs; /* Search for the slab that contains this node... */ while (&PS->Data[0] > Node || &PS->Data[NodeSize*NODES_PER_SLAB-1] < Node) { @@ -274,14 +273,14 @@ free(PS); } else if (PS->LastUsed == -1) { /* Empty slab? */ PoolSlab *HeadSlab; - *PPS = PS->Next; /* Unlink from the list of slabs... */ + *PPS = PS->Next; // Unlink from the list of slabs... - HeadSlab = (PoolSlab*)Pool->Data; - if (HeadSlab && HeadSlab->LastUsed == -1){/*List already has empty slab?*/ - free(PS); /*Free memory for slab */ + HeadSlab = (PoolSlab*)Pool->Slabs; + if (HeadSlab && HeadSlab->LastUsed == -1){// List already has empty slab? + free(PS); // Free memory for slab } else { - PS->Next = HeadSlab; /*No empty slab yet, add this*/ - Pool->Data = PS; /*one to the head of the list */ + PS->Next = HeadSlab; // No empty slab yet, add this + Pool->Slabs = PS; // one to the head of the list } } } else { @@ -294,10 +293,10 @@ /* Do not free the pool, but move it to the head of the list if there is no empty slab there already */ PoolSlab *HeadSlab; - HeadSlab = (PoolSlab*)Pool->Data; + HeadSlab = (PoolSlab*)Pool->Slabs; if (HeadSlab && HeadSlab->LastUsed != -1) { PS->Next = HeadSlab; - Pool->Data = PS; + Pool->Slabs = PS; } } } @@ -388,7 +387,7 @@ if (NodeSize == 0) return 0; - PoolSlab *PS = (PoolSlab*)Pool->Data; + PoolSlab *PS = (PoolSlab*)Pool->Slabs; void *Result; if ((Result = FindSlabEntryArray(PS, NodeSize,Size))) @@ -419,7 +418,7 @@ } /* Add the slab to the list... */ - PS->Next = (PoolSlab*)Pool->Data; - Pool->Data = PS; + PS->Next = (PoolSlab*)Pool->Slabs; + Pool->Slabs = PS; return &PS->Data[0]; } From gaeke at cs.uiuc.edu Fri Oct 24 14:59:01 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Fri Oct 24 14:59:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/ExecutionEngine/ExecutionEngine.h Message-ID: <200310241958.OAA04182@gally.cs.uiuc.edu> Changes in directory llvm/include/llvm/ExecutionEngine: ExecutionEngine.h updated: 1.16 -> 1.17 --- Log message: ExecutionEngine::create no longer takes a TraceMode argument. --- Diffs of the changes: (+1 -2) Index: llvm/include/llvm/ExecutionEngine/ExecutionEngine.h diff -u llvm/include/llvm/ExecutionEngine/ExecutionEngine.h:1.16 llvm/include/llvm/ExecutionEngine/ExecutionEngine.h:1.17 --- llvm/include/llvm/ExecutionEngine/ExecutionEngine.h:1.16 Mon Oct 20 15:19:24 2003 +++ llvm/include/llvm/ExecutionEngine/ExecutionEngine.h Fri Oct 24 14:58:15 2003 @@ -56,8 +56,7 @@ virtual GenericValue run(Function *F, const std::vector &ArgValues) = 0; - static ExecutionEngine *create(ModuleProvider *MP, bool ForceInterpreter, - bool TraceMode); + static ExecutionEngine *create(ModuleProvider *MP, bool ForceInterpreter); void addGlobalMapping(const Function *F, void *Addr) { void *&CurVal = GlobalAddress[(const GlobalValue*)F]; From brukman at cs.uiuc.edu Fri Oct 24 14:59:17 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Oct 24 14:59:17 2003 Subject: [llvm-commits] CVS: llvm/docs/llvm.css Message-ID: <200310241958.OAA17423@zion.cs.uiuc.edu> Changes in directory llvm/docs: llvm.css updated: 1.3 -> 1.4 --- Log message: Added a style for making test red, which is used in CommandLine.html --- Diffs of the changes: (+3 -0) Index: llvm/docs/llvm.css diff -u llvm/docs/llvm.css:1.3 llvm/docs/llvm.css:1.4 --- llvm/docs/llvm.css:1.3 Fri Oct 24 12:56:09 2003 +++ llvm/docs/llvm.css Fri Oct 24 14:58:36 2003 @@ -37,6 +37,9 @@ .doc_footer { text-align: left; padding: 0 0 0 0; font-size 12pt } +.doc_red { color: red } + + /* Publications */ .pub_title { font-family: "Georgia,Palatino,Times,Roman"; font-size: 24pt; From gaeke at cs.uiuc.edu Fri Oct 24 14:59:34 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Fri Oct 24 14:59:34 2003 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/ExecutionEngine.cpp Message-ID: <200310241958.OAA04218@gally.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine: ExecutionEngine.cpp updated: 1.35 -> 1.36 --- Log message: ExecutionEngine::create no longer takes a TraceMode argument. --- Diffs of the changes: (+4 -5) Index: llvm/lib/ExecutionEngine/ExecutionEngine.cpp diff -u llvm/lib/ExecutionEngine/ExecutionEngine.cpp:1.35 llvm/lib/ExecutionEngine/ExecutionEngine.cpp:1.36 --- llvm/lib/ExecutionEngine/ExecutionEngine.cpp:1.35 Mon Oct 20 14:43:16 2003 +++ llvm/lib/ExecutionEngine/ExecutionEngine.cpp Fri Oct 24 14:58:38 2003 @@ -47,18 +47,17 @@ /// NULL is returned. /// ExecutionEngine *ExecutionEngine::create(ModuleProvider *MP, - bool ForceInterpreter, - bool TraceMode) { + bool ForceInterpreter) { ExecutionEngine *EE = 0; - // If there is nothing that is forcing us to use the interpreter, make a JIT. - if (!ForceInterpreter && !TraceMode) + // Unless the interpreter was explicitly selected, make a JIT. + if (!ForceInterpreter) EE = VM::create(MP); // If we can't make a JIT, make an interpreter instead. try { if (EE == 0) - EE = Interpreter::create(MP->materializeModule(), TraceMode); + EE = Interpreter::create(MP->materializeModule()); } catch (...) { EE = 0; } From gaeke at cs.uiuc.edu Fri Oct 24 15:00:01 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Fri Oct 24 15:00:01 2003 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/Interpreter/Interpreter.cpp Message-ID: <200310241959.OAA04303@gally.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/Interpreter: Interpreter.cpp updated: 1.14 -> 1.15 --- Log message: ExecutionEngine::create no longer takes a TraceMode argument. CurFrame, TraceMode, and the CachedWriter are history. --- Diffs of the changes: (+7 -13) Index: llvm/lib/ExecutionEngine/Interpreter/Interpreter.cpp diff -u llvm/lib/ExecutionEngine/Interpreter/Interpreter.cpp:1.14 llvm/lib/ExecutionEngine/Interpreter/Interpreter.cpp:1.15 --- llvm/lib/ExecutionEngine/Interpreter/Interpreter.cpp:1.14 Mon Oct 20 14:43:16 2003 +++ llvm/lib/ExecutionEngine/Interpreter/Interpreter.cpp Fri Oct 24 14:59:28 2003 @@ -20,7 +20,7 @@ /// create - Create a new interpreter object. This can never fail. /// -ExecutionEngine *Interpreter::create(Module *M, bool TraceMode){ +ExecutionEngine *Interpreter::create(Module *M){ bool isLittleEndian = false; switch (M->getEndianness()) { case Module::LittleEndian: isLittleEndian = true; break; @@ -41,23 +41,21 @@ break; } - return new Interpreter(M, isLittleEndian, isLongPointer, TraceMode); + return new Interpreter(M, isLittleEndian, isLongPointer); } //===----------------------------------------------------------------------===// // Interpreter ctor - Initialize stuff // -Interpreter::Interpreter(Module *M, bool isLittleEndian, bool isLongPointer, - bool TraceMode) - : ExecutionEngine(M), ExitCode(0), Trace(TraceMode), - CurFrame(-1), TD("lli", isLittleEndian, isLongPointer ? 8 : 4, - isLongPointer ? 8 : 4, isLongPointer ? 8 : 4) { +Interpreter::Interpreter(Module *M, bool isLittleEndian, bool isLongPointer) + : ExecutionEngine(M), ExitCode(0), + TD("lli", isLittleEndian, isLongPointer ? 8 : 4, isLongPointer ? 8 : 4, + isLongPointer ? 8 : 4) { setTargetData(TD); // Initialize the "backend" initializeExecutionEngine(); initializeExternalFunctions(); - CW.setModule(M); // Update Writer emitGlobals(); } @@ -84,15 +82,11 @@ // though. std::vector ActualArgs; const unsigned ArgCount = F->getFunctionType()->getParamTypes().size(); - for (unsigned i = 0; i < ArgCount; ++i) { + for (unsigned i = 0; i < ArgCount; ++i) ActualArgs.push_back (ArgValues[i]); - } // Set up the function call. callFunction(F, ActualArgs); - - // Reset the current frame location to the top of stack - CurFrame = ECStack.size()-1; // Start executing the function. run(); From gaeke at cs.uiuc.edu Fri Oct 24 15:00:19 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Fri Oct 24 15:00:19 2003 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/Interpreter/ExecutionAnnotations.h Message-ID: <200310241959.OAA04280@gally.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/Interpreter: ExecutionAnnotations.h (r1.13) removed --- Log message: The ExecutionAnnotations (SlotNumber, InstNumber, and FunctionInfo) are history. --- Diffs of the changes: (+0 -0) From gaeke at cs.uiuc.edu Fri Oct 24 15:00:36 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Fri Oct 24 15:00:36 2003 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/Interpreter/Execution.cpp Message-ID: <200310241959.OAA04251@gally.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/Interpreter: Execution.cpp updated: 1.102 -> 1.103 --- Log message: Reduce the number of #includes. CurFrame, TraceMode, and the CachedWriter are history. ArrayChecksEnabled and non-QuietMode are history. The ExecutionAnnotations (SlotNumber, InstNumber, and FunctionInfo) are history. ExecutionContext now keeps Values for each stack frame in a std::map. Stop pre-initializing Values on the stack to 42. Remove some dead variables, excess whitespace and commented-out code. executeInstruction() is now part of run(). printValue() and print() are history. --- Diffs of the changes: (+22 -186) Index: llvm/lib/ExecutionEngine/Interpreter/Execution.cpp diff -u llvm/lib/ExecutionEngine/Interpreter/Execution.cpp:1.102 llvm/lib/ExecutionEngine/Interpreter/Execution.cpp:1.103 --- llvm/lib/ExecutionEngine/Interpreter/Execution.cpp:1.102 Mon Oct 20 14:43:16 2003 +++ llvm/lib/ExecutionEngine/Interpreter/Execution.cpp Fri Oct 24 14:59:01 2003 @@ -12,13 +12,10 @@ //===----------------------------------------------------------------------===// #include "Interpreter.h" -#include "ExecutionAnnotations.h" -#include "llvm/Module.h" +#include "llvm/Function.h" #include "llvm/Instructions.h" #include "llvm/DerivedTypes.h" #include "llvm/Constants.h" -#include "llvm/Assembly/Writer.h" -#include "Support/CommandLine.h" #include "Support/Statistic.h" #include // For fmod @@ -26,41 +23,18 @@ namespace { Statistic<> NumDynamicInsts("lli", "Number of dynamic instructions executed"); - - cl::opt - QuietMode("quiet", cl::desc("Do not emit any non-program output"), - cl::init(true)); - - cl::alias - QuietModeA("q", cl::desc("Alias for -quiet"), cl::aliasopt(QuietMode)); - - cl::opt - ArrayChecksEnabled("array-checks", cl::desc("Enable array bound checks")); } -// Create a TargetData structure to handle memory addressing and size/alignment -// computations -// -CachedWriter CW; // Object to accelerate printing of LLVM - - //===----------------------------------------------------------------------===// // Value Manipulation code //===----------------------------------------------------------------------===// -static unsigned getOperandSlot(Value *V) { - SlotNumber *SN = (SlotNumber*)V->getAnnotation(SlotNumberAID); - assert(SN && "Operand does not have a slot number annotation!"); - return SN->SlotNum; -} - // Operations used by constant expr implementations... static GenericValue executeCastOperation(Value *Src, const Type *DestTy, ExecutionContext &SF); static GenericValue executeAddInst(GenericValue Src1, GenericValue Src2, const Type *Ty); - GenericValue Interpreter::getOperandValue(Value *V, ExecutionContext &SF) { if (ConstantExpr *CE = dyn_cast(V)) { switch (CE->getOpcode()) { @@ -83,19 +57,12 @@ } else if (GlobalValue *GV = dyn_cast(V)) { return PTOGV(TheEE->getPointerToGlobal(GV)); } else { - unsigned TyP = V->getType()->getUniqueID(); // TypePlane for value - unsigned OpSlot = getOperandSlot(V); - assert(TyP < SF.Values.size() && - OpSlot < SF.Values[TyP].size() && "Value out of range!"); - return SF.Values[TyP][getOperandSlot(V)]; + return SF.Values[V]; } } static void SetValue(Value *V, GenericValue Val, ExecutionContext &SF) { - unsigned TyP = V->getType()->getUniqueID(); // TypePlane for value - - //std::cout << "Setting value: " << &SF.Values[TyP][getOperandSlot(V)]<< "\n"; - SF.Values[TyP][getOperandSlot(V)] = Val; + SF.Values[V] = Val; } //===----------------------------------------------------------------------===// @@ -242,7 +209,6 @@ return Dest; } - static GenericValue executeOrInst(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; @@ -263,7 +229,6 @@ return Dest; } - static GenericValue executeXorInst(GenericValue Src1, GenericValue Src2, const Type *Ty) { GenericValue Dest; @@ -284,7 +249,6 @@ return Dest; } - #define IMPLEMENT_SETCC(OP, TY) \ case Type::TY##TyID: Dest.BoolVal = Src1.TY##Val OP Src2.TY##Val; break @@ -465,12 +429,6 @@ //===----------------------------------------------------------------------===// void Interpreter::exitCalled(GenericValue GV) { - if (!QuietMode) { - std::cout << "Program returned "; - print(Type::IntTy, GV); - std::cout << " via 'void exit(int)'\n"; - } - ExitCode = GV.SByteVal; ECStack.clear(); } @@ -486,45 +444,24 @@ Result = getOperandValue(I.getReturnValue(), SF); } - // Save previously executing meth - const Function *M = ECStack.back().CurFunction; - // Pop the current stack frame... this invalidates SF ECStack.pop_back(); if (ECStack.empty()) { // Finished main. Put result into exit code... - if (RetTy) { // Nonvoid return type? - if (!QuietMode) { - CW << "Function " << M->getType() << " \"" << M->getName() - << "\" returned "; - print(RetTy, Result); - std::cout << "\n"; - } - - if (RetTy->isIntegral()) - ExitCode = Result.IntVal; // Capture the exit code of the program + if (RetTy && RetTy->isIntegral()) { // Nonvoid return type? + ExitCode = Result.IntVal; // Capture the exit code of the program } else { ExitCode = 0; } - return; - } - - // If we have a previous stack frame, and we have a previous call, fill in - // the return value... - // - ExecutionContext &NewSF = ECStack.back(); - if (NewSF.Caller) { - if (NewSF.Caller->getType() != Type::VoidTy) // Save result... - SetValue(NewSF.Caller, Result, NewSF); - - NewSF.Caller = 0; // We returned from the call... - } else if (!QuietMode) { - // This must be a function that is executing because of a user 'call' - // instruction. - CW << "Function " << M->getType() << " \"" << M->getName() - << "\" returned "; - print(RetTy, Result); - std::cout << "\n"; + } else { + // If we have a previous stack frame, and we have a previous call, + // fill in the return value... + ExecutionContext &NewSF = ECStack.back(); + if (NewSF.Caller) { + if (NewSF.Caller->getType() != Type::VoidTy) // Save result... + SetValue(NewSF.Caller, Result, NewSF); + NewSF.Caller = 0; // We returned from the call... + } } } @@ -580,8 +517,6 @@ std::vector ResultValues; for (; PHINode *PN = dyn_cast(SF.CurInst); ++SF.CurInst) { - if (Trace) CW << "Run:" << PN; - // Search for the value corresponding to this previous bb... int i = PN->getBasicBlockIndex(PrevBB); assert(i != -1 && "PHINode doesn't contain entry for predecessor??"); @@ -598,7 +533,6 @@ SetValue(PN, ResultValues[i], SF); } - //===----------------------------------------------------------------------===// // Memory Instruction Implementations //===----------------------------------------------------------------------===// @@ -631,7 +565,6 @@ free(GVTOP(Value)); // Free memory } - // getElementOffset - The workhorse for getelementptr. // GenericValue Interpreter::executeGEPOperation(Value *Ptr, User::op_iterator I, @@ -655,22 +588,13 @@ Total += SLO->MemberOffsets[Index]; Ty = STy->getElementTypes()[Index]; } else if (const SequentialType *ST = cast(Ty)) { - // Get the index number for the array... which must be long type... assert((*I)->getType() == Type::LongTy); unsigned Idx = getOperandValue(*I, SF).LongVal; - if (const ArrayType *AT = dyn_cast(ST)) - if (Idx >= AT->getNumElements() && ArrayChecksEnabled) { - std::cerr << "Out of range memory access to element #" << Idx - << " of a " << AT->getNumElements() << " element array." - << " Subscript #" << *I << "\n"; - abort(); - } - Ty = ST->getElementType(); unsigned Size = TD.getTypeSize(Ty); Total += Size*Idx; - } + } } GenericValue Result; @@ -700,8 +624,6 @@ I.getOperand(0)->getType()); } - - //===----------------------------------------------------------------------===// // Miscellaneous Instruction Implementations //===----------------------------------------------------------------------===// @@ -846,7 +768,6 @@ return Dest; } - void Interpreter::visitCastInst(CastInst &I) { ExecutionContext &SF = ECStack.back(); SetValue(&I, executeCastOperation(I.getOperand(0), I.getType(), SF), SF); @@ -869,27 +790,6 @@ // Dispatch and Execution Code //===----------------------------------------------------------------------===// -FunctionInfo::FunctionInfo(Function *F) { - // Assign slot numbers to the function arguments... - for (Function::const_aiterator AI = F->abegin(), E = F->aend(); AI != E; ++AI) - AI->addAnnotation(new SlotNumber(getValueSlot(AI))); - - // Iterate over all of the instructions... - unsigned InstNum = 0; - for (Function::iterator BB = F->begin(), BBE = F->end(); BB != BBE; ++BB) - for (BasicBlock::iterator II = BB->begin(), IE = BB->end(); II != IE; ++II) - // For each instruction... Add Annote - II->addAnnotation(new InstNumber(++InstNum, getValueSlot(II))); -} - -unsigned FunctionInfo::getValueSlot(const Value *V) { - unsigned Plane = V->getType()->getUniqueID(); - if (Plane >= NumPlaneElements.size()) - NumPlaneElements.resize(Plane+1, 0); - return NumPlaneElements[Plane]++; -} - - //===----------------------------------------------------------------------===// // callFunction - Execute the specified function... // @@ -908,17 +808,7 @@ if (!ECStack.empty() && ECStack.back().Caller) { ExecutionContext &SF = ECStack.back(); SetValue(SF.Caller, Result, SF); - SF.Caller = 0; // We returned from the call... - } else if (!QuietMode) { - // print it. - CW << "Function " << F->getType() << " \"" << F->getName() - << "\" returned "; - print(RetTy, Result); - std::cout << "\n"; - - if (RetTy->isIntegral()) - ExitCode = Result.IntVal; // Capture the exit code of the program } } @@ -929,8 +819,6 @@ // the function. Also calculate the number of values for each type slot // active. // - FunctionInfo *&FuncInfo = FunctionInfoMap[F]; - if (!FuncInfo) FuncInfo = new FunctionInfo(F); // Make a new stack frame... and fill it in. ECStack.push_back(ExecutionContext()); @@ -938,18 +826,6 @@ StackFrame.CurFunction = F; StackFrame.CurBB = F->begin(); StackFrame.CurInst = StackFrame.CurBB->begin(); - StackFrame.FuncInfo = FuncInfo; - - // Initialize the values to nothing... - StackFrame.Values.resize(FuncInfo->NumPlaneElements.size()); - for (unsigned i = 0; i < FuncInfo->NumPlaneElements.size(); ++i) { - StackFrame.Values[i].resize(FuncInfo->NumPlaneElements[i]); - - // Taint the initial values of stuff - memset(&StackFrame.Values[i][0], 42, - FuncInfo->NumPlaneElements[i]*sizeof(GenericValue)); - } - // Run through the function arguments and initialize their values... assert((ArgVals.size() == F->asize() || @@ -965,55 +841,15 @@ StackFrame.VarArgs.assign(ArgVals.begin()+i, ArgVals.end()); } -// executeInstruction - Interpret a single instruction & increment the "PC". -// -void Interpreter::executeInstruction() { - assert(!ECStack.empty() && "No program running, cannot execute inst!"); - - ExecutionContext &SF = ECStack.back(); // Current stack frame - Instruction &I = *SF.CurInst++; // Increment before execute - - if (Trace) CW << "Run:" << I; - - // Track the number of dynamic instructions executed. - ++NumDynamicInsts; - - visit(I); // Dispatch to one of the visit* methods... - - // Reset the current frame location to the top of stack - CurFrame = ECStack.size()-1; -} - void Interpreter::run() { while (!ECStack.empty()) { - // Run an instruction... - executeInstruction(); - } -} + // Interpret a single instruction & increment the "PC". + ExecutionContext &SF = ECStack.back(); // Current stack frame + Instruction &I = *SF.CurInst++; // Increment before execute + + // Track the number of dynamic instructions executed. + ++NumDynamicInsts; -void Interpreter::printValue(const Type *Ty, GenericValue V) { - switch (Ty->getPrimitiveID()) { - case Type::BoolTyID: std::cout << (V.BoolVal?"true":"false"); break; - case Type::SByteTyID: - std::cout << (int)V.SByteVal << " '" << V.SByteVal << "'"; break; - case Type::UByteTyID: - std::cout << (unsigned)V.UByteVal << " '" << V.UByteVal << "'"; break; - case Type::ShortTyID: std::cout << V.ShortVal; break; - case Type::UShortTyID: std::cout << V.UShortVal; break; - case Type::IntTyID: std::cout << V.IntVal; break; - case Type::UIntTyID: std::cout << V.UIntVal; break; - case Type::LongTyID: std::cout << (long)V.LongVal; break; - case Type::ULongTyID: std::cout << (unsigned long)V.ULongVal; break; - case Type::FloatTyID: std::cout << V.FloatVal; break; - case Type::DoubleTyID: std::cout << V.DoubleVal; break; - case Type::PointerTyID:std::cout << (void*)GVTOP(V); break; - default: - std::cout << "- Don't know how to print value of this type!"; - break; + visit(I); // Dispatch to one of the visit* methods... } -} - -void Interpreter::print(const Type *Ty, GenericValue V) { - CW << Ty << " "; - printValue(Ty, V); } From brukman at cs.uiuc.edu Fri Oct 24 15:00:54 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Oct 24 15:00:54 2003 Subject: [llvm-commits] CVS: llvm/docs/CommandLine.html Message-ID: <200310241959.OAA22424@zion.cs.uiuc.edu> Changes in directory llvm/docs: CommandLine.html updated: 1.15 -> 1.16 --- Log message: * Use stylesheets and
    s for layout instead of + +
  • Internal vs External Storage
  • + +
  • Option Attributes
  • +
  • Option Modifiers + specified
  • +
  • Controlling other formatting options
  • +
  • Miscellaneous option modifiers
  • + +
  • Top-Level Classes and Functions +
  • The + cl::ParseCommandLineOptions function
  • +
  • The + cl::ParseEnvironmentOptions function
  • +
  • The cl::opt class
  • +
  • The cl::list class
  • +
  • The cl::alias class
  • + +
  • Builtin parsers - + parser<float> specializations
  • + +
  • Extension Guide
      -
    1. Writing a custom parser -
    2. Exploiting external storage -
    3. Dynamically adding command line options -
    - -

    Written by Chris Lattner

    -

    +

  • Writing a custom parser
  • +
  • Exploiting external storage
  • +
  • Dynamically adding command line + options
  • + + +
    +

    Written by Chris Lattner

    +
    - -
    -Introduction -
      +
      + Introduction +
      -This document describes the CommandLine argument processing library. It will +
      + +

      This document describes the CommandLine argument processing library. It will show you how to use it, and what it can do. The CommandLine library uses a declarative approach to specifying the command line options that your program takes. By default, these options declarations implicitly hold the value parsed for the option declared (of course this can be -changed).

      +changed).

      -Although there are a lot of command line argument parsing libraries out -there in many different languages, none of them fit well with what I needed. By -looking at the features and problems of other libraries, I designed the -CommandLine library to have the following features:

      +

      Although there are a lot of command line argument parsing libraries +out there in many different languages, none of them fit well with what I needed. +By looking at the features and problems of other libraries, I designed the +CommandLine library to have the following features:

      1. Speed: The CommandLine library is very quick and uses little resources. The @@ -98,43 +114,45 @@ parsed, not the the number of options recognized. Additionally, command line argument values are captured transparently into user defined global variables, which can be accessed like any other variable (and with the same -performance).

        +performance).

      2. Type Safe: As a user of CommandLine, you don't have to worry about remembering the type of arguments that you want (is it an int? a string? a bool? an enum?) and keep casting it around. Not only does this help prevent -error prone constructs, it also leads to dramatically cleaner source code.

        +error prone constructs, it also leads to dramatically cleaner source code.

      3. No subclasses required: To use CommandLine, you instantiate variables that correspond to the arguments that you would like to capture, you don't subclass a -parser. This means that you don't have to write any boilerplate code.

        +parser. This means that you don't have to write any boilerplate +code.

      4. Globally accessible: Libraries can specify command line arguments that are automatically enabled in any tool that links to the library. This is possible because the application doesn't have to keep a "list" of arguments to pass to the parser. This also makes supporting dynamically -loaded options trivial.

        +loaded options trivial.

      5. Cleaner: CommandLine supports enum and other types directly, meaning that there is less error and more security built into the library. You don't have to worry about whether your integral command line argument accidentally got -assigned a value that is not valid for your enum type.

        +assigned a value that is not valid for your enum type.

      6. Powerful: The CommandLine library supports many different types of arguments, from simple boolean flags to scalars arguments (strings, integers, enums, doubles), to lists of -arguments. This is possible because CommandLine is...

        +arguments. This is possible because CommandLine is...

      7. Extensible: It is very simple to add a new argument type to CommandLine. Simply specify the parser that you want to use with the command line option when -you declare it. Custom parsers are no problem.

        +you declare it. Custom parsers are no problem.

      8. Labor Saving: The CommandLine library cuts down on the amount of grunt work that you, the user, have to do. For example, it automatically provides a --help option that shows the available command line options for your -tool. Additionally, it does most of the basic correctness checking for you.

        +tool. Additionally, it does most of the basic correctness checking for +you.

      9. Capable: The CommandLine library can handle lots of different forms of options often found in real programs. For example, grouping options (to allow processing 'ls -lad' naturally), ld style prefix options (to parse '-lmalloc -L/usr/lib'), and interpreter style options.

        +href="#cl::ConsumeAfter">interpreter style options.

      -This document will hopefully let you jump in and start using CommandLine in your -utility quickly and painlessly. Additionally it should be a simple reference -manual to figure out how stuff works. If it is failing in some area (or you -want an extension to the library), nag the author, Chris Lattner.

      - +

      This document will hopefully let you jump in and start using CommandLine in +your utility quickly and painlessly. Additionally it should be a simple +reference manual to figure out how stuff works. If it is failing in some area +(or you want an extension to the library), nag the author, Chris Lattner.

      +
      -
    -Quick Start Guide -
      + -This section of the manual runs through a simple CommandLine'ification of a +
      + +

      This section of the manual runs through a simple CommandLine'ification of a basic compiler tool. This is intended to show you how to jump into using the CommandLine library in your own program, and show you some of the cool things it -can do.

      +can do.

      -To start out, you need to include the CommandLine header file into your -program:

      +

      To start out, you need to include the CommandLine header file into your +program:

         #include "Support/CommandLine.h"
      -

      + -Additionally, you need to add this as the first line of your main program:

      +

      Additionally, you need to add this as the first line of your main +program:

       int main(int argc, char **argv) {
         cl::ParseCommandLineOptions(argc, argv);
         ...
       }
      -

      + -... which actually parses the arguments and fills in the variable -declarations.

      +

      ... which actually parses the arguments and fills in the variable +declarations.

      -Now that you are ready to support command line arguments, we need to tell the +

      Now that you are ready to support command line arguments, we need to tell the system which ones we want, and what type of argument they are. The CommandLine library uses a declarative syntax to model command line arguments with the global variable declarations that capture the parsed values. This means that @@ -192,22 +213,23 @@ global variable declaration to capture the result. For example, in a compiler, we would like to support the unix standard '-o <filename>' option to specify where to put the output. With the CommandLine library, this is -represented like this:

      +represented like this:

      -
      
      -cl::opt<string> OutputFilename("o", cl::desc("Specify output filename"), cl::value_desc("filename"));
      -

      +

      + +cl::opt<string> OutputFilename("o", cl::desc("Specify output filename"), cl::value_desc("filename")); +

      -This declares a global variable "OutputFilename" that is used to +

      This declares a global variable "OutputFilename" that is used to capture the result of the "o" argument (first parameter). We specify that this is a simple scalar option by using the "cl::opt" template (as opposed to the "cl::list template), and tell the CommandLine library -that the data type that we are parsing is a string.

      +that the data type that we are parsing is a string.

      -The second and third parameters (which are optional) are used to specify what to -output for the "--help" option. In this case, we get a line that looks -like this:

      +

      The second and third parameters (which are optional) are used to specify what +to output for the "--help" option. In this case, we get a line that +looks like this:

       USAGE: compiler [options]
      @@ -217,40 +239,39 @@
         -o <filename>     - Specify output filename
       
      -Because we specified that the command line option should parse using the +

      Because we specified that the command line option should parse using the string data type, the variable declared is automatically usable as a real string in all contexts that a normal C++ string object may be used. For -example:

      +example:

         ...
         ofstream Output(OutputFilename.c_str());
         if (Out.good()) ...
         ...
      -

      + -There are many different options that you can use to customize the command line -option handling library, but the above example shows the general interface to -these options. The options can be specified in any order, and are specified +

      There are many different options that you can use to customize the command +line option handling library, but the above example shows the general interface +to these options. The options can be specified in any order, and are specified with helper functions like cl::desc(...), so there are no positional dependencies to remember. The available options are -discussed in detail in the Reference Guide.

      - +discussed in detail in the Reference Guide.

      -Continuing the example, we would like to have our compiler take an input +

      Continuing the example, we would like to have our compiler take an input filename as well as an output filename, but we do not want the input filename to be specified with a hyphen (ie, not -filename.c). To support this style of argument, the CommandLine library allows for positional arguments to be specified for the program. These positional arguments are filled with command line parameters that are not -in option form. We use this feature like this:

      +in option form. We use this feature like this:

       cl::opt<string> InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
       
      -This declaration indicates that the first positional argument should be treated -as the input filename. Here we use the This declaration indicates that the first positional argument should be +treated as the input filename. Here we use the cl::init option to specify an initial value for the command line option, which is used if the option is not specified (if you do not specify a cl::init modifier for an option, then @@ -258,26 +279,26 @@ Command line options default to being optional, so if we would like to require that the user always specify an input filename, we would add the cl::Required flag, and we could eliminate the -cl::init modifier, like this:

      +cl::init modifier, like this:

       cl::opt<string> InputFilename(cl::Positional, cl::desc("<input file>"), cl::Required);
       
      -Again, the CommandLine library does not require the options to be specified in -any particular order, so the above declaration is equivalent to:

      +

      Again, the CommandLine library does not require the options to be specified +in any particular order, so the above declaration is equivalent to:

       cl::opt<string> InputFilename(cl::Positional, cl::Required, cl::desc("<input file>"));
       
      -By simply adding the cl::Required flag, the -CommandLine library will automatically issue an error if the argument is not +

      By simply adding the cl::Required flag, +the CommandLine library will automatically issue an error if the argument is not specified, which shifts all of the command line option verification code out of your application into the library. This is just one example of how using flags can alter the default behaviour of the library, on a per-option basis. By adding one of the declarations above, the --help option synopsis is now -extended to:

      +extended to:

       USAGE: compiler [options] <input file>
      @@ -287,42 +308,44 @@
         -o <filename>     - Specify output filename
       
      -... indicating that an input filename is expected.

      - +

      ... indicating that an input filename is expected.

      +
      -
       -Boolean Arguments -
      + + +
      -In addition to input and output filenames, we would like the compiler example to -support three boolean flags: "-f" to force overwriting of the output +

      In addition to input and output filenames, we would like the compiler example +to support three boolean flags: "-f" to force overwriting of the output file, "--quiet" to enable quiet mode, and "-q" for backwards compatibility with some of our users. We can support these by declaring options -of boolean type like this:

      +of boolean type like this:

       cl::opt<bool> Force ("f", cl::desc("Overwrite output files"));
       cl::opt<bool> Quiet ("quiet", cl::desc("Don't print informational messages"));
       cl::opt<bool> Quiet2("q", cl::desc("Don't print informational messages"), cl::Hidden);
      -

      + -This does what you would expect: it declares three boolean variables +

      This does what you would expect: it declares three boolean variables ("Force", "Quiet", and "Quiet2") to recognize these options. Note that the "-q" option is specified with the "cl::Hidden" flag. This modifier prevents it from being shown by the standard "--help" output (note that it is still -shown in the "--help-hidden" output).

      +shown in the "--help-hidden" output).

      -The CommandLine library uses a different parser +

      The CommandLine library uses a different parser for different data types. For example, in the string case, the argument passed to the option is copied literally into the content of the string variable... we obviously cannot do that in the boolean case, however, so we must use a smarter parser. In the case of the boolean parser, it allows no options (in which case it assigns the value of true to the variable), or it allows the values "true" or "false" to be specified, allowing any of the -following inputs:

      +following inputs:

        compiler -f          # No value, 'Force' == true
      @@ -331,14 +354,14 @@
        compiler -f=FALSE    # Value specified, 'Force' == false
       
      -... you get the idea. The bool parser just turns the -string values into boolean values, and rejects things like 'compiler +

      ... you get the idea. The bool parser just turns +the string values into boolean values, and rejects things like 'compiler -f=foo'. Similarly, the float, double, and int parsers work like you would expect, using the 'strtol' and 'strtod' C -library calls to parse the string value into the specified data type.

      +library calls to parse the string value into the specified data type.

      -With the declarations above, "compiler --help" emits this:

      +

      With the declarations above, "compiler --help" emits this:

       USAGE: compiler [options] <input file>
      @@ -348,9 +371,9 @@
         -o     - Override output filename
         -quiet - Don't print informational messages
         -help  - display available options (--help-hidden for more)
      -

      + -and "opt --help-hidden" prints this:

      +

      and "opt --help-hidden" prints this:

       USAGE: compiler [options] <input file>
      @@ -361,96 +384,103 @@
         -q     - Don't print informational messages
         -quiet - Don't print informational messages
         -help  - display available options (--help-hidden for more)
      -

      + -This brief example has shown you how to use the 'This brief example has shown you how to use the 'cl::opt' class to parse simple scalar command line arguments. In addition to simple scalar arguments, the CommandLine library also provides primitives to support CommandLine option aliases, -and lists of options.

      +and lists of options.

      +
      -
       -Argument Aliases -
      + -So far, the example works well, except for the fact that we need to check the -quiet condition like this now:

      +

      + +

      So far, the example works well, except for the fact that we need to check the +quiet condition like this now:

       ...
         if (!Quiet && !Quiet2) printInformationalMessage(...);
       ...
      -

      + -... which is a real pain! Instead of defining two values for the same +

      ... which is a real pain! Instead of defining two values for the same condition, we can use the "cl::alias" class to make the "-q" option an alias for the "-quiet" option, instead of providing -a value itself:

      +a value itself:

       cl::opt<bool> Force ("f", cl::desc("Overwrite output files"));
       cl::opt<bool> Quiet ("quiet", cl::desc("Don't print informational messages"));
       cl::alias     QuietA("q", cl::desc("Alias for -quiet"), cl::aliasopt(Quiet));
      -

      + -The third line (which is the only one we modified from above) defines a +

      The third line (which is the only one we modified from above) defines a "-q alias that updates the "Quiet" variable (as specified by the cl::aliasopt modifier) whenever it is specified. Because aliases do not hold state, the only thing the program has to query is the Quiet variable now. Another nice feature of aliases is that they automatically hide themselves from the -help output (although, again, they are still visible in the --help-hidden -output).

      +output).

      -Now the application code can simply use:

      +

      Now the application code can simply use:

       ...
         if (!Quiet) printInformationalMessage(...);
       ...
      -

      - -... which is much nicer! The "cl::alias" can be used to specify an -alternative name for any variable type, and has many uses.

      + +

      ... which is much nicer! The "cl::alias" +can be used to specify an alternative name for any variable type, and has many +uses.

      +
      -
       -Selecting an alternative from a set of possibilities -
      + + +
      -So far, we have seen how the CommandLine library handles builtin types like +

      So far, we have seen how the CommandLine library handles builtin types like std::string, bool and int, but how does it handle -things it doesn't know about, like enums or 'int*'s?

      +things it doesn't know about, like enums or 'int*'s?

      -The answer is that it uses a table driven generic parser (unless you specify +

      The answer is that it uses a table driven generic parser (unless you specify your own parser, as described in the Extension Guide). This parser maps literal strings to whatever type is required, are -requires you to tell it what this mapping should be.

      +requires you to tell it what this mapping should be.

      -Lets say that we would like to add four optimizations levels to our optimizer, -using the standard flags "-g", "-O0", "-O1", and -"-O2". We could easily implement this with boolean options like above, -but there are several problems with this strategy:

      +

      Lets say that we would like to add four optimizations levels to our +optimizer, using the standard flags "-g", "-O0", +"-O1", and "-O2". We could easily implement this with boolean +options like above, but there are several problems with this strategy:

      1. A user could specify more than one of the options at a time, for example, "opt -O3 -O2". The CommandLine library would not be able to catch this -erroneous input for us. +erroneous input for us.
      2. -
      3. We would have to test 4 different variables to see which ones are set. +
      4. We would have to test 4 different variables to see which ones are set.
      5. This doesn't map to the numeric levels that we want... so we cannot easily -see if some level >= "-O1" is enabled. +see if some level >= "-O1" is enabled.
      6. -

      + -To cope with these problems, we can use an enum value, and have the CommandLine -library fill it in with the appropriate level directly, which is used like -this:

      +

      To cope with these problems, we can use an enum value, and have the +CommandLine library fill it in with the appropriate level directly, which is +used like this:

       enum OptLevel {
      @@ -468,16 +498,16 @@
       ...
         if (OptimizationLevel >= O2) doPartialRedundancyElimination(...);
       ...
      -

      + -This declaration defines a variable "OptimizationLevel" of the +

      This declaration defines a variable "OptimizationLevel" of the "OptLevel" enum type. This variable can be assigned any of the values that are listed in the declaration (Note that the declaration list must be terminated with the "0" argument!). The CommandLine library enforces that the user can only specify one of the options, and it ensure that only valid enum values can be specified. The "clEnumVal" macros ensure that the command line arguments matched the enum values. With this option added, our -help output now is:

      +help output now is:

       USAGE: compiler [options] <input file>
      @@ -494,10 +524,10 @@
         -quiet        - Don't print informational messages
       
      -In this case, it is sort of awkward that flag names correspond directly to enum -names, because we probably don't want a enum definition named "g" in -our program. Because of this, we can alternatively write this example like -this:

      +

      In this case, it is sort of awkward that flag names correspond directly to +enum names, because we probably don't want a enum definition named "g" +in our program. Because of this, we can alternatively write this example like +this:

       enum OptLevel {
      @@ -515,28 +545,30 @@
       ...
         if (OptimizationLevel == Debug) outputDebugInfo(...);
       ...
      -

      - -By using the "clEnumValN" macro instead of "clEnumVal", we can -directly specify the name that the flag should get. In general a direct mapping -is nice, but sometimes you can't or don't want to preserve the mapping, which is -when you would use it.

      + +

      By using the "clEnumValN" macro instead of "clEnumVal", we +can directly specify the name that the flag should get. In general a direct +mapping is nice, but sometimes you can't or don't want to preserve the mapping, +which is when you would use it.

      +
      -
       -Named Alternatives -
      + + +
      -Another useful argument form is a named alternative style. We shall use this +

      Another useful argument form is a named alternative style. We shall use this style in our compiler to specify different debug levels that can be used. Instead of each debug level being its own switch, we want to support the following options, of which only one can be specified at a time: "--debug-level=none", "--debug-level=quick", "--debug-level=detailed". To do this, we use the exact same format as our optimization level flags, but we also specify an option name. For this -case, the code looks like this:

      +case, the code looks like this:

       enum DebugLev {
      @@ -552,10 +584,10 @@
           0));
       
      -This definition defines an enumerated command line variable of type "enum +

      This definition defines an enumerated command line variable of type "enum DebugLev", which works exactly the same way as before. The difference here is just the interface exposed to the user of your program and the help output by -the "--help" option:

      +the "--help" option:

       USAGE: compiler [options] <input file>
      @@ -574,38 +606,40 @@
         -help         - display available options (--help-hidden for more)
         -o <filename> - Specify output filename
         -quiet        - Don't print informational messages
      -

      + -Again, the only structural difference between the debug level declaration and +

      Again, the only structural difference between the debug level declaration and the optimiation level declaration is that the debug level declaration includes an option name ("debug_level"), which automatically changes how the library processes the argument. The CommandLine library supports both forms so -that you can choose the form most appropriate for your application.

      - +that you can choose the form most appropriate for your application.

      +
      -
       -Parsing a list of options -
      + + +
      -Now that we have the standard run of the mill argument types out of the way, +

      Now that we have the standard run of the mill argument types out of the way, lets get a little wild and crazy. Lets say that we want our optimizer to accept a list of optimizations to perform, allowing duplicates. For example, we might want to run: "compiler -dce -constprop -inline -dce -strip". In this case, the order of the arguments and the number of appearances is very important. This is what the "cl::list" template is for. First, start by defining an enum of the optimizations that you -would like to perform:

      +would like to perform:

       enum Opts {
         // 'inline' is a C++ keyword, so name it 'inlining'
         dce, constprop, inlining, strip
       };
      -

      + -Then define your "cl::list" variable:

      +

      Then define your "cl::list" variable:

       cl::list<Opts> OptimizationList(cl::desc("Available Optimizations:"),
      @@ -615,11 +649,11 @@
          clEnumValN(inlining, "inline", "Procedure Integration"),
           clEnumVal(strip             , "Strip Symbols"),
         0));
      -

      + -This defines a variable that is conceptually of the type +

      This defines a variable that is conceptually of the type "std::vector<enum Opts>". Thus, you can access it with standard -vector methods:

      +vector methods:

         for (unsigned i = 0; i != OptimizationList.size(); ++i)
      @@ -627,37 +661,39 @@
              ...
       
      -... to iterate through the list of options specified.

      +

      ... to iterate through the list of options specified.

      -Note that the "cl::list" template is completely general and may be used -with any data types or other arguments that you can use with the -"cl::opt" template. One especially useful way to use a list is to -capture all of the positional arguments together if there may be more than one -specified. In the case of a linker, for example, the linker takes several -'.o' files, and needs to capture them into a list. This is naturally -specified as:

      +

      Note that the "cl::list" template is +completely general and may be used with any data types or other arguments that +you can use with the "cl::opt" template. One +especially useful way to use a list is to capture all of the positional +arguments together if there may be more than one specified. In the case of a +linker, for example, the linker takes several '.o' files, and needs to +capture them into a list. This is naturally specified as:

       ...
       cl::list<std::string> InputFilenames(cl::Positional, cl::desc("<Input files>"), cl::OneOrMore);
       ...
      -

      + -This variable works just like a "vector<string>" object. As +

      This variable works just like a "vector<string>" object. As such, accessing the list is simple, just like above. In this example, we used the cl::OneOrMore modifier to inform the CommandLine library that it is an error if the user does not specify any .o files on our command line. Again, this just reduces the amount of -checking we have to do.

      - +checking we have to do.

      +
      -
       -Adding freeform text to help output -
      + -As our program grows and becomes more mature, we may decide to put summary +
      + +

      As our program grows and becomes more mature, we may decide to put summary information about what it does into the help output. The help output is styled to look similar to a Unix man page, providing concise information about a program. Unix man pages, however often have a description about what @@ -666,7 +702,7 @@ href="#cl::ParseCommandLineOptions">cl::ParseCommandLineOptions call in main. This additional argument is then printed as the overview information for your program, allowing you to include any additional information -that you want. For example:

      +that you want. For example:

       int main(int argc, char **argv) {
      @@ -674,9 +710,9 @@
                                     "  This program blah blah blah...\n");
         ...
       }
      -

      + -Would yield the help output: +

      Would yield the help output:

       OVERVIEW: CommandLine compiler example
      @@ -689,42 +725,47 @@
         ...
         -help             - display available options (--help-hidden for more)
         -o <filename>     - Specify output filename
      -

      - + +

      -
    -Reference Guide -
      + -Now that you know the basics of how to use the CommandLine library, this section -will give you the detailed information you need to tune how command line options -work, as well as information on more "advanced" command line option processing -capabilities.

      +

      + +

      Now that you know the basics of how to use the CommandLine library, this +section will give you the detailed information you need to tune how command line +options work, as well as information on more "advanced" command line option +processing capabilities.

      +
      -
       -Positional Arguments -
      + -Positional arguments are those arguments that are not named, and are not +
      + +

      Positional arguments are those arguments that are not named, and are not specified with a hyphen. Positional arguments should be used when an option is specified by its position alone. For example, the standard Unix grep tool takes a regular expression argument, and an optional filename to search through (which defaults to standard input if a filename is not specified). -Using the CommandLine library, this would be specified as:

      +Using the CommandLine library, this would be specified as:

       cl::opt<string> Regex   (cl::Positional, cl::desc("<regular expression>"), cl::Required);
       cl::opt<string> Filename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
       
      -Given these two option declarations, the --help output for our grep -replacement would look like this:

      +

      Given these two option declarations, the --help output for our grep +replacement would look like this:

       USAGE: spiffygrep [options] <regular expression> <input file>
      @@ -733,25 +774,30 @@
         -help - display available options (--help-hidden for more)
       
      -... and the resultant program could be used just like the standard grep -tool.

      +

      ... and the resultant program could be used just like the standard +grep tool.

      -Positional arguments are sorted by their order of construction. This means that -command line options will be ordered according to how they are listed in a .cpp -file, but will not have an ordering defined if they positional arguments are -defined in multiple .cpp files. The fix for this problem is simply to define -all of your positional arguments in one .cpp file.

      +

      Positional arguments are sorted by their order of construction. This means +that command line options will be ordered according to how they are listed in a +.cpp file, but will not have an ordering defined if they positional arguments +are defined in multiple .cpp files. The fix for this problem is simply to +define all of your positional arguments in one .cpp file.

      +
      -


    Specifying positional options with hyphens

      + + +
      -Sometimes you may want to specify a value to your positional argument that +

      Sometimes you may want to specify a value to your positional argument that starts with a hyphen (for example, searching for '-foo' in a file). At first, you will have trouble doing this, because it will try to find an argument named '-foo', and will fail (and single quotes will not save you). -Note that the system grep has the same problem:

      +Note that the system grep has the same problem:

         $ spiffygrep '-foo' test.txt
      @@ -762,45 +808,49 @@
         grep: illegal option -- o
         grep: illegal option -- o
         Usage: grep -hblcnsviw pattern file . . .
      -

      + -The solution for this problem is the same for both your tool and the system +

      The solution for this problem is the same for both your tool and the system version: use the '--' marker. When the user specifies '--' on the command line, it is telling the program that all options after the '--' should be treated as positional arguments, not options. Thus, we -can use it like this:

      +can use it like this:

         $ spiffygrep -- -foo test.txt
           ...output...
      -

      - + +

      -


    The cl::ConsumeAfter modifier

      + -The cl::ConsumeAfter formatting option is +
      + +

      The cl::ConsumeAfter formatting option is used to construct programs that use "interpreter style" option processing. With this style of option processing, all arguments specified after the last positional argument are treated as special interpreter arguments that are not -interpreted by the command line argument.

      +interpreted by the command line argument.

      -As a concrete example, lets say we are developing a replacement for the standard -Unix Bourne shell (/bin/sh). To run /bin/sh, first you -specify options to the shell itself (like -x which turns on trace +

      As a concrete example, lets say we are developing a replacement for the +standard Unix Bourne shell (/bin/sh). To run /bin/sh, first +you specify options to the shell itself (like -x which turns on trace output), then you specify the name of the script to run, then you specify arguments to the script. These arguments to the script are parsed by the bourne shell command line option processor, but are not interpreted as options to the -shell itself. Using the CommandLine library, we would specify this as:

      +shell itself. Using the CommandLine library, we would specify this as:

       cl::opt<string> Script(cl::Positional, cl::desc("<input script>"), cl::init("-"));
       cl::list<string>  Argv(cl::ConsumeAfter, cl::desc("<program arguments>..."));
       cl::opt<bool>    Trace("x", cl::desc("Enable trace output"));
      -

      + -which automatically provides the help output:

      +

      which automatically provides the help output:

       USAGE: spiffysh [options] <input script> <program arguments>...
      @@ -808,43 +858,45 @@
       OPTIONS:
         -help - display available options (--help-hidden for more)
         -x    - Enable trace output
      -

      + -At runtime, if we run our new shell replacement as 'spiffysh -x test.sh -a --x -y bar', the Trace variable will be set to true, the +

      At runtime, if we run our new shell replacement as 'spiffysh -x test.sh +-a -x -y bar', the Trace variable will be set to true, the Script variable will be set to "test.sh", and the -Argv list will contain ["-a", "-x", "-y", "bar"], because -they were specified after the last positional argument (which is the script -name).

      - -There are several limitations to when cl::ConsumeAfter options can be -specified. For example, only one cl::ConsumeAfter can be specified per -program, there must be at least one positional +Argv list will contain ["-a", "-x", "-y", "bar"], because they +were specified after the last positional argument (which is the script +name).

      + +

      There are several limitations to when cl::ConsumeAfter options can +be specified. For example, only one cl::ConsumeAfter can be specified +per program, there must be at least one positional argument specified, and the cl::ConsumeAfter option should be a cl::list option.

      - +href="#cl::list">cl::list option.

      +
      -
       -Internal vs External Storage -
      + + +
      -By default, all command line options automatically hold the value that they +

      By default, all command line options automatically hold the value that they parse from the command line. This is very convenient in the common case, especially when combined with the ability to define command line options in the -files that use them. This is called the internal storage model.

      +files that use them. This is called the internal storage model.

      -Sometimes, however, it is nice to separate the command line option processing +

      Sometimes, however, it is nice to separate the command line option processing code from the storage of the value parsed. For example, lets say that we have a '-debug' option that we would like to use to enable debug information across the entire body of our program. In this case, the boolean value controlling the debug code should be globally accessable (in a header file, for example) yet the command line option processing code should not be exposed to all of these clients (requiring lots of .cpp files to #include -CommandLine.h).

      +CommandLine.h).

      -To do this, set up your .h file with your option, like this for example:

      +

      To do this, set up your .h file with your option, like this for example:

       // DebugFlag.h - Get access to the '-debug' command line option
      @@ -863,19 +915,20 @@
       //
       // DEBUG(cerr << "Bitset contains: " << Bitset << "\n");
       //
      -#ifdef NDEBUG
      +#ifdef NDEBUG
       #define DEBUG(X)
       #else
      -#define DEBUG(X) \
      +#define DEBUG(X) \
         do { if (DebugFlag) { X; } } while (0)
      -#endif
      +#endif
       
      -This allows clients to blissfully use the DEBUG() macro, or the +

      This allows clients to blissfully use the DEBUG() macro, or the DebugFlag explicitly if they want to. Now we just need to be able to set the DebugFlag boolean when the option is set. To do this, we pass an additial argument to our command line argument processor, and we specify -where to fill in with the cl::location attribute:

      +where to fill in with the cl::location +attribute:

       bool DebugFlag;      // the actual value
      @@ -884,41 +937,46 @@
             cl::location(DebugFlag));
       
      -In the above example, we specify "true" as the second argument to the -cl::opt template, indicating that the template should not -maintain a copy of the value itself. In addition to this, we specify the In the above example, we specify "true" as the second argument to +the cl::opt template, indicating that the template should +not maintain a copy of the value itself. In addition to this, we specify the cl::location attribute, so that DebugFlag is -automatically set.

      - +automatically set.

      +
      -
       -Option Attributes -
       -Option Modifiers -


    Hiding an option from --help output


    Controlling the number of occurances required and allowed


    Controlling whether or not a value must be specified

      + + +
      -This group of options is used to control whether or not the option allows a +

      This group of options is used to control whether or not the option allows a value to be present. In the case of the CommandLine library, a value is either specified with an equal sign (e.g. '-index-depth=17') or as a trailing -string (e.g. '-o a.out').

      +string (e.g. '-o a.out').

      -The allowed values for this option group are:

      +

      The allowed values for this option group are:

      -In general, the default values for this option group work just like you would +

      In general, the default values for this option group work just like you would want them to. As mentioned above, you can specify the cl::ValueDisallowed modifier to a boolean argument to restrict your command line parser. These options are mostly useful -when extending the library.

      - +when extending the library.

      +
      -


    Controlling other formatting options


    Miscellaneous option modifiers

       -Top-Level Classes and Functions -


    The -cl::ParseCommandLineOptions function

      + + +
      -The cl::ParseCommandLineOptions function is designed to be called +

      The cl::ParseCommandLineOptions function is designed to be called directly from main, and is used to fill in the values of all of the command line option variables once argc and argv are -available.

      +available.

      -The cl::ParseCommandLineOptions function requires two parameters +

      The cl::ParseCommandLineOptions function requires two parameters (argc and argv), but may also take an optional third parameter which holds additional extra text to emit when the ---help option is invoked.

      +--help option is invoked.

      +
      -


    The -cl::ParseEnvironmentOptions function

      + + +
      + +

      The cl::ParseEnvironmentOptions function has mostly the same effects +as cl::ParseCommandLineOptions, +except that it is designed to take values for options from an environment +variable, for those cases in which reading the command line is not convenient or +not desired. It fills in the values of all the command line option variables +just like cl::ParseCommandLineOptions +does.

      -The cl::ParseEnvironmentOptions -function has mostly the same effects as -cl::ParseCommandLineOptions, -except that it is designed to take values for options from an -environment variable, for those cases in which reading the -command line is not convenient or not desired. It fills in -the values of all the command line option variables just like -cl::ParseCommandLineOptions -does.

      - -It takes three parameters: first, the name of the program (since argv -may not be available, it can't just look in argv[0]), second, -the name of the environment variable to examine, and third, the optional +

      It takes three parameters: first, the name of the program (since +argv may not be available, it can't just look in argv[0]), +second, the name of the environment variable to examine, and third, the optional additional extra text to emit when the ---help option is invoked.

      +--help option is invoked.

      -cl::ParseEnvironmentOptions will break the environment +

      cl::ParseEnvironmentOptions will break the environment variable's value up into words and then process them using cl::ParseCommandLineOptions. Note: Currently cl::ParseEnvironmentOptions does not support quoting, so an environment variable containing -option "foo bar" will be parsed as three words, -option, "foo, and bar", which is different from what you would get from the shell with the same -input.

      +input.

      + +
      -


    The cl::opt class

      + + +
      -The cl::opt class is the class used to represent scalar command line +

      The cl::opt class is the class used to represent scalar command line options, and is the one used most of the time. It is a templated class which can take up to three arguments (all except for the first have default values -though):

      +though):

       namespace cl {
      @@ -1258,28 +1380,33 @@
                   class ParserClass = parser<DataType> >
         class opt;
       }
      -

      + -The first template argument specifies what underlying data type the command line -argument is, and is used to select a default parser implementation. The second -template argument is used to specify whether the option should contain the -storage for the option (the default) or whether external storage should be used -to contain the value parsed for the option (see Internal vs -External Storage for more information).

      +

      The first template argument specifies what underlying data type the command +line argument is, and is used to select a default parser implementation. The +second template argument is used to specify whether the option should contain +the storage for the option (the default) or whether external storage should be +used to contain the value parsed for the option (see Internal +vs External Storage for more information).

      -The third template argument specifies which parser to use. The default value +

      The third template argument specifies which parser to use. The default value selects an instantiation of the parser class based on the underlying data type of the option. In general, this default works well for most applications, so this option is only used when using a custom parser.

      +href="#customparser">custom parser.

      +
      -


    The cl::list class

      + -The cl::list class is the class used to represent a list of command +
      + +

      The cl::list class is the class used to represent a list of command line options. It too is a templated class which can take up to three -arguments:

      +arguments:

       namespace cl {
      @@ -1287,135 +1414,162 @@
                   class ParserClass = parser<DataType> >
         class list;
       }
      -

      + -This class works the exact same as the cl::opt -class, except that the second argument is the type of the external -storage, not a boolean value. For this class, the marker type 'bool' -is used to indicate that internal storage should be used.

      +

      This class works the exact same as the cl::opt class, except that the second argument is +the type of the external storage, not a boolean value. For this class, +the marker type 'bool' is used to indicate that internal storage should +be used.

      +
      -


    The cl::alias class

      + -The cl::alias class is a nontemplated class that is used to form -aliases for other arguments.

      +

      + +

      The cl::alias class is a nontemplated class that is used to form +aliases for other arguments.

       namespace cl {
         class alias;
       }
      -

      + -The cl::aliasopt attribute should be used -to specify which option this is an alias for. Alias arguments default to being -Hidden, and use the aliased options parser to do the -conversion from string to data.

      +

      The cl::aliasopt attribute should be +used to specify which option this is an alias for. Alias arguments default to +being Hidden, and use the aliased options parser to do +the conversion from string to data.

      +
      -
       -Builtin parsers -
      - -Parsers control how the string value taken from the command line is translated -into a typed value, suitable for use in a C++ program. By default, the -CommandLine library uses an instance of parser<type> if the + + +
      + +

      Parsers control how the string value taken from the command line is +translated into a typed value, suitable for use in a C++ program. By default, +the CommandLine library uses an instance of parser<type> if the command line option specifies that it uses values of type 'type'. Because of this, custom option processing is specified with specializations of -the 'parser' class.

      +the 'parser' class.

      -The CommandLine library provides the following builtin parser specializations, -which are sufficient for most applications. It can, however, also be extended to -work with new data types and new ways of interpreting the same data. See the Writing a Custom Parser for more details on this type -of library extension.

      +

      The CommandLine library provides the following builtin parser +specializations, which are sufficient for most applications. It can, however, +also be extended to work with new data types and new ways of interpreting the +same data. See the Writing a Custom Parser for more +details on this type of library extension.

      -
    • The generic parser<t> parser + +
    • -
    -Extension Guide -
      + -Although the CommandLine library has a lot of functionality built into it +
      + +

      Although the CommandLine library has a lot of functionality built into it already (as discussed previously), one of its true strengths lie in its extensibility. This section discusses how the CommandLine library works under -the covers and illustrates how to do some simple, common, extensions.

      +the covers and illustrates how to do some simple, common, extensions.

      +
      -
    -
       Writing a custom parser -
      + + +
      -One of the simplest and most common extensions is the use of a custom parser. +

      One of the simplest and most common extensions is the use of a custom parser. As discussed previously, parsers are the portion of the CommandLine library that turns string input from the user into a -particular parsed data type, validating the input in the process.

      +particular parsed data type, validating the input in the process.

      -There are two ways to use a new parser:

      +

      There are two ways to use a new parser:

        -
      1. Specialize the cl::parser template for - your custom data type.

        - This approach has the advantage that users of your custom data type will - automatically use your custom parser whenever they define an option with a - value type of your data type. The disadvantage of this approach is that it - doesn't work if your fundemental data type is something that is already - supported.

        - -

      2. Write an independent class, using it explicitly from options that need - it.

        - - This approach works well in situations where you would line to parse an - option using special syntax for a not-very-special data-type. The drawback - of this approach is that users of your parser have to be aware that they are - using your parser, instead of the builtin ones.

        +

      3. + +

        Specialize the cl::parser template for +your custom data type.

        + +

        This approach has the advantage that users of your custom data type will +automatically use your custom parser whenever they define an option with a value +type of your data type. The disadvantage of this approach is that it doesn't +work if your fundemental data type is something that is already supported.

        + +
      4. + +
      5. + +

        Write an independent class, using it explicitly from options that need +it.

        -

      +

      This approach works well in situations where you would line to parse an +option using special syntax for a not-very-special data-type. The drawback of +this approach is that users of your parser have to be aware that they are using +your parser, instead of the builtin ones.

      -To guide the discussion, we will discuss a custom parser that accepts file + + + + +

      To guide the discussion, we will discuss a custom parser that accepts file sizes, specified with an optional unit after the numeric size. For example, we would like to parse "102kb", "41M", "1G" into the appropriate integer value. In this case, the underlying data type we want to parse into is 'unsigned'. We choose approach #2 above because we don't want to make -this the default for all unsigned options.

      +this the default for all unsigned options.

      -To start out, we declare our new FileSizeParser class:

      +

      To start out, we declare our new FileSizeParser class:

       struct FileSizeParser : public cl::basic_parser<unsigned> {
      @@ -1423,18 +1577,21 @@
         bool parse(cl::Option &O, const char *ArgName, const std::string &ArgValue,
                    unsigned &Val);
       };
      -

      + -Our new class inherits from the cl::basic_parser template class to fill -in the default, boiler plate, code for us. We give it the data type that we -parse into (the last argument to the parse method so that clients of +

      Our new class inherits from the cl::basic_parser template class to +fill in the default, boiler plate, code for us. We give it the data type that +we parse into (the last argument to the parse method so that clients of our custom parser know what object type to pass in to the parse method (here we -declare that we parse into 'unsigned' variables.

      +declare that we parse into 'unsigned' variables.

      -For most purposes, the only method that must be implemented in a custom parser -is the parse method. The parse method is called whenever the -option is invoked, passing in the option itself, the option name, the string to -parse, and a reference to a return value. If the string to parse is not well formed, the parser should output an error message and return true. Otherwise it should return false and set 'Val' to the parsed value. In our example, we implement parse as:

      +

      For most purposes, the only method that must be implemented in a custom +parser is the parse method. The parse method is called +whenever the option is invoked, passing in the option itself, the option name, +the string to parse, and a reference to a return value. If the string to parse +is not well formed, the parser should output an error message and return true. +Otherwise it should return false and set 'Val' to the parsed value. In +our example, we implement parse as:

       bool FileSizeParser::parse(cl::Option &O, const char *ArgName,
      @@ -1462,32 +1619,32 @@
           }
         }
       }
      -

      + -This function implements a very simple parser for the kinds of strings we are +

      This function implements a very simple parser for the kinds of strings we are interested in. Although it has some holes (it allows "123KKK" for example), it is good enough for this example. Note that we use the option itself to print out the error message (the error method always returns true) in order to get a nice error message (shown below). Now that we have our -parser class, we can use it like this:

      +parser class, we can use it like this:

       static cl::opt<unsigned, false, FileSizeParser>
       MFS("max-file-size", cl::desc("Maximum file size to accept"),
           cl::value_desc("size"));
      -

      + -Which adds this to the output of our program:

      +

      Which adds this to the output of our program:

       OPTIONS:
         -help                 - display available options (--help-hidden for more)
         ...
         -max-file-size=<size> - Maximum file size to accept
      -

      + -And we can test that our parse works correctly now (the test program just prints -out the max-file-size argument value):

      +

      And we can test that our parse works correctly now (the test program just +prints out the max-file-size argument value):

       $ ./test
      @@ -1498,41 +1655,43 @@
       MFS: 3221225472
       $ ./test -max-file-size=dog
       -max-file-size option: 'dog' value invalid for file size argument!
      -

      + -It looks like it works. The error message that we get is nice and helpful, and -we seem to accept reasonable file sizes. This wraps up the "custom parser" -tutorial.

      +

      It looks like it works. The error message that we get is nice and helpful, +and we seem to accept reasonable file sizes. This wraps up the "custom parser" +tutorial.

      +
      -
    -
       Exploiting external -storage
    -
       Dynamically adding command -line options
      +
    + + +
    +

    TODO: fill in this section

    +
    - -
    - + + + + From gaeke at cs.uiuc.edu Fri Oct 24 15:01:14 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Fri Oct 24 15:01:14 2003 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/Interpreter/Interpreter.h Message-ID: <200310241959.OAA04320@gally.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/Interpreter: Interpreter.h updated: 1.45 -> 1.46 --- Log message: ExecutionEngine::create no longer takes a TraceMode argument. CurFrame, TraceMode, and the CachedWriter are history. The ExecutionAnnotations (SlotNumber, InstNumber, and FunctionInfo) are history. ExecutionContext now keeps Values for each stack frame in a std::map. printValue() and print() are history. executeInstruction() is now part of run(). --- Diffs of the changes: (+4 -18) Index: llvm/lib/ExecutionEngine/Interpreter/Interpreter.h diff -u llvm/lib/ExecutionEngine/Interpreter/Interpreter.h:1.45 llvm/lib/ExecutionEngine/Interpreter/Interpreter.h:1.46 --- llvm/lib/ExecutionEngine/Interpreter/Interpreter.h:1.45 Tue Oct 21 10:17:13 2003 +++ llvm/lib/ExecutionEngine/Interpreter/Interpreter.h Fri Oct 24 14:59:37 2003 @@ -15,15 +15,12 @@ #define LLI_INTERPRETER_H #include "llvm/BasicBlock.h" -#include "llvm/Assembly/CachedWriter.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/ExecutionEngine/GenericValue.h" #include "llvm/Support/InstVisitor.h" #include "llvm/Target/TargetData.h" #include "Support/DataTypes.h" -extern CachedWriter CW; // Object to accelerate printing of LLVM - struct FunctionInfo; // Defined in ExecutionAnnotations.h // AllocaHolder - Object to track all of the blocks of memory allocated by @@ -65,10 +62,8 @@ Function *CurFunction;// The currently executing function BasicBlock *CurBB; // The currently executing BB BasicBlock::iterator CurInst; // The next instruction to execute - FunctionInfo *FuncInfo; // The FuncInfo annotation for the function - std::vector Values;// ValuePlanes for each type + std::map Values; // LLVM values used in this invocation std::vector VarArgs; // Values passed through an ellipsis - CallInst *Caller; // Holds the call that called subframes. // NULL if main func or debugger invoked fn AllocaHolderHandle Allocas; // Track memory allocated by alloca @@ -78,8 +73,6 @@ // class Interpreter : public ExecutionEngine, public InstVisitor { int ExitCode; // The exit code to be returned by the lli util - bool Trace; // Tracing enabled? - int CurFrame; // The current stack frame being inspected TargetData TD; // The runtime stack of executing code. The top of the stack is the current @@ -90,11 +83,9 @@ // registered with the atexit() library function. std::vector AtExitHandlers; - std::map FunctionInfoMap; public: - Interpreter(Module *M, bool isLittleEndian, bool isLongPointer, - bool TraceMode); - inline ~Interpreter() { CW.setModule(0); } + Interpreter(Module *M, bool isLittleEndian, bool isLongPointer); + inline ~Interpreter() { } /// runAtExitHandlers - Run any functions registered by the /// program's calls to atexit(3), which we intercept and store in @@ -104,21 +95,16 @@ /// create - Create an interpreter ExecutionEngine. This can never fail. /// - static ExecutionEngine *create(Module *M, bool TraceMode); + static ExecutionEngine *create(Module *M); /// run - Start execution with the specified function and arguments. /// virtual GenericValue run(Function *F, const std::vector &ArgValues); - // Methods used for debug printouts: - static void print(const Type *Ty, GenericValue V); - static void printValue(const Type *Ty, GenericValue V); - // Methods used to execute code: // Place a call on the stack void callFunction(Function *F, const std::vector &ArgVals); - void executeInstruction(); // Execute one instruction void run(); // Execute instructions until nothing left to do // Opcode Implementations From gaeke at cs.uiuc.edu Fri Oct 24 15:02:03 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Fri Oct 24 15:02:03 2003 Subject: [llvm-commits] CVS: llvm/tools/gccld/gccld.cpp Message-ID: <200310242000.PAA04376@gally.cs.uiuc.edu> Changes in directory llvm/tools/gccld: gccld.cpp updated: 1.57 -> 1.58 --- Log message: lli -q is history. Rebuild your gccld shell scripts, folks! --- Diffs of the changes: (+1 -1) Index: llvm/tools/gccld/gccld.cpp diff -u llvm/tools/gccld/gccld.cpp:1.57 llvm/tools/gccld/gccld.cpp:1.58 --- llvm/tools/gccld/gccld.cpp:1.57 Mon Oct 20 12:58:43 2003 +++ llvm/tools/gccld/gccld.cpp Fri Oct 24 15:00:06 2003 @@ -298,7 +298,7 @@ if (!Out2.good()) return PrintAndReturn(argv[0], "error opening '" + OutputFilename + "' for writing!"); - Out2 << "#!/bin/sh\nlli -q $0.bc $*\n"; + Out2 << "#!/bin/sh\nlli $0.bc $*\n"; Out2.close(); } From gaeke at cs.uiuc.edu Fri Oct 24 15:02:20 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Fri Oct 24 15:02:20 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/Makefile.programs Message-ID: <200310242000.PAA04354@gally.cs.uiuc.edu> Changes in directory llvm/test/Programs: Makefile.programs updated: 1.99 -> 1.100 --- Log message: lli -q is history. Rebuild your gccld shell scripts, folks! --- Diffs of the changes: (+1 -1) Index: llvm/test/Programs/Makefile.programs diff -u llvm/test/Programs/Makefile.programs:1.99 llvm/test/Programs/Makefile.programs:1.100 --- llvm/test/Programs/Makefile.programs:1.99 Fri Oct 24 13:09:48 2003 +++ llvm/test/Programs/Makefile.programs Fri Oct 24 14:59:56 2003 @@ -281,7 +281,7 @@ # of the JIT and LLI in order to get timing info and statistics. EXTRA_LLI_OPTS = -LLI_OPTS = -q -force-interpreter=true $(EXTRA_LLI_OPTS) +LLI_OPTS = -force-interpreter=true $(EXTRA_LLI_OPTS) JIT_OPTS = -force-interpreter=false $(EXTRA_LLI_OPTS) native: $(PROGRAMS_TO_TEST:%=Output/%.native) From gaeke at cs.uiuc.edu Fri Oct 24 15:02:37 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Fri Oct 24 15:02:37 2003 Subject: [llvm-commits] CVS: llvm/tools/lli/lli.cpp Message-ID: <200310242000.PAA04395@gally.cs.uiuc.edu> Changes in directory llvm/tools/lli: lli.cpp updated: 1.32 -> 1.33 --- Log message: TraceMode, as you may have heard, is history. ExecutionEngine::create no longer takes a TraceMode argument. --- Diffs of the changes: (+1 -3) Index: llvm/tools/lli/lli.cpp diff -u llvm/tools/lli/lli.cpp:1.32 llvm/tools/lli/lli.cpp:1.33 --- llvm/tools/lli/lli.cpp:1.32 Mon Oct 20 15:40:30 2003 +++ llvm/tools/lli/lli.cpp Fri Oct 24 15:00:17 2003 @@ -39,8 +39,6 @@ MainFunction("f", cl::desc("Function to execute"), cl::init("main"), cl::value_desc("function name")); - cl::opt TraceMode("trace", cl::desc("Enable Tracing")); - cl::opt ForceInterpreter("force-interpreter", cl::desc("Force interpretation: disable JIT"), cl::init(false)); @@ -137,7 +135,7 @@ } ExecutionEngine *EE = - ExecutionEngine::create(MP, ForceInterpreter, TraceMode); + ExecutionEngine::create(MP, ForceInterpreter); assert(EE && "Couldn't create an ExecutionEngine, not even an interpreter?"); // Add the module's name to the start of the vector of arguments to main(). From lattner at cs.uiuc.edu Fri Oct 24 15:07:09 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Oct 24 15:07:09 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAllocLocal.cpp Message-ID: <200310242006.PAA22583@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocLocal.cpp updated: 1.29 -> 1.30 --- Log message: standardize command line option names --- Diffs of the changes: (+1 -1) Index: llvm/lib/CodeGen/RegAllocLocal.cpp diff -u llvm/lib/CodeGen/RegAllocLocal.cpp:1.29 llvm/lib/CodeGen/RegAllocLocal.cpp:1.30 --- llvm/lib/CodeGen/RegAllocLocal.cpp:1.29 Mon Oct 20 14:43:15 2003 +++ llvm/lib/CodeGen/RegAllocLocal.cpp Fri Oct 24 15:05:58 2003 @@ -29,7 +29,7 @@ namespace { Statistic<> NumSpilled ("ra-local", "Number of registers spilled"); Statistic<> NumReloaded("ra-local", "Number of registers reloaded"); - cl::opt DisableKill("no-kill", cl::Hidden, + cl::opt DisableKill("disable-kill", cl::Hidden, cl::desc("Disable register kill in local-ra")); class RA : public MachineFunctionPass { From lattner at cs.uiuc.edu Fri Oct 24 15:11:08 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Oct 24 15:11:08 2003 Subject: [llvm-commits] CVS: poolalloc/runtime/PoolAllocator/PoolAllocatorChained.cpp Message-ID: <200310242010.PAA23610@zion.cs.uiuc.edu> Changes in directory poolalloc/runtime/PoolAllocator: PoolAllocatorChained.cpp updated: 1.8 -> 1.9 --- Log message: Add a fast-path for allocation: this speeds up treeadd by 30% --- Diffs of the changes: (+25 -13) Index: poolalloc/runtime/PoolAllocator/PoolAllocatorChained.cpp diff -u poolalloc/runtime/PoolAllocator/PoolAllocatorChained.cpp:1.8 poolalloc/runtime/PoolAllocator/PoolAllocatorChained.cpp:1.9 --- poolalloc/runtime/PoolAllocator/PoolAllocatorChained.cpp:1.8 Fri Oct 24 14:56:44 2003 +++ poolalloc/runtime/PoolAllocator/PoolAllocatorChained.cpp Fri Oct 24 15:10:20 2003 @@ -14,7 +14,6 @@ #include "PoolAllocator.h" #include -#include #include #undef assert @@ -150,29 +149,43 @@ assert(Pool && "Null pool pointer passed in to poolalloc!\n"); unsigned NodeSize = Pool->NodeSize; - PoolSlab *PS = (PoolSlab*)Pool->Slabs; + PoolSlab *CurPoolSlab = (PoolSlab*)Pool->Slabs; - void *Result; - if ((Result = FindSlabEntry(PS, NodeSize))) - return Result; + // Fastpath for allocation in the common case. + if (CurPoolSlab && !CurPoolSlab->isSingleArray && + CurPoolSlab->LastUsed < NODES_PER_SLAB-1) { + // Mark the returned entry used + CurPoolSlab->markNodeAllocated(CurPoolSlab->LastUsed+1); + CurPoolSlab->setStartBit(CurPoolSlab->LastUsed+1); + + // If we are allocating out the first unused field, bump its index also + if (CurPoolSlab->FirstUnused == (unsigned)CurPoolSlab->LastUsed+1) + CurPoolSlab->FirstUnused++; + + // Return the entry, increment LastUsed field. + return &CurPoolSlab->Data[0] + ++CurPoolSlab->LastUsed * NodeSize; + } - /* Otherwise we must allocate a new slab and add it to the list */ - PS = (PoolSlab*)malloc(sizeof(PoolSlab)+NodeSize*NODES_PER_SLAB-1); + if (void *Result = FindSlabEntry(CurPoolSlab, NodeSize)) + return Result; + // Otherwise we must allocate a new slab and add it to the list + PoolSlab *PS = (PoolSlab*)malloc(sizeof(PoolSlab)+NodeSize*NODES_PER_SLAB-1); assert(PS && "poolalloc: Could not allocate memory!"); - /* Initialize the slab to indicate that the first element is allocated */ + // Initialize the slab to indicate that the first element is allocated PS->FirstUnused = 1; PS->LastUsed = 0; - /* This is not a single array */ + + // This is not a single array PS->isSingleArray = 0; PS->ArraySize = 0; PS->markNodeAllocated(0); PS->setStartBit(0); - /* Add the slab to the list... */ - PS->Next = (PoolSlab*)Pool->Slabs; + // Add the slab to the list... + PS->Next = CurPoolSlab; Pool->Slabs = PS; return &PS->Data[0]; } @@ -389,8 +402,7 @@ PoolSlab *PS = (PoolSlab*)Pool->Slabs; - void *Result; - if ((Result = FindSlabEntryArray(PS, NodeSize,Size))) + if (void *Result = FindSlabEntryArray(PS, NodeSize,Size)) return Result; /* Otherwise we must allocate a new slab and add it to the list */ From criswell at cs.uiuc.edu Fri Oct 24 15:18:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Oct 24 15:18:01 2003 Subject: [llvm-commits] [release_1] CVS: llvm/docs/FAQ.html Message-ID: <200310242017.PAA02859@choi.cs.uiuc.edu> Changes in directory llvm/docs: FAQ.html updated: 1.1.2.1 -> 1.1.2.2 --- Log message: Added an answer about running the tests. --- Diffs of the changes: (+14 -0) Index: llvm/docs/FAQ.html diff -u llvm/docs/FAQ.html:1.1.2.1 llvm/docs/FAQ.html:1.1.2.2 --- llvm/docs/FAQ.html:1.1.2.1 Thu Oct 23 15:23:00 2003 +++ llvm/docs/FAQ.html Fri Oct 24 15:17:46 2003 @@ -138,6 +138,20 @@ cases, this takes care of the problem. To do this, just type make clean and then make in the directory that fails to build.

    + +

    I've built LLVM and am testing it, but the tests freeze. +
    + This is most likely occurring because you built a profile or release + (optimized) build of LLVM and have not specified the same information on + the gmake command line. +

    + For example, if you built LLVM with the command: +

    + gmake ENABLE_PROFILING=1 +

    + ...then you must run the tests with the following commands: +

    + cd llvm/test
    gmake ENABLE_PROFILING=1


    From criswell at cs.uiuc.edu Fri Oct 24 15:21:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Oct 24 15:21:01 2003 Subject: [llvm-commits] CVS: llvm-www/releases/1.0/llvm.tar.gz Message-ID: <200310242020.PAA03303@choi.cs.uiuc.edu> Changes in directory llvm-www/releases/1.0: llvm.tar.gz updated: 1.5 -> 1.6 --- Log message: Updated the FAQ. --- Diffs of the changes: (+0 -0) Index: llvm-www/releases/1.0/llvm.tar.gz From criswell at cs.uiuc.edu Fri Oct 24 15:52:03 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Oct 24 15:52:03 2003 Subject: [llvm-commits] CVS: llvm-www/releases/1.0/AliasAnalysis.html CFEBuildInstrs.html CodingStandards.html CommandLine.html DSGraphStatus.html FAQ.html GettingStarted.html HowToSubmitABug.html LangRef.html OpenProjects.html ProgrammersManual.html Projects.html ReleaseNotes.html ReleaseTasks.html TestingGuide.html WritingAnLLVMPass.html download.html register.cgi register.html index.html Message-ID: <200310242051.PAA09917@choi.cs.uiuc.edu> Changes in directory llvm-www/releases/1.0: AliasAnalysis.html added (r1.1) CFEBuildInstrs.html added (r1.1) CodingStandards.html added (r1.1) CommandLine.html added (r1.1) DSGraphStatus.html added (r1.1) FAQ.html added (r1.1) GettingStarted.html added (r1.1) HowToSubmitABug.html added (r1.1) LangRef.html added (r1.1) OpenProjects.html added (r1.1) ProgrammersManual.html added (r1.1) Projects.html added (r1.1) ReleaseNotes.html added (r1.1) ReleaseTasks.html added (r1.1) TestingGuide.html added (r1.1) WritingAnLLVMPass.html added (r1.1) download.html added (r1.1) register.cgi added (r1.1) register.html added (r1.1) index.html updated: 1.1 -> 1.2 --- Log message: Added documentation to the release section of the website. Also adding registration script. --- Diffs of the changes: (+12737 -1) Index: llvm-www/releases/1.0/AliasAnalysis.html diff -c /dev/null llvm-www/releases/1.0/AliasAnalysis.html:1.1 *** /dev/null Fri Oct 24 15:51:50 2003 --- llvm-www/releases/1.0/AliasAnalysis.html Fri Oct 24 15:51:39 2003 *************** *** 0 **** --- 1,505 ---- + + + + + + Alias Analysis Infrastructure in LLVM + + + + +
    + Alias Analysis Infrastructure in LLVM +
    + +
      +
    1. Introduction
    2. + +
    3. AliasAnalysis Overview
    4. + + +
    5. Writing a new AliasAnalysis Implementation
    6. + + +
    7. Using AliasAnalysis results
    8. + +
    9. Helpful alias analysis related tools
    10. + + + +

      Written by Chris Lattner

      +
    + + + + + + +
    +

    + Alias Analysis (or Pointer Analysis) is a technique which attempts to determine + whether or not two pointers ever can point to the same object in memory. + Traditionally, Alias Analyses respond to a query with either a Must, May, or No alias response, indicating that two + pointers do point to the same object, might point to the same object, or are + known not to point to the same object. +

    +

    + The AliasAnalysis class is the + centerpiece of the LLVM Alias Analysis related infrastructure. This class is + the common interface between clients of alias analysis information and the + implementations providing it. In addition to simple alias analysis information, + this class exposes Mod/Ref information from those implementations which can + provide it, allowing for powerful analyses and transformations to work well + together. +

    +

    + This document contains information necessary to successfully implement this + interface, use it, and to test both sides. It also explains some of the finer + points about what exactly results mean. If you feel that something is unclear + or should be added, please let me + know. +

    +
    + + + + + +
    +

    + The AliasAnalysis class defines + the interface that Alias Analysis implementations should support. This class + exports two important enums: AliasResult and ModRefResult + which represent the result of an alias query or a mod/ref query, + respectively. +

    +

    + The AliasAnalysis interface exposes information about memory, represented in + several different ways. In particular, memory objects are represented as a + starting address and size, and function calls are represented as the actual + call or invoke instructions that performs the call. The + AliasAnalysis interface also exposes some helper methods which allow you to get + mod/ref information for arbitrary instructions. +

    +
    + + + + +
    +

    + Most importantly, the AliasAnalysis class provides several methods which are + used to query whether or not pointers alias, whether function calls can modify + or read memory, etc. +

    +

    + Representing memory objects as a starting address and a size is critically + important for precise Alias Analyses. For example, consider this (silly) C + code: +

    +

    +

    +   int i;
    +   char C[2];
    +   char A[10]; 
    +   /* ... */
    +   for (i = 0; i != 10; ++i) {
    +     C[0] = A[i];          /* One byte store */
    +     C[1] = A[9-i];        /* One byte store */
    +   }
    + 
    +

    +

    + In this case, the basicaa pass will disambiguate the stores to + C[0] and C[1] because they are accesses to two distinct + locations one byte apart, and the accesses are each one byte. In this case, the + LICM pass can use store motion to remove the stores from the loop. In + constrast, the following code: +

    +

    +

    +   int i;
    +   char C[2];
    +   char A[10]; 
    +   /* ... */
    +   for (i = 0; i != 10; ++i) {
    +     ((short*)C)[0] = A[i];  /* Two byte store! */
    +     C[1] = A[9-i];          /* One byte store */
    +   }
    + 
    +

    +

    + In this case, the two stores to C do alias each other, because the access to the + &C[0] element is a two byte access. If size information wasn't + available in the query, even the first case would have to conservatively assume + that the accesses alias. +

    +
    + + + + +
    +

    + An Alias Analysis implementation can return one of three responses: MustAlias, + MayAlias, and NoAlias. The No and May alias results are obvious: if the two + pointers may never equal each other, return NoAlias, if they might, return + MayAlias. +

    +

    + The Must Alias response is trickier though. In LLVM, the Must Alias response + may only be returned if the two memory objects are guaranteed to always start at + exactly the same location. If two memory objects overlap, but do not start at + the same location, MayAlias must be returned. +

    +
    + + + + +
    +

    + The getModRefInfo methods return information about whether the + execution of an instruction can read or modify a memory location. Mod/Ref + information is always conservative: if an action may read a location, Ref + is returned. +

    +
    + + + + + +
    +

    + Writing a new alias analysis implementation for LLVM is quite straight-forward. + There are already several implementations that you can use for examples, and the + following information should help fill in any details. For a minimal example, + take a look at the no-aa + implementation. +

    +
    + + + + +
    +

    + The first step to determining what type of LLVM + pass you need to use for your Alias Analysis. As is the case with most + other analyses and transformations, the answer should be fairly obvious from + what type of problem you are trying to solve: +

    +

    +

      +
    1. If you require interprocedural analysis, it should be a + Pass.
    2. +
    3. If you are a global analysis, subclass FunctionPass.
    4. +
    5. If you are a local pass, subclass BasicBlockPass.
    6. +
    7. If you don't need to look at the program at all, subclass + ImmutablePass.
    8. +
    +

    +

    + In addition to the pass that you subclass, you should also inherit from the + AliasAnalysis interface, of course, and use the + RegisterAnalysisGroup template to register as an implementation of + AliasAnalysis. +

    +
    + + + + +
    +

    + Your subclass of AliasAnalysis is required to invoke two methods on the + AliasAnalysis base class: getAnalysisUsage and + InitializeAliasAnalysis. In particular, your implementation of + getAnalysisUsage should explicitly call into the + AliasAnalysis::getAnalysisUsage method in addition to doing any + declaring any pass dependencies your pass has. Thus you should have something + like this: +

    +

    +

    +     void getAnalysisUsage(AnalysisUsage &AU) const {
    +       AliasAnalysis::getAnalysisUsage(AU);
    +       // declare your dependencies here.
    +     }
    + 
    +

    +

    + Additionally, your must invoke the InitializeAliasAnalysis method from + your analysis run method (run for a Pass, + runOnFunction for a FunctionPass, runOnBasicBlock for + a BasicBlockPass, or InitializeAliasAnalysis for an + ImmutablePass). For example (as part of a Pass): +

    +

    +

    +     bool run(Module &M) {
    +       InitializeAliasAnalysis(this);
    +       // Perform analysis here...
    +       return false;
    +     }
    + 
    +

    +
    + + + + +
    +

    + All of the AliasAnalysis virtual + methods default to providing conservatively correct information (returning "May" + Alias and "Mod/Ref" for alias and mod/ref queries respectively). Depending on + the capabilities of the analysis you are implementing, you just override the + interfaces you can improve. +

    +
    + + + + +
    +

    + With only two special exceptions (the basicaa and no-aa passes) every alias analysis pass should chain + to another alias analysis implementation (for example, you could specify + "-basic-aa -ds-aa -andersens-aa -licm" to get the maximum benefit from + the three alias analyses). To do this, simply "Require" AliasAnalysis in your + getAnalysisUsage method, and if you need to return a conservative + MayAlias or Mod/Ref result, simply chain to a lower analysis. +

    +
    + + + + +
    +

    + From the LLVM perspective, the only thing you need to do to provide an efficient + alias analysis is to make sure that alias analysis queries are serviced + quickly. The actual calculation of the alias analysis results (the "run" + method) is only performed once, but many (perhaps duplicate) queries may be + performed. Because of this, try to move as much computation to the run method + as possible (within reason). +

    +
    + + + + + +
    +

    + There are several different ways to use alias analysis results. In order of + preference, these are... +

    +
    + + + + +
    +

    + The load-vn pass uses alias analysis to provide value numbering + information for load instructions. If your analysis or transformation + can be modelled in a form that uses value numbering information, you don't have + to do anything special to handle load instructions: just use the + load-vn pass, which uses alias analysis. +

    +
    + + + + +
    +

    + Many transformations need information about alias sets that are active in + some scope, rather than information about pairwise aliasing. The AliasSetTracker class is used + to efficiently build these Alias Sets from the pairwise alias analysis + information provided by the AliasAnalysis interface. +

    +

    + First you initialize the AliasSetTracker by use the "add" methods to + add information about various potentially aliasing instructions in the scope you + are interested in. Once all of the alias sets are completed, your pass should + simply iterate through the constructed alias sets, using the AliasSetTracker + begin()/end() methods. +

    +

    + The AliasSets formed by the AliasSetTracker are guaranteed to + be disjoint, calculate mod/ref information for the set, and keep track of + whether or not all of the pointers in the set are Must aliases. The + AliasSetTracker also makes sure that sets are properly folded due to call + instructions, and can provide a list of pointers in each set. +

    +

    + As an example user of this, the Loop + Invariant Code Motion pass uses AliasSetTrackers to build alias information + about each loop nest. If an AliasSet in a loop is not modified, then all load + instructions from that set may be hoisted out of the loop. If any alias sets + are stored and are must alias sets, then the stores may be sunk to + outside of the loop. Both of these transformations obviously only apply if the + pointer argument is loop-invariant. +

    +
    + + + + +
    +

    + As a last resort, your pass could use the AliasAnalysis interface directly to + service your pass. If you find the need to do this, please let me know so I can see if something new + needs to be added to LLVM. +

    +
    + + + + + +
    +

    + If you're going to be working with the AliasAnalysis infrastructure, there are + several nice tools that may be useful for you and are worth knowing about... +

    +
    + + + + +
    +

    + The -no-aa analysis is just like what it sounds: an alias analysis that + never returns any useful information. This pass can be useful if you think that + alias analysis is doing something wrong and are trying to narrow down a problem. + If you don't specify an alias analysis, the default will be to use the + basicaa pass which does quite a bit of disambiguation on its own. +

    +
    + + + + + +
    +

    + The -print-alias-sets pass is exposed as part of the analyze + tool to print out the Alias Sets formed by the AliasSetTracker class. This is useful if you're using + the AliasSetTracker. +

    +
    + + + + +
    +

    + The -count-aa pass is useful to see how many queries a particular pass + is making and what kinds of responses are returned by the alias analysis. An + example usage is: +

    +

    +

    +   $ opt -basicaa -count-aa -ds-aa -count-aa -licm
    + 
    +

    +

    + Which will print out how many queries (and what responses are returned) by the + -licm pass (of the -ds-aa pass) and how many queries are made + of the -basicaa pass by the -ds-aa pass. This can be useful + when evaluating an alias analysis for precision. +

    +
    + + + + +
    +

    + The -aa-eval pass simply iterates through all pairs of pointers in a + function and asks an alias analysis whether or not the pointers alias. This + gives an indication of the precision of the alias analysis. Statistics are + printed. +

    +
    + + + +
    + +
    Chris Lattner
    + The LLVM Compiler Infrastructure +
    + Last modified: $Date: 2003/10/24 20:51:39 $ +
    + + Index: llvm-www/releases/1.0/CFEBuildInstrs.html diff -c /dev/null llvm-www/releases/1.0/CFEBuildInstrs.html:1.1 *** /dev/null Fri Oct 24 15:51:50 2003 --- llvm-www/releases/1.0/CFEBuildInstrs.html Fri Oct 24 15:51:39 2003 *************** *** 0 **** --- 1,166 ---- + + + + + + Bootstrapping the C/C++ Front-End + + + +
    + Bootstrapping the C/C++ Front-End +
    + +

    This document is intended to explain the process of building the LLVM + C/C++ front-end, based on GCC 3.4, from source.

    + +

    NOTE: This is currently a somewhat fragile, error-prone + process, and you should only try to do it if +

      +
    • (A) you really, really, really can't use the binaries we distribute +
    • (B) you need GCC to fix some of the header files on your system +
    • (C) you are an elite GCC hacker.

      +
    + +

    We welcome patches to help make this process simpler.

    + + + + + +
    +

    +

      +
    1. Configure and build the LLVM libraries and tools using:

      +
      +  % cd llvm
      +  % ./configure [options...]
      +  % gmake tools-only
      + 
      +

      The use of the non-default target "tools-only" means that the + LLVM tools and libraries will build, and the binaries will be + deposited in llvm/tools/Debug, but the runtime (bytecode) + libraries will not build.

    2. + +
    3. Add the directory containing the tools to your PATH.

      +
      +  % set path = ( `cd llvm/tools/Debug && pwd` $path )
      + 
    4. + +
    5. Unpack the C/C++ front-end source into cfrontend/src.

    6. + +
    7. Edit src/configure. Change the first line (starting w/ #!) to + contain the correct full pathname of sh.

    8. + +
    9. Make "build" and "install" directories as siblings of the "src" + tree.

      +
      +  % pwd
      +  /usr/local/example/cfrontend/src
      +  % cd ..
      +  % mkdir build install
      +  % set CFEINSTALL = `pwd`/install
      + 
    10. + +
    11. Configure, build and install the C front-end:

      +
      +  % cd build
      +  % ../src/configure --prefix=$CFEINSTALL --disable-nls --disable-shared \
      +    --enable-languages=c,c++
      +  % gmake all-gcc
      +  % setenv LLVM_LIB_SEARCH_PATH `pwd`/gcc 
      +  % gmake all; gmake install
      + 
      + +

      Common Problem: You may get error messages regarding the fact + that LLVM does not support inline assembly. Here are two common + fixes:

      + +
        +
      • Fix 1: If you have system header files that include + inline assembly, you may have to modify them to remove the inline + assembly, and install the modified versions in + $CFEINSTALL/target-triplet/sys-include.

      • + +
      • Fix 2: If you are building the C++ front-end on a CPU we + haven't tried yet, you will probably have to edit the appropriate + version of atomicity.h under + src/libstdc++-v3/config/cpu/name-of-cpu/atomicity.h + and apply a patch so that it does not use inline assembly.

      • +
      + +

      Porting to a new architecture: If you are porting the new front-end + to a new architecture, or compiling in a different configuration that we have + previously, there are probably several changes you will have to make to the GCC + target to get it to work correctly. These include:

      + +

        +
      • Often targets include special or assembler linker flags which + gccas/gccld does not understand. In general, these can + just be removed.
      • +
      • LLVM currently does not support any floating point values other than + 32-bit and 64-bit IEEE floating point. The primary effect of this is + that you may have to map "long double" onto "double".
      • +
      • The profiling hooks in GCC do not apply at all to the LLVM front-end. + These may need to be disabled.
      • +
      • No inline assembly for position independent code. At the LLVM level, + everything is position independent.
      • +
      • We handle .init and .fini differently.
      • +
      • You may have to disable multilib support in your target. Using multilib + support causes the GCC compiler driver to add a lot of "-L" + options to the link line, which do not relate to LLVM and confuse + gccld. To disable multilibs, delete any + MULTILIB_OPTIONS lines from your target files.
      • +
      • Did we mention that we don't support inline assembly? You'll probably + have to add some fixinclude hacks to disable it in the system + headers.
      • +
      +
    12. + +
    13. Go back into the LLVM source tree proper. Edit Makefile.config + to redefine LLVMGCCDIR to the full pathname of the + $CFEINSTALL directory, which is the directory you just + installed the C front-end into. (The ./configure script is likely to + have set this to a directory which does not exist on your system.)

    14. + +
    15. If you edited header files during the C/C++ front-end build as + described in "Fix 1" above, you must now copy those header files from + $CFEINSTALL/target-triplet/sys-include to + $CFEINSTALL/lib/gcc/target-triplet/3.4-llvm/include. + (This should be the "include" directory in the same directory as the + libgcc.a library, which you can find by running + $CFEINSTALL/bin/gcc --print-libgcc-file-name.)

    16. + +
    17. Build and install the runtime (bytecode) libraries by running:

      +
      +  % gmake -C runtime
      +  % mkdir $CFEINSTALL/bytecode-libs
      +  % gmake -C runtime install
      +  % setenv LLVM_LIB_SEARCH_PATH $CFEINSTALL/bytecode-libs
      + 
    18. + +
    19. Test the newly-installed C frontend by one or more of the + following means:

      +
        +
      • compiling and running a "hello, LLVM" program in C and C++.
      • +
      • running the tests under test/Programs using gmake -C + test/Programs
      • +
      +

      +
    20. +
    +
    + + + +
    +
    Brian Gaeke
    + The LLVM Compiler Infrastructure +
    + Last modified: $Date: 2003/10/24 20:51:39 $ +
    + + + Index: llvm-www/releases/1.0/CodingStandards.html diff -c /dev/null llvm-www/releases/1.0/CodingStandards.html:1.1 *** /dev/null Fri Oct 24 15:51:50 2003 --- llvm-www/releases/1.0/CodingStandards.html Fri Oct 24 15:51:39 2003 *************** *** 0 **** --- 1,841 ---- + + A Few Coding Standards + + + + +
      A Few Coding Standards
    + +
      +
    1. Introduction +
    2. Mechanical Source Issues +
        +
      1. Source Code Formatting +
          +
        1. Commenting +
        2. Comment Formatting +
        3. #include Style +
        4. Source Code Width +
        5. Use Spaces Instead of Tabs +
        6. Indent Code Consistently +
        +
      2. Compiler Issues +
          +
        1. Treat Compiler Warnings Like Errors +
        2. Which C++ features can I use? +
        3. Write Portable Code +
        +
      +
    3. Style Issues +
        +
      1. The High Level Issues +
          +
        1. A Public Header File is a Module +
        2. #include as Little as Possible +
        3. Keep "internal" Headers Private +
        +
      2. The Low Level Issues +
          +
        1. Assert Liberally +
        2. Prefer Preincrement +
        3. Avoid endl +
        4. Exploit C++ to its Fullest +
        +
      3. Writing Iterators +
      +
    4. See Also +

    + + + +
    + Introduction +

    + Mechanical Source Issues +
      + + + +
       + Source Code Formatting +
      + + + +


    Commenting

      + + Comments are one critical part of readability and maintainability. Everyone + knows they should comment, so should you. :) Although we all should probably + comment our code more than we do, there are a few very critical places that + documentation is very useful:

      + +

        +

      1. File Headers
      2. + Every source file should have a header on it that describes the basic purpose of + the file. If a file does not have a header, it should not be checked into CVS. + Most source trees will probably have a standard file header format. The + standard format for the LLVM source tree looks like this:

        + +

        + //===-- llvm/Instruction.h - Instruction class definition -------*- C++ -*-===//
        + //
        + // This file contains the declaration of the Instruction class, which is the
        + // base class for all of the VM instructions.
        + //
        + //===----------------------------------------------------------------------===//
        + 
        + + A few things to note about this particular format. The "-*- C++ -*-" + string on the first line is there to tell Emacs that the source file is a C++ + file, not a C file (Emacs assumes .h files are C files by default [Note that tag + this is not necessary in .cpp files]). The name of the file is also on the + first line, along with a very short description of the purpose of the file. + This is important when printing out code and flipping though lots of pages.

        + + The main body of the description does not have to be very long in most cases. + Here it's only two lines. If an algorithm is being implemented or something + tricky is going on, a reference to the paper where it is published should be + included, as well as any notes or "gotchas" in the code to watch out for.

        + + +

      3. Class overviews
      4. + + Classes are one fundemental part of a good object oriented design. As such, a + class definition should have a comment block that explains what the class is + used for... if it's not obvious. If it's so completely obvious your grandma + could figure it out, it's probably safe to leave it out. Naming classes + something sane goes a long ways towards avoiding writing documentation. :)

        + + +

      5. Method information
      6. + + Methods defined in a class (as well as any global functions) should also be + documented properly. A quick note about what it does any a description of the + borderline behaviour is all that is necessary here (unless something + particularly tricky or insideous is going on). The hope is that people can + figure out how to use your interfaces without reading the code itself... that is + the goal metric.

        + + Good things to talk about here are what happens when something unexpected + happens: does the method return null? Abort? Format your hard disk?

        +

      + + + +


    Comment Formatting

      + + In general, prefer C++ style (//) comments. They take less space, + require less typing, don't have nesting problems, etc. There are a few cases + when it is useful to use C style (/* */) comments however:

      + +

        +
      1. When writing a C code: Obviously if you are writing C code, use C style + comments. :) +
      2. When writing a header file that may be #included by a C source file. +
      3. When writing a source file that is used by a tool that only accepts C style + comments. +

      + + To comment out a large block of code, use #if 0 and #endif. + These nest properly and are better behaved in general than C style comments.

      + + +


    #include Style


    Source Code Width

      + + Write your code to fit within 80 columns of text. This helps those of us who like to print out code and look at your code in an xterm without resizing it. + + + +


    Use Spaces Instead of Tabs


    Indent Code Consistently

      + + Okay, your first year of programming you were told that indentation is + important. If you didn't believe and internalize this then, now is the time. + Just do it.

      + + + + + +

       + Compiler Issues +
      + + + +


    Treat Compiler Warnings Like Errors

      + + If your code has compiler warnings in it, something is wrong: you aren't casting + values correctly, your have "questionable" constructs in your code, or you are + doing something legitimately wrong. Compiler warnings can cover up legitimate + errors in output and make dealing with a translation unit difficult.

      + + It is not possible to prevent all warnings from all compilers, nor is it + desirable. Instead, pick a standard compiler (like gcc) that provides + a good thorough set of warnings, and stick to them. At least in the case of + gcc, it is possible to work around any spurious errors by changing the + syntax of the code slightly. For example, an warning that annoys me occurs when + I write code like this:

      + +

      +   if (V = getValue()) {
      +     ..
      +   }
      + 

      + + gcc will warn me that I probably want to use the == operator, + and that I probably mistyped it. In most cases, I haven't, and I really don't + want the spurious errors. To fix this particular problem, I rewrite the code + like this:

      + +

      +   if ((V = getValue())) {
      +     ..
      +   }
      + 

      + + ...which shuts gcc up. Any gcc warning that annoys you can be + fixed by massaging the code appropriately.

      + + These are the gcc warnings that I prefer to enable: -Wall -Winline + -W -Wwrite-strings -Wno-unused

      + + + +


    Which C++ features can I use?

      + + Compilers are finally catching up to the C++ standard. Most compilers implement + most features, so you can use just about any features that you would like. In + the LLVM source tree, I have chosen to not use these features:

      + +

        +
      1. Exceptions: Exceptions are very useful for error reporting and handling + exceptional conditions. I do not use them in LLVM because they do have an + associated performance impact (by restricting restructuring of code), and parts + of LLVM are designed for performance critical purposes.

        + + Just like most of the rules in this document, this isn't a hard and fast + requirement. Exceptions are used in the Parser, because it simplifies error + reporting significantly, and the LLVM parser is not at all in the + critical path.

        + +

      2. RTTI: RTTI has a large cost in terms of executable size, and compilers are + not yet very good at stomping out "dead" class information blocks. Because of + this, typeinfo and dynamic cast are not used. +

      + + Other features, such as templates (without partial specialization) can be used + freely. The general goal is to have clear, consise, performant code... if a + technique assists with that then use it.

      + + + +


    Write Portable Code

      + + In almost all cases, it is possible and within reason to write completely + portable code. If there are cases where it isn't possible to write portable + code, isolate it behind a well defined (and well documented) interface.

      + + In practice, this means that you shouldn't assume much about the host compiler, + including its support for "high tech" features like partial specialization of + templates. In fact, Visual C++ 6 could be an important target for our work in + the future, and we don't want to have to rewrite all of our code to support + it.

      + + + + +

    + Style Issues +
      + + + + +
       + The High Level Issues +
      + + + +


    A Public Header File is a Module


    #include as Little as Possible

      + + #include hurts compile time performance. Don't do it unless you have + to, especially in header files.

      + + But wait, sometimes you need to have the definition of a class to use it, or to + inherit from it. In these cases go ahead and #include that header file. Be + aware however that there are many cases where you don't need to have the full + definition of a class. If you are using a pointer or reference to a class, you + don't need the header file. If you are simply returning a class instance from a + prototyped function or method, you don't need it. In fact, for most cases, you + simply don't need the definition of a class... and not #include'ing + speeds up compilation.

      + + It is easy to try to go too overboard on this recommendation, however. You + must include all of the header files that you are using, either directly + or indirectly (through another header file). To make sure that you don't + accidently forget to include a header file in your module header, make sure to + include your module header first in the implementation file (as mentioned + above). This way there won't be any hidden dependencies that you'll find out + about later...

      + + + +


    Keep "internal" Headers Private

      + + Many modules have a complex implementation that causes them to use more than one + implementation (.cpp) file. It is often tempting to put the internal + communication interface (helper classes, extra functions, etc) in the public + module header file. Don't do this. :)

      + + If you really need to do something like this, put a private header file in the + same directory as the source files, and include it locally. This ensures that + your private interface remains private and undisturbed by outsiders.

      + + Note however, that it's okay to put extra implementation methods a public class + itself... just make them private (or protected), and all is well.

      + + + +

       + The Low Level Issues +
      + + + +


    Assert Liberally

      + + Use the "assert" function to its fullest. Check all of your + preconditions and assumptions, you never know when a bug (not neccesarily even + yours) might be caught early by an assertion, which reduces debugging time + dramatically. The "<cassert>" header file is probably already + included by the header files you are using, so it doesn't cost anything to use + it.

      + + To further assist with debugging, make sure to put some kind of error message in + the assertion statement (which is printed if the assertion is tripped). This + helps the poor debugging make sense of why an assertion is being made and + enforced, and hopefully what to do about it. Here is one complete example:

      + +

      +   inline Value *getOperand(unsigned i) { 
      +     assert(i < Operands.size() && "getOperand() out of range!");
      +     return Operands[i]; 
      +   }
      + 
      + + Here are some examples: + +
      +   assert(Ty->isPointerType() && "Can't allocate a non pointer type!");
      + 
      +   assert((Opcode == Shl || Opcode == Shr) && "ShiftInst Opcode invalid!");
      + 
      +   assert(idx < getNumSuccessors() && "Successor # out of range!");
      + 
      +   assert(V1.getType() == V2.getType() && "Constant types must be identical!");
      + 
      +   assert(isa<PHINode>(Succ->front()) && "Only works on PHId BBs!");
      + 

      + + You get the idea...

      + + + +


    Prefer Preincrement

      + + Hard fast rule: Preincrement (++X) may be no slower than postincrement (X++) and + could very well be a lot faster than it. Use preincrementation whenever + possible.

      + + The semantics of postincrement include making a copy of the value being + incremented, returning it, and then preincrementing the "work value". For + primitive types, this isn't a big deal... but for iterators, it can be a huge + issue (for example, some iterators contains stack and set objects in them... + copying an iterator could invoke the copy ctor's of these as well). In general, + get in the habit of always using preincrement, and you won't have a problem.

      + + + +


    Avoid endl

      + + The endl modifier, when used with iostreams outputs a newline to the + output stream specified. In addition to doing this, however, it also flushes + the output stream. In other words, these are equivalent:

      + +

      +   cout << endl;
      +   cout << "\n" << flush;
      + 
      + + Most of the time, you probably have no reason to flush the output stream, so it's better to use a literal "\n".

      + + + +


    Exploit C++ to its Fullest

      + + C++ is a powerful language. With a firm grasp on its capabilities, you can make + write effective, consise, readable and maintainable code all at the same time. + By staying consistent, you reduce the amount of special cases that need to be + remembered. Reducing the total number of lines of code you write is a good way + to avoid documentation, and avoid giving bugs a place to hide.

      + + For these reasons, come to know and love the contents of your local + <algorithm> header file. Know about <functional> and what it can do + for you. C++ is just a tool that wants you to master it. :)

      + + + + +

       + Writing Iterators +
      + + Here's a pretty good summary of how to write your own data structure iterators + in a way that is compatible with the STL, and with a lot of other code out there + (slightly edited by Chris):

      + +

      + From: Ross Smith 
      + Newsgroups: comp.lang.c++.moderated
      + Subject: Writing iterators (was: Re: Non-template functions that take iterators)
      + Date: 28 Jun 2001 12:07:10 -0400
      + 
      + Andre Majorel wrote:
      + > Any pointers handy on "writing STL-compatible iterators for
      + > dummies ?"
      + 
      + I'll give it a try...
      + 
      + The usual situation requiring user-defined iterators is that you have
      + a type that bears some resemblance to an STL container, and you want
      + to provide iterators so it can be used with STL algorithms. You need
      + to ask three questions:
      + 
      + First, is this simply a wrapper for an underlying collection of
      + objects that's held somewhere as a real STL container, or is it a
      + "virtual container" for which iteration is (under the hood) more
      + complicated than simply incrementing some underlying iterator (or
      + pointer or index or whatever)? In the former case you can frequently
      + get away with making your container's iterators simply typedefs for
      + those of the underlying container; your begin() function would call
      + member_container.begin(), and so on.
      + 
      + Second, do you only need read-only iterators, or do you need separate
      + read-only (const) and read-write (non-const) iterators?
      + 
      + Third, which kind of iterator (input, output, forward, bidirectional,
      + or random access) is appropriate? If you're familiar with the
      + properties of the iterator types (if not, visit
      + http://www.sgi.com/tech/stl/), the appropriate choice should be
      + obvious from the semantics of the container.
      + 
      + I'll start with forward iterators, as the simplest case that's likely
      + to come up in normal code. Input and output iterators have some odd
      + properties and rarely need to be implemented in user code; I'll leave
      + them out of discussion. Bidirectional and random access iterators are
      + covered below.
      + 
      + The exact behaviour of a forward iterator is spelled out in the
      + Standard in terms of a set of expressions with specified behaviour,
      + rather than a set of member functions, which leaves some leeway in how
      + you actually implement it. Typically it looks something like this
      + (I'll start with the const-iterator-only situation):
      + 
      +   #include <iterator>
      + 
      +   class container {
      +     public:
      +       typedef something_or_other value_type;
      +       class const_iterator:
      +         public std::iterator<std::forward_iterator_tag, value_type> {
      +           friend class container;
      +           public:
      +             const value_type& operator*() const;
      +             const value_type* operator->() const;
      +             const_iterator& operator++();
      +             const_iterator operator++(int);
      +             friend bool operator==(const_iterator lhs,
      +                                    const_iterator rhs);
      +             friend bool operator!=(const_iterator lhs,
      +                                    const_iterator rhs);
      +           private:
      +             //...
      +         };
      +       //...
      +   };
      + 
      + An iterator should always be derived from an instantiation of the
      + std::iterator template. The iterator's life cycle functions
      + (constructors, destructor, and assignment operator) aren't declared
      + here; in most cases the compiler-generated ones are sufficient. The
      + container needs to be a friend of the iterator so that the container's
      + begin() and end() functions can fill in the iterator's private members
      + with the appropriate values.
      + 
      + [Chris's Note: I prefer to not make my iterators friends.  Instead, two
      + ctor's are provided for the iterator class: one to start at the end of the
      + container, and one at the beginning.  Typically this is done by providing
      + two constructors with different signatures.]
      + 
      + There are normally only three member functions that need nontrivial
      + implementations; the rest are just boilerplate.
      + 
      +   const container::value_type&
      +     container::const_iterator::operator*() const {
      +       // find the element and return a reference to it
      +     }
      + 
      +   const container::value_type*
      +     container::const_iterator::operator->() const {
      +       return &**this;
      +     }
      + 
      + If there's an underlying real container, operator*() can just return a
      + reference to the appropriate element. If there's no actual container
      + and the elements need to be generated on the fly -- what I think of as
      + a "virtual container" -- things get a bit more complicated; you'll
      + probably need to give the iterator a value_type member object, and
      + fill it in when you need to. This might be done as part of the
      + increment operator (below), or if the operation is nontrivial, you
      + might choose the "lazy" approach and only generate the actual value
      + when one of the dereferencing operators is called.
      + 
      + The operator->() function is just boilerplate around a call to
      + operator*().
      + 
      +   container::const_iterator&
      +     container::const_iterator::operator++() {
      +       // the incrementing logic goes here
      +       return *this;
      +     }
      + 
      +   container::const_iterator
      +     container::const_iterator::operator++(int) {
      +       const_iterator old(*this);
      +       ++*this;
      +       return old;
      +     }
      + 
      + Again, the incrementing logic will usually be trivial if there's a
      + real container involved, more complicated if you're working with a
      + virtual container. In particular, watch out for what happens when you
      + increment past the last valid item -- this needs to produce an
      + iterator that will compare equal to container.end(), and making this
      + work is often nontrivial for virtual containers.
      + 
      + The post-increment function is just boilerplate again (and
      + incidentally makes it obvious why all the experts recommend using
      + pre-increment wherever possible).
      + 
      +   bool operator==(container::const_iterator lhs,
      +                   container::const_iterator rhs) {
      +     // equality comparison goes here
      +   }
      + 
      +   bool operator!=(container::const_iterator lhs,
      +                   container::const_iterator rhs) {
      +     return !(lhs == rhs);
      +   }
      + 
      + For a real container, the equality comparison will usually just
      + compare the underlying iterators (or pointers or indices or whatever).
      + The semantics of comparisons for virtual container iterators are often
      + tricky. Remember that iterator comparison only needs to be defined for
      + iterators into the same container, so you can often simplify things by
      + taking for granted that lhs and rhs both point into the same container
      + object. Again, the second function is just boilerplate.
      + 
      + It's a matter of taste whether iterator arguments are passed by value
      + or reference; I've shown tham passed by value to reduce clutter, but
      + if the iterator contains several data members, passing by reference
      + may be better.
      + 
      + That convers the const-iterator-only situation. When we need separate
      + const and mutable iterators, one small complication is added beyond
      + the simple addition of a second class.
      + 
      +   class container {
      +     public:
      +       typedef something_or_other value_type;
      +       class const_iterator;
      +       class iterator:
      +         public std::iterator<std::forward_iterator_tag, value_type> {
      +           friend class container;
      +           friend class container::const_iterator;
      +           public:
      +             value_type& operator*() const;
      +             value_type* operator->() const;
      +             iterator& operator++();
      +             iterator operator++(int);
      +             friend bool operator==(iterator lhs, iterator rhs);
      +             friend bool operator!=(iterator lhs, iterator rhs);
      +           private:
      +             //...
      +         };
      +       class const_iterator:
      +         public std::iterator<std::forward_iterator_tag, value_type> {
      +           friend class container;
      +           public:
      +             const_iterator();
      +             const_iterator(const iterator& i);
      +             const value_type& operator*() const;
      +             const value_type* operator->() const;
      +             const_iterator& operator++();
      +             const_iterator operator++(int);
      +             friend bool operator==(const_iterator lhs,
      +                                    const_iterator rhs);
      +             friend bool operator!=(const_iterator lhs,
      +                                    const_iterator rhs);
      +           private:
      +             //...
      +         };
      +       //...
      +   };
      + 
      + There needs to be a conversion from iterator to const_iterator (so
      + that mixed-type operations, such as comparison between an iterator and
      + a const_iterator, will work). This is done here by giving
      + const_iterator a conversion constructor from iterator (equivalently,
      + we could have given iterator an operator const_iterator()), which
      + requires const_iterator to be a friend of iterator, so it can copy its
      + data members. (It also requires the addition of an explicit default
      + constructor to const_iterator, since the existence of another
      + user-defined constructor inhibits the compiler-defined one.)
      + 
      + Bidirectional iterators add just two member functions to forward
      + iterators:
      + 
      +   class iterator:
      +     public std::iterator<std::bidirectional_iterator_tag, value_type> {
      +       public:
      +         //...
      +         iterator& operator--();
      +         iterator operator--(int);
      +         //...
      +     };
      + 
      + I won't detail the implementations, they're obvious variations on
      + operator++().
      + 
      + Random access iterators add several more member and friend functions:
      + 
      +   class iterator:
      +     public std::iterator<std::random_access_iterator_tag, value_type> {
      +       public:
      +         //...
      +         iterator& operator+=(difference_type rhs);
      +         iterator& operator-=(difference_type rhs);
      +         friend iterator operator+(iterator lhs, difference_type rhs);
      +         friend iterator operator+(difference_type lhs, iterator rhs);
      +         friend iterator operator-(iterator lhs, difference_type rhs);
      +         friend difference_type operator-(iterator lhs, iterator rhs);
      +         friend bool operator<(iterator lhs, iterator rhs);
      +         friend bool operator>(iterator lhs, iterator rhs);
      +         friend bool operator<=(iterator lhs, iterator rhs);
      +         friend bool operator>=(iterator lhs, iterator rhs);
      +         //...
      +     };
      + 
      +   container::iterator&
      +     container::iterator::operator+=(container::difference_type rhs) {
      +       // add rhs to iterator position
      +       return *this;
      +     }
      + 
      +   container::iterator&
      +     container::iterator::operator-=(container::difference_type rhs) {
      +       // subtract rhs from iterator position
      +       return *this;
      +     }
      + 
      +   container::iterator operator+(container::iterator lhs,
      +                                 container::difference_type rhs) {
      +     return iterator(lhs) += rhs;
      +   }
      + 
      +   container::iterator operator+(container::difference_type lhs,
      +                                 container::iterator rhs) {
      +     return iterator(rhs) += lhs;
      +   }
      + 
      +   container::iterator operator-(container::iterator lhs,
      +                                 container::difference_type rhs) {
      +     return iterator(lhs) -= rhs;
      +   }
      + 
      +   container::difference_type operator-(container::iterator lhs,
      +                                        container::iterator rhs) {
      +     // calculate distance between iterators
      +   }
      + 
      +   bool operator<(container::iterator lhs, container::iterator rhs) {
      +     // perform less-than comparison
      +   }
      + 
      +   bool operator>(container::iterator lhs, container::iterator rhs) {
      +     return rhs < lhs;
      +   }
      + 
      +   bool operator<=(container::iterator lhs, container::iterator rhs) {
      +     return !(rhs < lhs);
      +   }
      + 
      +   bool operator>=(container::iterator lhs, container::iterator rhs) {
      +     return !(lhs < rhs);
      +   }
      + 
      + Four of the functions (operator+=(), operator-=(), the second
      + operator-(), and operator<()) are nontrivial; the rest are
      + boilerplate.
      + 
      + One feature of the above code that some experts may disapprove of is
      + the declaration of all the free functions as friends, when in fact
      + only a few of them need direct access to the iterator's private data.
      + I originally got into the habit of doing this simply to keep the
      + declarations together; declaring some functions inside the class and
      + some outside seemed awkward. Since then, though, I've been told that
      + there's a subtle difference in the way name lookup works for functions
      + declared inside a class (as friends) and outside, so keeping them
      + together in the class is probably a good idea for practical as well as
      + aesthetic reasons.
      + 
      + I hope all this is some help to anyone who needs to write their own
      + STL-like containers and iterators.
      + 
      + -- 
      + Ross Smith <ross.s at ihug.co.nz> The Internet Group, Auckland, New Zealand
      + 
      + + + +
    + See Also +
      + + + A lot of these comments and recommendations have been culled for other sources. + Two particularly important books for our work are:

      + +

        +
      1. Effective C++ by Scott Meyers. There is an online version of the book (only some chapters though) available as well. +
      2. Large-Scale C++ Software Design by John Lakos +

      + + If you get some free time, and you haven't read them: do so, you might learn + something. :) + + + +

    + + +
    + +
    Chris Lattner
    + The LLVM Compiler Infrastructure +
    + + + Last modified: Sun Oct 12 22:12:43 CDT 2003 + +
    + Index: llvm-www/releases/1.0/CommandLine.html diff -c /dev/null llvm-www/releases/1.0/CommandLine.html:1.1 *** /dev/null Fri Oct 24 15:51:50 2003 --- llvm-www/releases/1.0/CommandLine.html Fri Oct 24 15:51:39 2003 *************** *** 0 **** --- 1,1540 ---- + + CommandLine 2.0 Library Manual + + + + +
      CommandLine 2.0 Library Manual
    + +
      +
    1. Introduction +
    2. Quick Start Guide +
        +
      1. Boolean Arguments +
      2. Argument Aliases +
      3. Selecting an alternative from a + set of possibilities +
      4. Named alternatives +
      5. Parsing a list of options +
      6. Adding freeform text to help output +
      +
    3. Reference Guide +
        +
      1. Positional Arguments + +
      2. Internal vs External Storage +
      3. Option Attributes +
      4. Option Modifiers + +
      5. Top-Level Classes and Functions + +
      6. Builtin parsers + +
      +
    4. Extension Guide +
        +
      1. Writing a custom parser +
      2. Exploiting external storage +
      3. Dynamically adding command line options +
      + +

      Written by Chris Lattner

      +

    + + + + +
    + Introduction +

      + + + This document describes the CommandLine argument processing library. It will + show you how to use it, and what it can do. The CommandLine library uses a + declarative approach to specifying the command line options that your program + takes. By default, these options declarations implicitly hold the value parsed + for the option declared (of course this can be + changed).

      + + Although there are a lot of command line argument parsing libraries out + there in many different languages, none of them fit well with what I needed. By + looking at the features and problems of other libraries, I designed the + CommandLine library to have the following features:

      + +

        +
      1. Speed: The CommandLine library is very quick and uses little resources. The + parsing time of the library is directly proportional to the number of arguments + parsed, not the the number of options recognized. Additionally, command line + argument values are captured transparently into user defined global variables, + which can be accessed like any other variable (and with the same + performance).

        + +

      2. Type Safe: As a user of CommandLine, you don't have to worry about + remembering the type of arguments that you want (is it an int? a string? a + bool? an enum?) and keep casting it around. Not only does this help prevent + error prone constructs, it also leads to dramatically cleaner source code.

        + +

      3. No subclasses required: To use CommandLine, you instantiate variables that + correspond to the arguments that you would like to capture, you don't subclass a + parser. This means that you don't have to write any boilerplate code.

        + +

      4. Globally accessible: Libraries can specify command line arguments that are + automatically enabled in any tool that links to the library. This is possible + because the application doesn't have to keep a "list" of arguments to pass to + the parser. This also makes supporting dynamically + loaded options trivial.

        + +

      5. Cleaner: CommandLine supports enum and other types directly, meaning that + there is less error and more security built into the library. You don't have to + worry about whether your integral command line argument accidentally got + assigned a value that is not valid for your enum type.

        + +

      6. Powerful: The CommandLine library supports many different types of + arguments, from simple boolean flags to scalars arguments (strings, integers, enums, doubles), to lists of + arguments. This is possible because CommandLine is...

        + +

      7. Extensible: It is very simple to add a new argument type to CommandLine. + Simply specify the parser that you want to use with the command line option when + you declare it. Custom parsers are no problem.

        + +

      8. Labor Saving: The CommandLine library cuts down on the amount of grunt work + that you, the user, have to do. For example, it automatically provides a + --help option that shows the available command line options for your + tool. Additionally, it does most of the basic correctness checking for you.

        + +

      9. Capable: The CommandLine library can handle lots of different forms of + options often found in real programs. For example, positional arguments, ls style grouping options (to allow processing 'ls + -lad' naturally), ld style prefix + options (to parse '-lmalloc -L/usr/lib'), and interpreter style options.

        + +

      + + This document will hopefully let you jump in and start using CommandLine in your + utility quickly and painlessly. Additionally it should be a simple reference + manual to figure out how stuff works. If it is failing in some area (or you + want an extension to the library), nag the author, Chris Lattner.

      + + + + +

    + Quick Start Guide +
      + + + This section of the manual runs through a simple CommandLine'ification of a + basic compiler tool. This is intended to show you how to jump into using the + CommandLine library in your own program, and show you some of the cool things it + can do.

      + + To start out, you need to include the CommandLine header file into your + program:

      + +

      +   #include "Support/CommandLine.h"
      + 

      + + Additionally, you need to add this as the first line of your main program:

      + +

      + int main(int argc, char **argv) {
      +   cl::ParseCommandLineOptions(argc, argv);
      +   ...
      + }
      + 

      + + ... which actually parses the arguments and fills in the variable + declarations.

      + + Now that you are ready to support command line arguments, we need to tell the + system which ones we want, and what type of argument they are. The CommandLine + library uses a declarative syntax to model command line arguments with the + global variable declarations that capture the parsed values. This means that + for every command line option that you would like to support, there should be a + global variable declaration to capture the result. For example, in a compiler, + we would like to support the unix standard '-o <filename>' option + to specify where to put the output. With the CommandLine library, this is + represented like this:

      + +

      
      + cl::opt<string> OutputFilename("o", cl::desc("Specify output filename"), cl::value_desc("filename"));
      + 

      + + This declares a global variable "OutputFilename" that is used to + capture the result of the "o" argument (first parameter). We specify + that this is a simple scalar option by using the "cl::opt" template (as opposed to the "cl::list template), and tell the CommandLine library + that the data type that we are parsing is a string.

      + + The second and third parameters (which are optional) are used to specify what to + output for the "--help" option. In this case, we get a line that looks + like this:

      + +

      + USAGE: compiler [options]
      + 
      + OPTIONS:
      +   -help             - display available options (--help-hidden for more)
      +   -o <filename>     - Specify output filename
      + 
      + + Because we specified that the command line option should parse using the + string data type, the variable declared is automatically usable as a + real string in all contexts that a normal C++ string object may be used. For + example:

      + +

      +   ...
      +   ofstream Output(OutputFilename.c_str());
      +   if (Out.good()) ...
      +   ...
      + 

      + + There are many different options that you can use to customize the command line + option handling library, but the above example shows the general interface to + these options. The options can be specified in any order, and are specified + with helper functions like cl::desc(...), so + there are no positional dependencies to remember. The available options are + discussed in detail in the Reference Guide.

      + + + Continuing the example, we would like to have our compiler take an input + filename as well as an output filename, but we do not want the input filename to + be specified with a hyphen (ie, not -filename.c). To support this + style of argument, the CommandLine library allows for positional arguments to be specified for the program. + These positional arguments are filled with command line parameters that are not + in option form. We use this feature like this:

      + +

      + cl::opt<string> InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
      + 
      + + This declaration indicates that the first positional argument should be treated + as the input filename. Here we use the cl::init option to specify an initial value for the + command line option, which is used if the option is not specified (if you do not + specify a cl::init modifier for an option, then + the default constructor for the data type is used to initialize the value). + Command line options default to being optional, so if we would like to require + that the user always specify an input filename, we would add the cl::Required flag, and we could eliminate the + cl::init modifier, like this:

      + +

      + cl::opt<string> InputFilename(cl::Positional, cl::desc("<input file>"), cl::Required);
      + 
      + + Again, the CommandLine library does not require the options to be specified in + any particular order, so the above declaration is equivalent to:

      + +

      + cl::opt<string> InputFilename(cl::Positional, cl::Required, cl::desc("<input file>"));
      + 
      + + By simply adding the cl::Required flag, the + CommandLine library will automatically issue an error if the argument is not + specified, which shifts all of the command line option verification code out of + your application into the library. This is just one example of how using flags + can alter the default behaviour of the library, on a per-option basis. By + adding one of the declarations above, the --help option synopsis is now + extended to:

      + +

      + USAGE: compiler [options] <input file>
      + 
      + OPTIONS:
      +   -help             - display available options (--help-hidden for more)
      +   -o <filename>     - Specify output filename
      + 
      + + ... indicating that an input filename is expected.

      + + + + +

       + Boolean Arguments +
      + + In addition to input and output filenames, we would like the compiler example to + support three boolean flags: "-f" to force overwriting of the output + file, "--quiet" to enable quiet mode, and "-q" for backwards + compatibility with some of our users. We can support these by declaring options + of boolean type like this:

      + +

      + cl::opt<bool> Force ("f", cl::desc("Overwrite output files"));
      + cl::opt<bool> Quiet ("quiet", cl::desc("Don't print informational messages"));
      + cl::opt<bool> Quiet2("q", cl::desc("Don't print informational messages"), cl::Hidden);
      + 

      + + This does what you would expect: it declares three boolean variables + ("Force", "Quiet", and "Quiet2") to recognize these + options. Note that the "-q" option is specified with the "cl::Hidden" flag. This modifier prevents it + from being shown by the standard "--help" output (note that it is still + shown in the "--help-hidden" output).

      + + The CommandLine library uses a different parser + for different data types. For example, in the string case, the argument passed + to the option is copied literally into the content of the string variable... we + obviously cannot do that in the boolean case, however, so we must use a smarter + parser. In the case of the boolean parser, it allows no options (in which case + it assigns the value of true to the variable), or it allows the values + "true" or "false" to be specified, allowing any of the + following inputs:

      + +

      +  compiler -f          # No value, 'Force' == true
      +  compiler -f=true     # Value specified, 'Force' == true
      +  compiler -f=TRUE     # Value specified, 'Force' == true
      +  compiler -f=FALSE    # Value specified, 'Force' == false
      + 
      + + ... you get the idea. The bool parser just turns the + string values into boolean values, and rejects things like 'compiler + -f=foo'. Similarly, the float, double, and int parsers work + like you would expect, using the 'strtol' and 'strtod' C + library calls to parse the string value into the specified data type.

      + + With the declarations above, "compiler --help" emits this:

      + +

      + USAGE: compiler [options] <input file>
      + 
      + OPTIONS:
      +   -f     - Overwrite output files
      +   -o     - Override output filename
      +   -quiet - Don't print informational messages
      +   -help  - display available options (--help-hidden for more)
      + 

      + + and "opt --help-hidden" prints this:

      + +

      + USAGE: compiler [options] <input file>
      + 
      + OPTIONS:
      +   -f     - Overwrite output files
      +   -o     - Override output filename
      +   -q     - Don't print informational messages
      +   -quiet - Don't print informational messages
      +   -help  - display available options (--help-hidden for more)
      + 

      + + This brief example has shown you how to use the 'cl::opt' class to parse simple scalar command line + arguments. In addition to simple scalar arguments, the CommandLine library also + provides primitives to support CommandLine option aliases, + and lists of options.

      + + + +

       + Argument Aliases +
      + + So far, the example works well, except for the fact that we need to check the + quiet condition like this now:

      + +

      + ...
      +   if (!Quiet && !Quiet2) printInformationalMessage(...);
      + ...
      + 

      + + ... which is a real pain! Instead of defining two values for the same + condition, we can use the "cl::alias" class to make the "-q" + option an alias for the "-quiet" option, instead of providing + a value itself:

      + +

      + cl::opt<bool> Force ("f", cl::desc("Overwrite output files"));
      + cl::opt<bool> Quiet ("quiet", cl::desc("Don't print informational messages"));
      + cl::alias     QuietA("q", cl::desc("Alias for -quiet"), cl::aliasopt(Quiet));
      + 

      + + The third line (which is the only one we modified from above) defines a + "-q alias that updates the "Quiet" variable (as specified by + the cl::aliasopt modifier) whenever it is + specified. Because aliases do not hold state, the only thing the program has to + query is the Quiet variable now. Another nice feature of aliases is + that they automatically hide themselves from the -help output + (although, again, they are still visible in the --help-hidden + output).

      + + Now the application code can simply use:

      + +

      + ...
      +   if (!Quiet) printInformationalMessage(...);
      + ...
      + 

      + + ... which is much nicer! The "cl::alias" can be used to specify an + alternative name for any variable type, and has many uses.

      + + + + +

       + Selecting an alternative from a set of possibilities +
      + + So far, we have seen how the CommandLine library handles builtin types like + std::string, bool and int, but how does it handle + things it doesn't know about, like enums or 'int*'s?

      + + The answer is that it uses a table driven generic parser (unless you specify + your own parser, as described in the Extension + Guide). This parser maps literal strings to whatever type is required, are + requires you to tell it what this mapping should be.

      + + Lets say that we would like to add four optimizations levels to our optimizer, + using the standard flags "-g", "-O0", "-O1", and + "-O2". We could easily implement this with boolean options like above, + but there are several problems with this strategy:

      + +

        +
      1. A user could specify more than one of the options at a time, for example, + "opt -O3 -O2". The CommandLine library would not be able to catch this + erroneous input for us. + +
      2. We would have to test 4 different variables to see which ones are set. + +
      3. This doesn't map to the numeric levels that we want... so we cannot easily + see if some level >= "-O1" is enabled. + +

      + + To cope with these problems, we can use an enum value, and have the CommandLine + library fill it in with the appropriate level directly, which is used like + this:

      + +

      + enum OptLevel {
      +   g, O1, O2, O3
      + };
      + 
      + cl::opt<OptLevel> OptimizationLevel(cl::desc("Choose optimization level:"),
      +   cl::values(
      +     clEnumVal(g , "No optimizations, enable debugging"),
      +     clEnumVal(O1, "Enable trivial optimizations"),
      +     clEnumVal(O2, "Enable default optimizations"),
      +     clEnumVal(O3, "Enable expensive optimizations"),
      +    0));
      + 
      + ...
      +   if (OptimizationLevel >= O2) doPartialRedundancyElimination(...);
      + ...
      + 

      + + This declaration defines a variable "OptimizationLevel" of the + "OptLevel" enum type. This variable can be assigned any of the values + that are listed in the declaration (Note that the declaration list must be + terminated with the "0" argument!). The CommandLine library enforces + that the user can only specify one of the options, and it ensure that only valid + enum values can be specified. The "clEnumVal" macros ensure that the + command line arguments matched the enum values. With this option added, our + help output now is:

      + +

      + USAGE: compiler [options] <input file>
      + 
      + OPTIONS:
      +   Choose optimization level:
      +     -g          - No optimizations, enable debugging
      +     -O1         - Enable trivial optimizations
      +     -O2         - Enable default optimizations
      +     -O3         - Enable expensive optimizations
      +   -f            - Overwrite output files
      +   -help         - display available options (--help-hidden for more)
      +   -o <filename> - Specify output filename
      +   -quiet        - Don't print informational messages
      + 
      + + In this case, it is sort of awkward that flag names correspond directly to enum + names, because we probably don't want a enum definition named "g" in + our program. Because of this, we can alternatively write this example like + this:

      + +

      + enum OptLevel {
      +   Debug, O1, O2, O3
      + };
      + 
      + cl::opt<OptLevel> OptimizationLevel(cl::desc("Choose optimization level:"),
      +   cl::values(
      +    clEnumValN(Debug, "g", "No optimizations, enable debugging"),
      +     clEnumVal(O1        , "Enable trivial optimizations"),
      +     clEnumVal(O2        , "Enable default optimizations"),
      +     clEnumVal(O3        , "Enable expensive optimizations"),
      +    0));
      + 
      + ...
      +   if (OptimizationLevel == Debug) outputDebugInfo(...);
      + ...
      + 

      + + By using the "clEnumValN" macro instead of "clEnumVal", we can + directly specify the name that the flag should get. In general a direct mapping + is nice, but sometimes you can't or don't want to preserve the mapping, which is + when you would use it.

      + + + + +

       + Named Alternatives +
      + + Another useful argument form is a named alternative style. We shall use this + style in our compiler to specify different debug levels that can be used. + Instead of each debug level being its own switch, we want to support the + following options, of which only one can be specified at a time: + "--debug-level=none", "--debug-level=quick", + "--debug-level=detailed". To do this, we use the exact same format as + our optimization level flags, but we also specify an option name. For this + case, the code looks like this:

      + +

      + enum DebugLev {
      +   nodebuginfo, quick, detailed
      + };
      + 
      + // Enable Debug Options to be specified on the command line
      + cl::opt<DebugLev> DebugLevel("debug_level", cl::desc("Set the debugging level:"),
      +   cl::values(
      +     clEnumValN(nodebuginfo, "none", "disable debug information"),
      +      clEnumVal(quick,               "enable quick debug information"),
      +      clEnumVal(detailed,            "enable detailed debug information"),
      +     0));
      + 
      + + This definition defines an enumerated command line variable of type "enum + DebugLev", which works exactly the same way as before. The difference here + is just the interface exposed to the user of your program and the help output by + the "--help" option:

      + +

      + USAGE: compiler [options] <input file>
      + 
      + OPTIONS:
      +   Choose optimization level:
      +     -g          - No optimizations, enable debugging
      +     -O1         - Enable trivial optimizations
      +     -O2         - Enable default optimizations
      +     -O3         - Enable expensive optimizations
      +   -debug_level  - Set the debugging level:
      +     =none       - disable debug information
      +     =quick      - enable quick debug information
      +     =detailed   - enable detailed debug information
      +   -f            - Overwrite output files
      +   -help         - display available options (--help-hidden for more)
      +   -o <filename> - Specify output filename
      +   -quiet        - Don't print informational messages
      + 

      + + Again, the only structural difference between the debug level declaration and + the optimiation level declaration is that the debug level declaration includes + an option name ("debug_level"), which automatically changes how the + library processes the argument. The CommandLine library supports both forms so + that you can choose the form most appropriate for your application.

      + + + + +

       + Parsing a list of options +
      + + Now that we have the standard run of the mill argument types out of the way, + lets get a little wild and crazy. Lets say that we want our optimizer to accept + a list of optimizations to perform, allowing duplicates. For example, we + might want to run: "compiler -dce -constprop -inline -dce -strip". In + this case, the order of the arguments and the number of appearances is very + important. This is what the "cl::list" + template is for. First, start by defining an enum of the optimizations that you + would like to perform:

      + +

      + enum Opts {
      +   // 'inline' is a C++ keyword, so name it 'inlining'
      +   dce, constprop, inlining, strip
      + };
      + 

      + + Then define your "cl::list" variable:

      + +

      + cl::list<Opts> OptimizationList(cl::desc("Available Optimizations:"),
      +   cl::values(
      +     clEnumVal(dce               , "Dead Code Elimination"),
      +     clEnumVal(constprop         , "Constant Propagation"),
      +    clEnumValN(inlining, "inline", "Procedure Integration"),
      +     clEnumVal(strip             , "Strip Symbols"),
      +   0));
      + 

      + + This defines a variable that is conceptually of the type + "std::vector<enum Opts>". Thus, you can access it with standard + vector methods:

      + +

      +   for (unsigned i = 0; i != OptimizationList.size(); ++i)
      +     switch (OptimizationList[i])
      +        ...
      + 
      + + ... to iterate through the list of options specified.

      + + Note that the "cl::list" template is completely general and may be used + with any data types or other arguments that you can use with the + "cl::opt" template. One especially useful way to use a list is to + capture all of the positional arguments together if there may be more than one + specified. In the case of a linker, for example, the linker takes several + '.o' files, and needs to capture them into a list. This is naturally + specified as:

      + +

      + ...
      + cl::list<std::string> InputFilenames(cl::Positional, cl::desc("<Input files>"), cl::OneOrMore);
      + ...
      + 

      + + This variable works just like a "vector<string>" object. As + such, accessing the list is simple, just like above. In this example, we used + the cl::OneOrMore modifier to inform the + CommandLine library that it is an error if the user does not specify any + .o files on our command line. Again, this just reduces the amount of + checking we have to do.

      + + + + +

       + Adding freeform text to help output +
      + + As our program grows and becomes more mature, we may decide to put summary + information about what it does into the help output. The help output is styled + to look similar to a Unix man page, providing concise information about + a program. Unix man pages, however often have a description about what + the program does. To add this to your CommandLine program, simply pass a third + argument to the cl::ParseCommandLineOptions + call in main. This additional argument is then printed as the overview + information for your program, allowing you to include any additional information + that you want. For example:

      + +

      + int main(int argc, char **argv) {
      +   cl::ParseCommandLineOptions(argc, argv, " CommandLine compiler example\n\n"
      +                               "  This program blah blah blah...\n");
      +   ...
      + }
      + 

      + + Would yield the help output: + +

      + OVERVIEW: CommandLine compiler example
      + 
      +   This program blah blah blah...
      + 
      + USAGE: compiler [options] <input file>
      + 
      + OPTIONS:
      +   ...
      +   -help             - display available options (--help-hidden for more)
      +   -o <filename>     - Specify output filename
      + 

      + + + + + +

    + Reference Guide +
      + + + Now that you know the basics of how to use the CommandLine library, this section + will give you the detailed information you need to tune how command line options + work, as well as information on more "advanced" command line option processing + capabilities.

      + + + +

       + Positional Arguments +
      + + Positional arguments are those arguments that are not named, and are not + specified with a hyphen. Positional arguments should be used when an option is + specified by its position alone. For example, the standard Unix grep + tool takes a regular expression argument, and an optional filename to search + through (which defaults to standard input if a filename is not specified). + Using the CommandLine library, this would be specified as:

      + +

      + cl::opt<string> Regex   (cl::Positional, cl::desc("<regular expression>"), cl::Required);
      + cl::opt<string> Filename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
      + 
      + + Given these two option declarations, the --help output for our grep + replacement would look like this:

      + +

      + USAGE: spiffygrep [options] <regular expression> <input file>
      + 
      + OPTIONS:
      +   -help - display available options (--help-hidden for more)
      + 
      + + ... and the resultant program could be used just like the standard grep + tool.

      + + Positional arguments are sorted by their order of construction. This means that + command line options will be ordered according to how they are listed in a .cpp + file, but will not have an ordering defined if they positional arguments are + defined in multiple .cpp files. The fix for this problem is simply to define + all of your positional arguments in one .cpp file.

      + + + + +


    Specifying positional options with hyphens

      + + Sometimes you may want to specify a value to your positional argument that + starts with a hyphen (for example, searching for '-foo' in a file). At + first, you will have trouble doing this, because it will try to find an argument + named '-foo', and will fail (and single quotes will not save you). + Note that the system grep has the same problem:

      + +

      +   $ spiffygrep '-foo' test.txt
      +   Unknown command line argument '-foo'.  Try: spiffygrep --help'
      + 
      +   $ grep '-foo' test.txt
      +   grep: illegal option -- f
      +   grep: illegal option -- o
      +   grep: illegal option -- o
      +   Usage: grep -hblcnsviw pattern file . . .
      + 

      + + The solution for this problem is the same for both your tool and the system + version: use the '--' marker. When the user specifies '--' on + the command line, it is telling the program that all options after the + '--' should be treated as positional arguments, not options. Thus, we + can use it like this:

      + +

      +   $ spiffygrep -- -foo test.txt
      +     ...output...
      + 

      + + + + +


    The cl::ConsumeAfter modifier

      + + The cl::ConsumeAfter formatting option is + used to construct programs that use "interpreter style" option processing. With + this style of option processing, all arguments specified after the last + positional argument are treated as special interpreter arguments that are not + interpreted by the command line argument.

      + + As a concrete example, lets say we are developing a replacement for the standard + Unix Bourne shell (/bin/sh). To run /bin/sh, first you + specify options to the shell itself (like -x which turns on trace + output), then you specify the name of the script to run, then you specify + arguments to the script. These arguments to the script are parsed by the bourne + shell command line option processor, but are not interpreted as options to the + shell itself. Using the CommandLine library, we would specify this as:

      + +

      + cl::opt<string> Script(cl::Positional, cl::desc("<input script>"), cl::init("-"));
      + cl::list<string>  Argv(cl::ConsumeAfter, cl::desc("<program arguments>..."));
      + cl::opt<bool>    Trace("x", cl::desc("Enable trace output"));
      + 

      + + which automatically provides the help output:

      + +

      + USAGE: spiffysh [options] <input script> <program arguments>...
      + 
      + OPTIONS:
      +   -help - display available options (--help-hidden for more)
      +   -x    - Enable trace output
      + 

      + + At runtime, if we run our new shell replacement as 'spiffysh -x test.sh -a + -x -y bar', the Trace variable will be set to true, the + Script variable will be set to "test.sh", and the + Argv list will contain ["-a", "-x", "-y", "bar"], because + they were specified after the last positional argument (which is the script + name).

      + + There are several limitations to when cl::ConsumeAfter options can be + specified. For example, only one cl::ConsumeAfter can be specified per + program, there must be at least one positional + argument specified, and the cl::ConsumeAfter option should be a cl::list option.

      + + + + +

       + Internal vs External Storage +
      + + By default, all command line options automatically hold the value that they + parse from the command line. This is very convenient in the common case, + especially when combined with the ability to define command line options in the + files that use them. This is called the internal storage model.

      + + Sometimes, however, it is nice to separate the command line option processing + code from the storage of the value parsed. For example, lets say that we have a + '-debug' option that we would like to use to enable debug information + across the entire body of our program. In this case, the boolean value + controlling the debug code should be globally accessable (in a header file, for + example) yet the command line option processing code should not be exposed to + all of these clients (requiring lots of .cpp files to #include + CommandLine.h).

      + + To do this, set up your .h file with your option, like this for example:

      + +

      + // DebugFlag.h - Get access to the '-debug' command line option
      + //
      + 
      + // DebugFlag - This boolean is set to true if the '-debug' command line option
      + // is specified.  This should probably not be referenced directly, instead, use
      + // the DEBUG macro below.
      + //
      + extern bool DebugFlag;
      + 
      + // DEBUG macro - This macro should be used by code to emit debug information.
      + // In the '-debug' option is specified on the command line, and if this is a
      + // debug build, then the code specified as the option to the macro will be
      + // executed.  Otherwise it will not be.  Example:
      + //
      + // DEBUG(cerr << "Bitset contains: " << Bitset << "\n");
      + //
      + #ifdef NDEBUG
      + #define DEBUG(X)
      + #else
      + #define DEBUG(X) \
      +   do { if (DebugFlag) { X; } } while (0)
      + #endif
      + 
      + + This allows clients to blissfully use the DEBUG() macro, or the + DebugFlag explicitly if they want to. Now we just need to be able to + set the DebugFlag boolean when the option is set. To do this, we pass + an additial argument to our command line argument processor, and we specify + where to fill in with the cl::location attribute:

      + +

      + bool DebugFlag;      // the actual value
      + static cl::opt<bool, true>       // The parser
      + Debug("debug", cl::desc("Enable debug output"), cl::Hidden,
      +       cl::location(DebugFlag));
      + 
      + + In the above example, we specify "true" as the second argument to the + cl::opt template, indicating that the template should not + maintain a copy of the value itself. In addition to this, we specify the cl::location attribute, so that DebugFlag is + automatically set.

      + + + + +

       + Option Attributes +
       + Option Modifiers +


    Hiding an option from --help output


    Controlling the number of occurances required and allowed


    Controlling whether or not a value must be specified


    Controlling other formatting options


    Miscellaneous option modifiers

       + Top-Level Classes and Functions +
      + + Despite all of the builtin flexibility, the CommandLine option library really + only consists of one function (cl::ParseCommandLineOptions) + and three main classes: cl::opt, cl::list, and cl::alias. This section describes these three + classes in detail.

      + + +


    The + cl::ParseCommandLineOptions function


    The + cl::ParseEnvironmentOptions function

      + + The cl::ParseEnvironmentOptions + function has mostly the same effects as + cl::ParseCommandLineOptions, + except that it is designed to take values for options from an + environment variable, for those cases in which reading the + command line is not convenient or not desired. It fills in + the values of all the command line option variables just like + cl::ParseCommandLineOptions + does.

      + + It takes three parameters: first, the name of the program (since argv + may not be available, it can't just look in argv[0]), second, + the name of the environment variable to examine, and third, the optional + additional extra text to emit when the + --help option is invoked.

      + + cl::ParseEnvironmentOptions will break the environment + variable's value up into words and then process them using + cl::ParseCommandLineOptions. + Note: Currently cl::ParseEnvironmentOptions does not support + quoting, so an environment variable containing -option "foo bar" will + be parsed as three words, -option, "foo, and bar", + which is different from what you would get from the shell with the same + input.

      + + +


    The cl::opt class


    The cl::list class


    The cl::alias class

       + Builtin parsers +
    + Extension Guide +
    +
       Writing a custom parser +
      + + One of the simplest and most common extensions is the use of a custom parser. + As discussed previously, parsers are the portion + of the CommandLine library that turns string input from the user into a + particular parsed data type, validating the input in the process.

      + + There are two ways to use a new parser:

      + +

        +
      1. Specialize the cl::parser template for + your custom data type.

        + + This approach has the advantage that users of your custom data type will + automatically use your custom parser whenever they define an option with a + value type of your data type. The disadvantage of this approach is that it + doesn't work if your fundemental data type is something that is already + supported.

        + +

      2. Write an independent class, using it explicitly from options that need + it.

        + + This approach works well in situations where you would line to parse an + option using special syntax for a not-very-special data-type. The drawback + of this approach is that users of your parser have to be aware that they are + using your parser, instead of the builtin ones.

        + +

      + + To guide the discussion, we will discuss a custom parser that accepts file + sizes, specified with an optional unit after the numeric size. For example, we + would like to parse "102kb", "41M", "1G" into the appropriate integer value. In + this case, the underlying data type we want to parse into is + 'unsigned'. We choose approach #2 above because we don't want to make + this the default for all unsigned options.

      + + To start out, we declare our new FileSizeParser class:

      + +

      + struct FileSizeParser : public cl::basic_parser<unsigned> {
      +   // parse - Return true on error.
      +   bool parse(cl::Option &O, const char *ArgName, const std::string &ArgValue,
      +              unsigned &Val);
      + };
      + 

      + + Our new class inherits from the cl::basic_parser template class to fill + in the default, boiler plate, code for us. We give it the data type that we + parse into (the last argument to the parse method so that clients of + our custom parser know what object type to pass in to the parse method (here we + declare that we parse into 'unsigned' variables.

      + + For most purposes, the only method that must be implemented in a custom parser + is the parse method. The parse method is called whenever the + option is invoked, passing in the option itself, the option name, the string to + parse, and a reference to a return value. If the string to parse is not well formed, the parser should output an error message and return true. Otherwise it should return false and set 'Val' to the parsed value. In our example, we implement parse as:

      + +

      + bool FileSizeParser::parse(cl::Option &O, const char *ArgName,
      +                            const std::string &Arg, unsigned &Val) {
      +   const char *ArgStart = Arg.c_str();
      +   char *End;
      +  
      +   // Parse integer part, leaving 'End' pointing to the first non-integer char
      +   Val = (unsigned)strtol(ArgStart, &End, 0);
      + 
      +   while (1) {
      +     switch (*End++) {
      +     case 0: return false;   // No error
      +     case 'i':               // Ignore the 'i' in KiB if people use that
      +     case 'b': case 'B':     // Ignore B suffix
      +       break;
      + 
      +     case 'g': case 'G': Val *= 1024*1024*1024; break;
      +     case 'm': case 'M': Val *= 1024*1024;      break;
      +     case 'k': case 'K': Val *= 1024;           break;
      + 
      +     default:
      +       // Print an error message if unrecognized character!
      +       return O.error(": '" + Arg + "' value invalid for file size argument!");
      +     }
      +   }
      + }
      + 

      + + This function implements a very simple parser for the kinds of strings we are + interested in. Although it has some holes (it allows "123KKK" for + example), it is good enough for this example. Note that we use the option + itself to print out the error message (the error method always returns + true) in order to get a nice error message (shown below). Now that we have our + parser class, we can use it like this:

      + +

      + static cl::opt<unsigned, false, FileSizeParser>
      + MFS("max-file-size", cl::desc("Maximum file size to accept"),
      +     cl::value_desc("size"));
      + 

      + + Which adds this to the output of our program:

      + +

      + OPTIONS:
      +   -help                 - display available options (--help-hidden for more)
      +   ...
      +   -max-file-size=<size> - Maximum file size to accept
      + 

      + + And we can test that our parse works correctly now (the test program just prints + out the max-file-size argument value):

      + +

      + $ ./test
      + MFS: 0
      + $ ./test -max-file-size=123MB
      + MFS: 128974848
      + $ ./test -max-file-size=3G
      + MFS: 3221225472
      + $ ./test -max-file-size=dog
      + -max-file-size option: 'dog' value invalid for file size argument!
      + 

      + + It looks like it works. The error message that we get is nice and helpful, and + we seem to accept reasonable file sizes. This wraps up the "custom parser" + tutorial.

      + + + +

    +
       Exploiting external + storage
      + + + + +
    +
       Dynamically adding command + line options
      + + + + + + +
    + + +
    + +
    Chris Lattner
    + The LLVM Compiler Infrastructure +
    + + + Last modified: Fri Aug 1 16:30:11 CDT 2003 + +
    + Index: llvm-www/releases/1.0/DSGraphStatus.html diff -c /dev/null llvm-www/releases/1.0/DSGraphStatus.html:1.1 *** /dev/null Fri Oct 24 15:51:50 2003 --- llvm-www/releases/1.0/DSGraphStatus.html Fri Oct 24 15:51:39 2003 *************** *** 0 **** --- 1,885 ---- + + Data Structure Graph Analysis Status Page + +

    Data Structure Graph Analysis Status Page

    + + This page records information and the progress the data structure analysis + passes have been making. Times are in seconds, sizes are #bytes allocated for a + particular pass. Runs that are all '*'d out were not completed because they + were taking too long (time listed show how long I waited).

    + + Fields that appear in bold have changes from the last entry on the page. + Floating point entries are only highlighted if they change significantly from + their previous value.

    + +


    +

    Nov 14, 2002:

    + + Some fine tuning happened here. The DSNode object was shrunk by a little bit, + lowering memory consumption. The type merging code now ignores access to + structure fields when checking compatibility, reducing node collapses and + increasing memory consumption in some cases. This table also includes data for + the number of indirect call sites, and the number of indirect call targets. The + final column is the average number of call targets per indirect call site.

    + +

    + Name:                Anlyz: LocTm: BUTim: TDTim: TimeSum: BCTime:      LocSize: BUSize:  TDSize:  BUTDSz:  BCSize:    NumFold  NumNodes   MaxSz  GlobGr MaxSCC | Loads Store Calls Allca Mallc Sum   | num/ind indcallee ratio
    + 254.gap              0.6627 0.1810 0.6627 0.4697 1.3134   0.6080   |   2024800  2822584  2018424  4841008  16585864 |    2076  24032+3948 268    0+0    20     | 18420 3888  5805  87    3     28203 | 11      11        1     
    + 255.vortex           0.3589 0.1648 0.3589 0.6751 1.1988   0.4810   |   1381200  1259752  2001576  3261328  11694840 |    1038  7343+2842  166    0+0    38     | 13901 6136  6829  1420  2     28288 | 6       95        15.8333
    + 300.twolf            0.0690 0.0663 0.0690 0.1151 0.2504   0.2424   |   466600   392384   400272   792656   7054760  |    95    4144+784   215    0+0    1      | 11246 2911  1865  114   3     16139 | 269     269       1     
    + 197.parser           0.0481 0.0305 0.0481 0.0479 0.1265   0.1291   |   281184   225008   212296   437304   4409632  |    338   2257+707   97     0+0    3      | 2611  908   1651  25    2     5197  | 2       4         2     
    + burg.llvm            0.0265 0.0218 0.0265 0.0389 0.0872   0.1565   |   536960   477848   188472   666320   2997272  |    213   2309+575   98     0+0    2      | 2265  363   1128  44    4     3804  | 8       24        3     
    + ptrdist-bc           0.0107 0.0079 0.0107 0.0116 0.0302   0.0354   |   198640   269032   91248    360280   1332992  |    62    680+199    42     0+0    1      | 764   411   425   21    25    1646  | 3       3         1     
    + ptrdist-yacr2        0.0100 0.0073 0.0100 0.0078 0.0251   0.0212   |   176112   193048   72296    265344   982896   |    *     1036+90    53     0+0    1      | 872   174   289   16    27    1378  | *       *         n/a   
    + 164.gzip.llvm        0.0062 0.0094 0.0062 0.0070 0.0226   0.1029   |   201568   129000   70880    199880   1873760  |    8     971+87     67     0+0    1      | 1014  622   351   19    3     2009  | 9       9         1     
    + optimizer-eval.llvm  0.0060 0.0034 0.0060 0.0344 0.0438   0.0145   |   100008   78968    61784    140752   626688   |    *     309+41     72     0+0    1      | 278   405   108   32    *     823   | 2       174       87    
    + 181.mcf              0.0050 0.0040 0.0050 0.0055 0.0145   0.0195   |   130984   120848   43208    164056   579064   |    46    376+52     83     0+0    1      | 362   225   81    8     2     678   | *       *         n/a   
    + voronoi.llvm         0.0037 0.0028 0.0037 0.0054 0.0119   0.0098   |   63768    82584    48808    131392   413304   |    3     307+77     58     0+0    1      | 399   171   121   44    4     739   | *       *         n/a   
    + 256.bzip2            0.0030 0.0060 0.0030 0.0025 0.0115   0.0907   |   138536   83624    39760    123384   1363416  |    *     563+37     59     0+0    1      | 698   307   287   18    10    1320  | 2       2         1     
    + sgefa.llvm           0.0028 0.0019 0.0028 0.0029 0.0076   0.0080   |   85680    81992    67056    149048   372736   |    *     130+24     36     0+0    1      | 159   65    77    5     5     311   | 1       1         1     
    + sim.llvm             0.0022 0.0032 0.0022 0.0026 0.008    0.0193   |   54952    81152    21976    103128   737584   |    *     261+36     60     0+0    1      | 687   305   75    2     21    1090  | *       *         n/a   
    + bh.llvm              0.0021 0.0025 0.0021 0.0019 0.0065   0.0113   |   75656    51520    27768    79288    470680   |    38    194+35     23     0+0    1      | 266   189   151   36    3     645   | 2       2         1     
    + ptrdist-ft           0.0019 0.0020 0.0019 0.0021 0.006    0.0115   |   46336    58552    15464    74016    502704   |    *     192+42     19     0+0    1      | 147   80    96    1     5     329   | 6       6         1     
    + ptrdist-ks           0.0017 0.0028 0.0017 0.0017 0.0062   0.0089   |   48792    44664    31304    75968    381528   |    *     215+30     36     0+0    1      | 155   87    88    2     6     338   | *       *         n/a   
    + ptrdist-anagram      0.0014 0.0017 0.0014 0.0012 0.0043   0.0079   |   43400    41992    14864    56856    409312   |    5     196+28     20     0+0    1      | 105   77    60    5     3     250   | 3       3         1     
    + em3d.llvm            0.0013 0.0012 0.0013 0.0010 0.0035   0.0056   |   24256    43304    13024    56328    223952   |    1     178+28     21     0+0    1      | 114   41    71    *     12    238   | 3       8         2.66666
    + health.llvm          0.0012 0.0010 0.0012 0.0013 0.0035   0.0070   |   32064    31992    12720    44712    202312   |    3     97+31      13     0+0    1      | 85    72    47    5     3     212   | *       *         n/a   
    + lists.llvm           0.0010 0.0008 0.0010 0.0015 0.0033   0.0033   |   24968    22808    6640     29448    139832   |    *     67+26      28     0+0    1      | 40    31    53    *     3     127   | *       *         n/a   
    + mst.llvm             0.0008 0.0008 0.0008 0.0007 0.0023   0.0044   |   18944    15584    16680    32264    183080   |    4     97+15      13     0+0    1      | 55    36    42    5     5     143   | 2       2         1     
    + hash.llvm            0.0008 0.0006 0.0008 0.0008 0.0022   0.0035   |   17504    26464    8208     34672    150160   |    *     117+17     19     0+0    1      | 35    25    25    1     4     90    | *       *         n/a   
    + tsp.llvm             0.0007 0.0009 0.0007 0.0005 0.0021   0.0042   |   18416    15024    5408     20432    183312   |    *     42+15      7      0+0    1      | 54    61    64    *     1     180   | *       *         n/a   
    + power.llvm           0.0007 0.0008 0.0007 0.0007 0.0022   0.0050   |   19704    18880    18120    37000    212104   |    *     81+18      11     0+0    1      | 141   86    46    11    4     288   | *       *         n/a   
    + perimeter.llvm       0.0007 0.0006 0.0007 0.0004 0.0017   0.0035   |   14944    13072    3936     17008    155240   |    *     35+15      7      0+0    1      | 30    25    49    *     1     105   | *       *         n/a   
    + bisort.llvm          0.0005 0.0006 0.0005 0.0003 0.0014   0.0032   |   13480    11608    3704     15312    124416   |    *     35+13      7      0+0    1      | 37    24    40    *     1     102   | *       *         n/a   
    + objinst.llvm         0.0004 0.0004 0.0004 0.0005 0.0013   0.0028   |   11360    11008    12288    23296    86552    |    7     53+14      19     0+0    1      | 18    11    19    *     2     50    | *       *         n/a   
    + methcall.llvm        0.0004 0.0004 0.0004 0.0006 0.0014   0.0026   |   10280    9816     9128     18944    86632    |    17    45+12      15     0+0    1      | 18    11    16    *     2     47    | 1       3         3     
    + treeadd.llvm         0.0003 0.0003 0.0003 0.0002 0.0008   0.0019   |   8712     7568     2216     9784     70776    |    *     25+7       7      0+0    1      | 15    6     18    *     1     40    | *       *         n/a   
    + matrix.llvm          0.0003 0.0003 0.0003 0.0003 0.0009   0.0019   |   3840     15744    3064     18808    69184    |    *     38+9       12     0+0    1      | 21    4     11    *     2     38    | *       *         n/a   
    + llubenchmark.llvm    0.0003 0.0005 0.0003 0.0003 0.0011   0.0028   |   11016    9448     2616     12064    123384   |    *     31+7       15     0+0    1      | 29    9     26    *     2     66    | *       *         n/a   
    + ary3.llvm            0.0003 0.0003 0.0003 0.0002 0.0008   0.0018   |   8832     12584    3008     15592    71432    |    4     44+5       17     0+0    1      | 10    14    7     *     1     32    | *       *         n/a   
    + sumarraymalloc.llvm  0.0002 0.0005 0.0002 0.0002 0.0009   0.0016   |   7032     2680     2064     4744     54544    |    *     23+5       7      0+0    1      | 8     2     8     *     1     19    | *       *         n/a   
    + sieve.llvm           0.0002 0.0002 0.0002 0.0006 0.001    0.0032   |   5704     1944     1616     3560     216328   |    *     22+2       12     0+0    1      | 7     3     4     *     *     14    | *       *         n/a   
    + random.llvm          0.0002 0.0002 0.0002 0.0001 0.0005   0.0014   |   2056     7176     1312     8488     46680    |    *     15+2       7      0+0    1      | 8     2     6     *     *     16    | *       *         n/a   
    + heapsort.llvm        0.0002 0.0003 0.0002 0.0001 0.0006   0.0016   |   2856     6976     1992     8968     63368    |    *     26+3       7      0+0    1      | 14    7     6     *     1     28    | *       *         n/a   
    + fib2.llvm            0.0002 0.0002 0.0002 0.0001 0.0005   0.0014   |   5744     6168     1632     7800     42448    |    *     21+5       8      0+0    1      | 6     1     7     *     *     14    | *       *         n/a   
    + ackermann.llvm       0.0002 0.0002 0.0002 0.0001 0.0005   0.0013   |   1744     1536     1192     2728     47528    |    *     13+2       7      0+0    1      | 6     1     6     *     *     13    | *       *         n/a   
    + sumarray.llvm        0.0001 0.0001 0.0001 0.0000 0.0002   0.0007   |   912      624      632      1256     15112    |    *     6+1        4      0+0    1      | 1     3     2     *     1     7     | *       *         n/a   
    + sumarray2d.llvm      0.0001 0.0001 0.0001 0.0001 0.0003   0.0009   |   1576     3656     848      4504     22544    |    *     10+1       7      0+0    1      | 1     2     3     1     *     7     | *       *         n/a   
    + printargs.llvm       0.0001 0.0001 0.0001 0.0001 0.0003   0.0007   |   3712     1048     704      1752     19104    |    *     6+1        4      0+0    1      | 4     *     5     *     *     9     | *       *         n/a   
    + pi.llvm              0.0001 0.0002 0.0001 0.0001 0.0004   0.0011   |   2368     4720     4736     9456     35208    |    *     17+2       13     0+0    1      | 7     3     7     2     *     19    | *       *         n/a   
    + matrixTranspose.llvm 0.0001 0.0002 0.0001 0.0001 0.0004   0.0013   |   1392     4128     736      4864     69720    |    *     8+1        5      0+0    1      | 6     5     4     *     *     15    | *       *         n/a   
    + indvars.llvm         0.0001 0.0002 0.0001 0.0001 0.0004   0.0010   |   4752     1072     1024     2096     31536    |    *     13+1       8      0+0    1      | 2     6     3     1     *     12    | *       *         n/a   
    + hello.llvm           0.0000 0.0001 0.0000 0.0000 0.0001   0.0006   |   752      472      472      944      14112    |    *     2+0        2      0+0    1      | 3     *     4     *     *     7     | *       *         n/a   
    + 

    + +


    +

    Nov 13, 2002:

    + + New numbers, same as last time, just some extra columns on the end:

    + + This data set also includes new data for the ptrdist benchmark.

    + +

    + Name:                Anlyz: LocTime: BUTime:  TDTime:  TimeSum: BCTime:      LocSize: BUSize:  TDSize:  BUTDSz:  BCSize:    NumFold  NumNodes   MaxSz  GlobGr MaxSCC | Loads Store Calls Allca Mallc Sum  
    + 254.gap                4.39 0.1773   0.6581   0.4703   1.3057   0.6054   |   2024952  2823064  2018920  4841984  16585864 |    2080  24032+3948 268    0+0    20     | 18420 3888  5805  87    3     28203 
    + 255.vortex             4.03 0.1154   0.3172   0.6416   1.0742   0.4523   |   1381344  1261232  1997512  3258744  11694840 |    1043  7331+2844  166    0+0    38     | 13901 6136  6829  1420  2     28288 
    + 300.twolf              0.80 0.0557   0.0593   0.1062   0.2212   0.2191   |   466544   391432   394760   786192   7054760  |    115   4127+784   215    0+0    1      | 11246 2911  1865  114   3     16139 
    + 197.parser             0.44 0.0302   0.0403   0.0442   0.1147   0.1204   |   280960   224800   212168   436968   4409632  |    338   2255+706   97     0+0    3      | 2611  908   1651  25    2     5197  
    + burg.llvm              0.33 0.0208   0.0268   0.0356   0.0832   0.1293   |   536552   478856   185880   664736   2997272  |    205   2273+576   98     0+0    2      | 2265  363   1128  44    4     3804  
    + 164.gzip.llvm          0.20 0.0093   0.0062   0.0073   0.0228   0.0999   |   201568   129000   70880    199880   1873760  |    8     971+87     67     0+0    1      | 1014  622   351   19    3     2009  
    + ptrdist-bc             0.12 0.0080   0.0111   0.0132   0.0323   0.0304   |   198640   269032   91232    360264   1332992  |    62    680+199    42     0+0    1      | 764   411   425   21    25    1646  
    + 256.bzip2              0.11 0.0057   0.0028   0.0024   0.0109   0.0462   |   138536   83624    39760    123384   1363416  |    *     563+37     59     0+0    1      | 698   307   287   18    10    1320  
    + optimizer-eval.llvm    0.10 0.0033   0.0064   0.0304   0.0401   0.0133   |   100008   78968    61784    140752   626688   |    *     309+41     72     0+0    1      | 278   405   108   32    *     823   
    + ptrdist-yacr2          0.09 0.0075   0.0097   0.0084   0.0256   0.0211   |   176112   193048   72296    265344   982896   |    *     1036+90    53     0+0    1      | 872   174   289   16    27    1378  
    + 181.mcf                0.09 0.0081   0.0051   0.0054   0.0186   0.0216   |   130816   121096   43648    164744   579064   |    44    388+51     83     0+0    1      | 362   225   81    8     2     678   
    + sgefa.llvm             0.08 0.0019   0.0026   0.0029   0.0074   0.0081   |   85680    81992    67056    149048   372736   |    *     130+24     36     0+0    1      | 159   65    77    5     5     311   
    + voronoi.llvm           0.06 0.0028   0.0037   0.0053   0.0118   0.0097   |   63768    82416    51856    134272   413304   |    11    299+77     58     0+0    1      | 399   171   121   44    4     739   
    + sim.llvm               0.06 0.0032   0.0022   0.0025   0.0079   0.0162   |   54952    81152    21976    103128   737584   |    *     261+36     60     0+0    1      | 687   305   75    2     21    1090  
    + bh.llvm                0.06 0.0025   0.0021   0.0023   0.0069   0.0116   |   75656    51520    27768    79288    470680   |    38    194+35     23     0+0    1      | 266   189   151   36    3     645   
    + ptrdist-ft             0.05 0.0020   0.0019   0.0021   0.006    0.0113   |   46336    58552    15464    74016    502704   |    *     192+42     19     0+0    1      | 147   80    96    1     5     329   
    + em3d.llvm              0.05 0.0012   0.0012   0.0011   0.0035   0.0056   |   24256    43304    13024    56328    223952   |    1     178+28     21     0+0    1      | 114   41    71    *     12    238   
    + ptrdist-ks             0.04 0.0023   0.0016   0.0017   0.0056   0.0081   |   48792    44664    31304    75968    381528   |    *     215+30     36     0+0    1      | 155   87    88    2     6     338   
    + ptrdist-anagram        0.04 0.0016   0.0014   0.0025   0.0055   0.0079   |   43400    41992    14864    56856    409312   |    5     196+28     20     0+0    1      | 105   77    60    5     3     250   
    + mst.llvm               0.04 0.0008   0.0007   0.0007   0.0022   0.0044   |   18944    15584    16680    32264    183080   |    4     97+15      13     0+0    1      | 55    36    42    5     5     143   
    + health.llvm            0.04 0.0010   0.0012   0.0017   0.0039   0.0070   |   32064    31992    12720    44712    202312   |    3     97+31      13     0+0    1      | 85    72    47    5     3     212   
    + tsp.llvm               0.03 0.0009   0.0006   0.0005   0.002    0.0041   |   18416    14504    4872     19376    183312   |    9     42+15      7      0+0    1      | 54    61    64    *     1     180   
    + treeadd.llvm           0.03 0.0003   0.0003   0.0002   0.0008   0.0019   |   8712     7568     2216     9784     70776    |    *     25+7       7      0+0    1      | 15    6     18    *     1     40    
    + sieve.llvm             0.03 0.0002   0.0002   0.0001   0.0005   0.0032   |   5704     1944     1616     3560     216328   |    *     22+2       12     0+0    1      | 7     3     4     *     *     14    
    + power.llvm             0.03 0.0008   0.0007   0.0007   0.0022   0.0049   |   19704    18880    18120    37000    212104   |    *     81+18      11     0+0    1      | 141   86    46    11    4     288   
    + pi.llvm                0.03 0.0002   0.0001   0.0001   0.0004   0.0010   |   2368     4720     4736     9456     35208    |    *     17+2       13     0+0    1      | 7     3     7     2     *     19    
    + perimeter.llvm         0.03 0.0006   0.0007   0.0004   0.0017   0.0035   |   14944    13072    3936     17008    155240   |    *     35+15      7      0+0    1      | 30    25    49    *     1     105   
    + objinst.llvm           0.03 0.0005   0.0005   0.0006   0.0016   0.0025   |   11360    16328    4112     20440    86552    |    19    45+14      16     0+0    1      | 18    11    19    *     2     50    
    + methcall.llvm          0.03 0.0004   0.0004   0.0006   0.0014   0.0026   |   10280    9752     9040     18792    86632    |    19    43+12      14     0+0    1      | 18    11    16    *     2     47    
    + matrixTranspose.llvm   0.03 0.0002   0.0001   0.0002   0.0005   0.0013   |   1392     4128     736      4864     69720    |    *     8+1        5      0+0    1      | 6     5     4     *     *     15    
    + matrix.llvm            0.03 0.0003   0.0003   0.0003   0.0009   0.0019   |   3840     15744    3064     18808    69184    |    *     38+9       12     0+0    1      | 21    4     11    *     2     38    
    + llubenchmark.llvm      0.03 0.0005   0.0003   0.0003   0.0011   0.0028   |   11016    9448     2616     12064    123384   |    *     31+7       15     0+0    1      | 29    9     26    *     2     66    
    + lists.llvm             0.03 0.0008   0.0010   0.0014   0.0032   0.0033   |   24968    22552    6128     28680    139832   |    15    67+26      28     0+0    1      | 40    31    53    *     3     127   
    + hash.llvm              0.03 0.0006   0.0008   0.0008   0.0022   0.0035   |   17504    26464    8208     34672    150160   |    *     117+17     19     0+0    1      | 35    25    25    1     4     90    
    + bisort.llvm            0.03 0.0006   0.0005   0.0003   0.0014   0.0029   |   13480    11608    3704     15312    124416   |    *     35+13      7      0+0    1      | 37    24    40    *     1     102   
    + ary3.llvm              0.03 0.0003   0.0003   0.0002   0.0008   0.0018   |   8832     12584    3008     15592    71432    |    4     44+5       17     0+0    1      | 10    14    7     *     1     32    
    + sumarraymalloc.llvm    0.02 0.0002   0.0002   0.0002   0.0006   0.0015   |   7032     2680     2064     4744     54544    |    *     23+5       7      0+0    1      | 8     2     8     *     1     19    
    + sumarray.llvm          0.02 0.0001   0.0001   0.0000   0.0002   0.0007   |   912      624      632      1256     15112    |    *     6+1        4      0+0    1      | 1     3     2     *     1     7     
    + sumarray2d.llvm        0.02 0.0001   0.0001   0.0001   0.0003   0.0009   |   1576     3656     848      4504     22544    |    *     10+1       7      0+0    1      | 1     2     3     1     *     7     
    + random.llvm            0.02 0.0002   0.0002   0.0001   0.0005   0.0014   |   2056     7176     1312     8488     46680    |    *     15+2       7      0+0    1      | 8     2     6     *     *     16    
    + printargs.llvm         0.02 0.0001   0.0001   0.0000   0.0002   0.0008   |   3712     1048     704      1752     19104    |    *     6+1        4      0+0    1      | 4     *     5     *     *     9     
    + indvars.llvm           0.02 0.0002   0.0001   0.0001   0.0004   0.0010   |   4752     1072     1024     2096     31536    |    *     13+1       8      0+0    1      | 2     6     3     1     *     12    
    + heapsort.llvm          0.02 0.0002   0.0002   0.0001   0.0005   0.0017   |   2856     6976     1992     8968     63368    |    *     26+3       7      0+0    1      | 14    7     6     *     1     28    
    + fib2.llvm              0.02 0.0002   0.0002   0.0001   0.0005   0.0013   |   5744     6168     1632     7800     42448    |    *     21+5       8      0+0    1      | 6     1     7     *     *     14    
    + ackermann.llvm         0.02 0.0002   0.0002   0.0001   0.0005   0.0017   |   1744     1536     1192     2728     47528    |    *     13+2       7      0+0    1      | 6     1     6     *     *     13    
    + hello.llvm             0.01 0.0001   0.0001   0.0000   0.0002   0.0006   |   752      472      472      944      14112    |    *     2+0        2      0+0    1      | 3     *     4     *     *     7     
    + 

    + +


    +

    Nov 12, 2002 #2:

    + + This build is the same as
    before, except now this is + compiled in release mode (optimizations enabled, assertions off).

    + +

    + Name:                     Anlyz: LocTime: BUTime:  TDTime:  TotTime: BCTime:      LocSize: BUSize:  TDSize:  TotSize: BCSize:    NumFold  NumNodes   main   __main GlobGr
    + 254.gap.lib                 3.43 0.1783   0.6490   0.4676   1.7957   0.5938   |   2024904  2816256  2016824  6857984  16561248 |    5973  24033+3949 44+9   0+0    0+0    
    + 255.vortex.lib              3.01 0.1177   0.3156   0.6452   1.5678   0.4652   |   1381488  1260088  2000864  4642440  11691072 |    5851  7324+2837  166+11 0+0    0+0    
    + 300.twolf.lib               0.72 0.0547   0.0591   0.1054   0.3435   0.2076   |   466544   391448   394984   1252976  6950016  |    768   4127+784   90+53  0+0    0+0    
    + 197.parser.lib              0.38 0.0301   0.0400   0.0448   0.1712   0.1206   |   407728   224960   212368   964008   4442008  |    1332  2256+707   14+6   0+0    0+0    
    + burg.llvm.lib               0.31 0.0207   0.0264   0.0359   0.1114   0.1493   |   535720   477752   185808   1265384  2998392  |    754   2273+576   45+7   0+0    0+0    
    + 164.gzip.llvm.lib           0.17 0.0089   0.0062   0.0070   0.0400   0.0977   |   201336   128072   135240   561056   1860784  |    24    971+87     8+2    0+0    0+0    
    + optimizer-eval.llvm.lib     0.08 0.0033   0.0063   0.0311   0.0528   0.0131   |   101272   79216    61760    242248   624880   |    *     309+41     72+27  0+0    0+0    
    + 256.bzip2.lib               0.08 0.0056   0.0028   0.0024   0.0242   0.0342   |   139696   84264    39688    335984   1371144  |    *     563+37     8+2    0+0    0+0    
    + 181.mcf.lib                 0.07 0.0038   0.0049   0.0055   0.0345   0.0155   |   109872   142976   43664    313504   585632   |    167   388+51     22+10  0+0    0+0    
    + sim.llvm.lib                0.05 0.0031   0.0023   0.0026   0.0187   0.0159   |   55880    51128    21864    225776   728104   |    *     260+35     39+22  0+0    0+0    
    + voronoi.llvm.lib            0.04 0.0028   0.0037   0.0054   0.0165   0.0098   |   79696    83000    27112    203160   412912   |    18    299+77     15+8   0+0    0+0    
    + hash.llvm.lib               0.04 0.0006   0.0008   0.0008   0.0045   0.0038   |   25568    23384    8184     70024    150480   |    *     117+17     14+6   0+0    0+0    
    + bh.llvm.lib                 0.04 0.0025   0.0021   0.0019   0.0118   0.0114   |   75208    51032    27800    202752   482440   |    64    194+35     6+2    0+0    0+0    
    + sgefa.llvm.lib              0.03 0.0019   0.0026   0.0028   0.0124   0.0085   |   85856    82224    67032    260752   375800   |    *     130+24     24+14  0+0    0+0    
    + health.llvm.lib             0.03 0.0010   0.0012   0.0013   0.0077   0.0072   |   30416    30184    12704    80824    197952   |    18    97+31      12+4   0+0    0+0    
    + tsp.llvm.lib                0.02 0.0009   0.0006   0.0005   0.0044   0.0044   |   18416    14448    4880     52472    183104   |    22    42+15      7+4    0+0    0+0    
    + power.llvm.lib              0.02 0.0008   0.0007   0.0007   0.0049   0.0065   |   19592    27536    7848     63072    218032   |    *     81+18      11+2   0+0    0+0    
    + perimeter.llvm.lib          0.02 0.0006   0.0006   0.0004   0.0039   0.0035   |   15200    14104    3944     46320    158680   |    *     35+15      7+4    0+0    0+0    
    + objinst.llvm.lib            0.02 0.0004   0.0004   0.0006   0.0038   0.0026   |   11368    15280    4112     45376    90432    |    32    45+14      16+10  0+0    0+0    
    + mst.llvm.lib                0.02 0.0008   0.0008   0.0007   0.0047   0.0046   |   18952    16568    7024     58032    183080   |    10    97+15      12+3   0+0    0+0    
    + methcall.llvm.lib           0.02 0.0004   0.0004   0.0005   0.0035   0.0026   |   10944    11088    3928     39584    87008    |    30    43+12      14+8   0+0    0+0    
    + llubenchmark.llvm.lib       0.02 0.0005   0.0003   0.0003   0.0037   0.0030   |   11008    9448     2600     33976    123336   |    *     31+7       15+5   0+0    0+0    
    + lists.llvm.lib              0.02 0.0010   0.0010   0.0014   0.0054   0.0036   |   25352    15608    14344    67520    139752   |    29    67+26      3+1    0+0    0+0    
    + em3d.llvm.lib               0.02 0.0011   0.0013   0.0011   0.0063   0.0055   |   24320    32736    12984    86912    224936   |    1     178+28     12+4   0+0    0+0    
    + bisort.llvm.lib             0.02 0.0006   0.0005   0.0003   0.0033   0.0030   |   13520    11672    3704     45912    125120   |    *     35+13      7+4    0+0    0+0    
    + treeadd.llvm.lib            0.01 0.0003   0.0003   0.0002   0.0023   0.0019   |   8064     7512     2200     29880    70776    |    *     25+7       6+3    0+0    0+0    
    + sumarraymalloc.llvm.lib     0.01 0.0002   0.0002   0.0002   0.0020   0.0015   |   2712     7000     2048     25576    54608    |    *     23+5       7+4    0+0    0+0    
    + sumarray.llvm.lib           0.01 0.0001   0.0001   0.0001   0.0011   0.0007   |   904      3192     624      4720     15112    |    *     6+1        4+1    0+0    0+0    
    + sumarray2d.llvm.lib         0.01 0.0002   0.0001   0.0001   0.0013   0.0009   |   1568     3536     848      8176     22504    |    *     10+1       7+1    0+0    0+0    
    + sieve.llvm.lib              0.01 0.0002   0.0002   0.0001   0.0020   0.0033   |   2152     6144     1616     23240    216328   |    *     22+2       12+1   0+0    0+0    
    + random.llvm.lib             0.01 0.0002   0.0002   0.0001   0.0017   0.0014   |   7616     1632     1320     23104    46680    |    *     15+2       3+1    0+0    0+0    
    + printargs.llvm.lib          0.01 0.0001   0.0001   0.0001   0.0011   0.0008   |   1248     1048     704      5144     19104    |    *     6+1        4+1    0+0    0+0    
    + pi.llvm.lib                 0.01 0.0002   0.0001   0.0001   0.0016   0.0011   |   5392     3800     4728     13920    35880    |    *     17+2       13+2   0+0    0+0    
    + matrixTranspose.llvm.lib    0.01 0.0002   0.0001   0.0001   0.0012   0.0013   |   5800     1144     736      7680     69712    |    *     8+1        5+1    0+0    0+0    
    + matrix.llvm.lib             0.01 0.0003   0.0003   0.0003   0.0028   0.0018   |   10088    8616     10672    40912    68728    |    *     38+9       12+8   0+0    0+0    
    + indvars.llvm.lib            0.01 0.0002   0.0001   0.0001   0.0014   0.0010   |   4760     1080     1016     9392     31536    |    *     13+1       8+1    0+0    0+0    
    + hello.llvm.lib              0.01 0.0001   0.0001   0.0000   0.0009   0.0007   |   752      2952     472      6512     12216    |    *     2+0        0+0    0+0    0+0    
    + heapsort.llvm.lib           0.01 0.0002   0.0002   0.0001   0.0021   0.0017   |   2856     6968     2008     26672    63368    |    *     26+3       7+2    0+0    0+0    
    + fib2.llvm.lib               0.01 0.0002   0.0002   0.0001   0.0019   0.0013   |   5696     6136     1640     26200    41992    |    *     21+5       8+3    0+0    0+0    
    + ary3.llvm.lib               0.01 0.0003   0.0004   0.0002   0.0026   0.0018   |   10264    21184    3008     45968    72576    |    6     44+5       12+3   0+0    0+0    
    + ackermann.llvm.lib          0.01 0.0002   0.0002   0.0001   0.0016   0.0014   |   1752     5736     1200     24944    46728    |    *     13+2       3+1    0+0    0+0    
    + 

    + + +


    +

    Nov 12, 2002:

    + +
    This + small change is important to programs with large SCC's. It basically makes + sure to inline calls to non-scc functions before we inline any intra-scc + calls. The problem is that inlining an SCC call could add more call + sites that would slow things down.

    + + Note that the total time underestimates the improvement. Take a look at the + change on BU time/total time to get an accurate accessment. I had some of the + graph IO printing code commented out in the last run, which affected Analyze + time, but not total time.

    + +

    + Name:                     Anlyz: LocTime: BUTime:  TDTime:  TotTime: BCTime:      LocSize: BUSize:  TDSize:  TotSize: BCSize:    NumFold  NumNodes   main   __main GlobGr
    + 254.gap.lib                17.69 0.8298   4.1158   2.4087   8.9138   2.9912   |   2024984  2840288  2024560  6889832  16554904 |    5985  24035+3950 44+9   0+0    0+0    
    + 255.vortex.lib             14.99 0.5988   1.8871   3.6557   7.3284   2.4054   |   1381056  1259144  1997120  4637320  11689312 |    5853  7328+2841  166+11 0+0    0+0    
    + 300.twolf.lib               3.34 0.2774   0.2827   0.5115   1.5475   1.0153   |   466528   391512   396552   1254592  6936728  |    749   4128+784   90+53  0+0    0+0    
    + 197.parser.lib              1.85 0.1485   0.3190   0.2156   0.8689   0.6872   |   408392   225184   212552   965384   4447944  |    1343  2257+707   14+6   0+0    0+0    
    + burg.llvm.lib               1.22 0.1027   0.1926   0.1739   0.5598   0.4947   |   530600   474592   185792   1190984  3040208  |    758   2273+576   45+7   0+0    0+0    
    + 164.gzip.llvm.lib           0.74 0.0398   0.0559   0.0350   0.1957   0.4561   |   145952   184776   70872    499912   1876248  |    24    971+87     8+2    0+0    0+0    
    + optimizer-eval.llvm.lib     0.43 0.0183   0.0485   0.2054   0.3047   0.0839   |   101184   79456    61760    242400   624688   |    *     309+41     72+27  0+0    0+0    
    + 256.bzip2.lib               0.34 0.0241   0.0404   0.0113   0.1250   0.1624   |   139504   83400    39712    335144   1373216  |    *     563+37     8+2    0+0    0+0    
    + 181.mcf.lib                 0.23 0.0216   0.0279   0.0301   0.1126   0.0795   |   115448   146520   43680    322864   589440   |    166   388+51     22+10  0+0    0+0    
    + sim.llvm.lib                0.20 0.0137   0.0138   0.0131   0.0800   0.0876   |   81632    51496    21872    226584   734152   |    *     260+35     39+22  0+0    0+0    
    + voronoi.llvm.lib            0.17 0.0139   0.0246   0.0282   0.0811   0.0591   |   79824    84152    27112    204904   420568   |    18    299+77     15+8   0+0    0+0    
    + sgefa.llvm.lib              0.16 0.0090   0.0195   0.0201   0.0848   0.0542   |   85688    100456   67024    277864   368680   |    *     130+24     24+14  0+0    0+0    
    + bh.llvm.lib                 0.16 0.0121   0.0164   0.0115   0.0581   0.0682   |   75000    51080    27760    217632   470720   |    61    194+35     6+2    0+0    0+0    
    + power.llvm.lib              0.13 0.0044   0.0122   0.0037   0.0282   0.0484   |   27776    17688    18144    71424    213760   |    *     81+18      11+2   0+0    0+0    
    + em3d.llvm.lib               0.11 0.0060   0.0110   0.0059   0.0308   0.0561   |   33040    36256    13008    90632    227520   |    1     178+28     12+4   0+0    0+0    
    + health.llvm.lib             0.10 0.0052   0.0203   0.0073   0.0406   0.0421   |   30632    31432    12704    89592    199888   |    18    97+31      12+4   0+0    0+0    
    + tsp.llvm.lib                0.07 0.0051   0.0063   0.0027   0.0217   0.0332   |   18232    14336    4920     51888    180744   |    21    43+15      8+4    0+0    0+0    
    + mst.llvm.lib                0.07 0.0040   0.0065   0.0037   0.0215   0.0296   |   18624    25576    7040     65808    178832   |    10    97+15      12+3   0+0    0+0    
    + lists.llvm.lib              0.07 0.0043   0.0131   0.0071   0.0299   0.0269   |   24552    16920    14440    68024    141480   |    30    67+26      3+1    0+0    0+0    
    + fib2.llvm.lib               0.07 0.0053   0.0217   0.0008   0.0313   0.0076   |   7960     6288     1640     28408    42256    |    *     21+5       8+3    0+0    0+0    
    + perimeter.llvm.lib          0.06 0.0031   0.0064   0.0021   0.0190   0.0275   |   15016    14192    3936     45912    156352   |    *     35+15      7+4    0+0    0+0    
    + hash.llvm.lib               0.06 0.0031   0.0050   0.0052   0.0200   0.0211   |   25728    16608    8208     63576    151680   |    *     117+17     14+6   0+0    0+0    
    + bisort.llvm.lib             0.06 0.0030   0.0055   0.0019   0.0318   0.0126   |   13288    11408    3712     39448    127360   |    *     35+13      7+4    0+0    0+0    
    + sumarraymalloc.llvm.lib     0.04 0.0009   0.0014   0.0009   0.0075   0.0240   |   7040     2672     2048     25872    54352    |    *     23+5       7+4    0+0    0+0    
    + objinst.llvm.lib            0.04 0.0019   0.0050   0.0032   0.0154   0.0100   |   11280    15784    4112     45296    89856    |    34    45+14      16+10  0+0    0+0    
    + methcall.llvm.lib           0.04 0.0018   0.0047   0.0031   0.0145   0.0122   |   11008    9880     3928     38624    87976    |    30    43+12      14+8   0+0    0+0    
    + matrix.llvm.lib             0.04 0.0013   0.0021   0.0014   0.0106   0.0198   |   8808     8872     3072     33144    69112    |    *     38+9       12+8   0+0    0+0    
    + llubenchmark.llvm.lib       0.04 0.0024   0.0026   0.0015   0.0142   0.0118   |   11072    11760    2624     36480    124344   |    *     31+7       15+5   0+0    0+0    
    + heapsort.llvm.lib           0.04 0.0009   0.0019   0.0007   0.0073   0.0137   |   2856     6968     2008     26976    63160    |    *     26+3       7+2    0+0    0+0    
    + ary3.llvm.lib               0.04 0.0013   0.0020   0.0011   0.0090   0.0134   |   10240    13104    10888    45832    73064    |    6     44+5       12+3   0+0    0+0    
    + ackermann.llvm.lib          0.04 0.0007   0.0015   0.0004   0.0066   0.0262   |   1744     5728     1200     22056    46448    |    *     13+2       3+1    0+0    0+0    
    + treeadd.llvm.lib            0.03 0.0015   0.0028   0.0010   0.0090   0.0084   |   3856     7384     2200     29784    72064    |    *     25+7       6+3    0+0    0+0    
    + sieve.llvm.lib              0.03 0.0008   0.0012   0.0006   0.0061   0.0162   |   2176     6176     1632     23432    216840   |    *     22+2       12+1   0+0    0+0    
    + random.llvm.lib             0.03 0.0008   0.0017   0.0004   0.0059   0.0133   |   2056     5720     1320     22080    45264    |    *     15+2       3+1    0+0    0+0    
    + matrixTranspose.llvm.lib    0.03 0.0005   0.0010   0.0003   0.0032   0.0129   |   4272     1144     736      8560     68448    |    *     8+1        5+1    0+0    0+0    
    + hello.llvm.lib              0.03 0.0004   0.0015   0.0001   0.0066   0.0107   |   752      2952     472      6512     14160    |    *     2+0        0+0    0+0    0+0    
    + sumarray2d.llvm.lib         0.02 0.0005   0.0009   0.0002   0.0034   0.0055   |   1568     3584     848      8264     23288    |    *     10+1       7+1    0+0    0+0    
    + printargs.llvm.lib          0.02 0.0004   0.0013   0.0002   0.0032   0.0058   |   1240     1048     696      5128     19160    |    *     6+1        4+1    0+0    0+0    
    + pi.llvm.lib                 0.02 0.0008   0.0021   0.0005   0.0052   0.0036   |   5392     1560     1392     8344     36032    |    *     17+2       13+2   0+0    0+0    
    + indvars.llvm.lib            0.02 0.0006   0.0010   0.0003   0.0037   0.0036   |   4744     1072     4208     12544    31336    |    *     13+1       8+1    0+0    0+0    
    + sumarray.llvm.lib           0.01 0.0004   0.0008   0.0002   0.0026   0.0029   |   904      3192     624      4720     15152    |    *     6+1        4+1    0+0    0+0    
    + 

    + +


    +

    Nov 11, 2002 #2:

    + + This is the result after
    fixing + some major bugs. The globals list was supposed to be kept sorted, but there + was one minor, tiny, little, bug that caused it to get screwed up sometimes. + This caused vortex to explode, fixing it gets things back in control where you'd + expect. Viola.

    + + This also includes a merging bug that caused some things to be merged and some + other things to happen when they shouldn't, which accounts for folding + reductions.

    + +

    + Name:                     Anlyz: LocTime: BUTime:  TDTime:  TotTime: BCTime:      LocSize: BUSize:  TDSize:  TotSize: BCSize:    NumFold  NumNodes   main   __main GlobGr
    + 254.gap.lib                17.65 0.8186   4.5919   2.3718   9.2483   2.8978   |   2024984  2984936  2025480  7035400  16554904 |    6853  24032+3950 44+9   0+0    0+0    
    + 255.vortex.lib             15.02 0.5766   2.4586   3.5717   7.6692   2.2728   |   1381056  1340216  2461232  5182504  11689312 |    7127  7302+2815  166+11 0+0    0+0    
    + 300.twolf.lib               3.23 0.2747   0.2856   0.5057   1.5129   0.9846   |   466528   391512   396552   1254592  6936728  |    749   4128+784   90+53  0+0    0+0    
    + 197.parser.lib              1.84 0.1528   0.3458   0.2180   0.8983   0.6469   |   408392   225312   212688   965648   4447944  |    1357  2257+707   14+6   0+0    0+0    
    + burg.llvm.lib               1.20 0.1017   0.1867   0.1765   0.5525   0.4912   |   530600   473296   185792   1189688  3040208  |    756   2273+576   45+7   0+0    0+0    
    + 164.gzip.llvm.lib           0.71 0.0392   0.0649   0.0330   0.2008   0.4263   |   145952   184776   70872    499912   1876248  |    24    971+87     8+2    0+0    0+0    
    + optimizer-eval.llvm.lib     0.42 0.0163   0.0446   0.2063   0.2953   0.0798   |   101184   79456    61760    242400   624688   |    *     309+41     72+27  0+0    0+0    
    + 256.bzip2.lib               0.34 0.0238   0.0491   0.0112   0.1311   0.1543   |   139504   83400    39712    335144   1373216  |    *     563+37     8+2    0+0    0+0    
    + 181.mcf.lib                 0.20 0.0174   0.0267   0.0272   0.0906   0.0744   |   115448   146520   43680    322864   589440   |    166   388+51     22+10  0+0    0+0    
    + sim.llvm.lib                0.19 0.0135   0.0136   0.0130   0.0776   0.0794   |   81632    51496    21872    226584   734152   |    *     260+35     39+22  0+0    0+0    
    + voronoi.llvm.lib            0.17 0.0137   0.0267   0.0286   0.0829   0.0561   |   79824    84152    27112    204904   420568   |    18    299+77     15+8   0+0    0+0    
    + bh.llvm.lib                 0.16 0.0116   0.0161   0.0111   0.0591   0.0675   |   75000    51080    27760    217632   470720   |    61    194+35     6+2    0+0    0+0    
    + sgefa.llvm.lib              0.14 0.0086   0.0201   0.0208   0.0656   0.0517   |   85688    100456   67024    277864   368680   |    *     130+24     24+14  0+0    0+0    
    + sumarray2d.llvm.lib         0.11 0.0005   0.0009   0.0002   0.0033   0.0922   |   1568     3584     848      8264     23288    |    *     10+1       7+1    0+0    0+0    
    + health.llvm.lib             0.09 0.0050   0.0082   0.0073   0.0280   0.0419   |   30632    31432    12704    89592    199888   |    18    97+31      12+4   0+0    0+0    
    + em3d.llvm.lib               0.09 0.0058   0.0110   0.0059   0.0304   0.0395   |   33040    36256    13008    90632    227520   |    1     178+28     12+4   0+0    0+0    
    + power.llvm.lib              0.08 0.0042   0.0067   0.0040   0.0222   0.0365   |   27776    17688    18144    71424    213760   |    *     81+18      11+2   0+0    0+0    
    + mst.llvm.lib                0.08 0.0039   0.0072   0.0037   0.0218   0.0306   |   18624    25576    7040     65808    178832   |    10    97+15      12+3   0+0    0+0    
    + lists.llvm.lib              0.08 0.0043   0.0137   0.0072   0.0306   0.0283   |   24552    16920    14440    68024    141480   |    30    67+26      3+1    0+0    0+0    
    + tsp.llvm.lib                0.07 0.0048   0.0066   0.0027   0.0217   0.0327   |   18232    14336    4920     51888    180744   |    21    43+15      8+4    0+0    0+0    
    + perimeter.llvm.lib          0.06 0.0031   0.0066   0.0024   0.0194   0.0260   |   15016    14192    3936     45912    156352   |    *     35+15      7+4    0+0    0+0    
    + bisort.llvm.lib             0.06 0.0029   0.0056   0.0018   0.0230   0.0229   |   13288    11408    3712     39448    127360   |    *     35+13      7+4    0+0    0+0    
    + objinst.llvm.lib            0.05 0.0019   0.0048   0.0031   0.0153   0.0174   |   11280    15784    4112     45296    89856    |    34    45+14      16+10  0+0    0+0    
    + methcall.llvm.lib           0.05 0.0017   0.0043   0.0028   0.0135   0.0187   |   11008    9880     3928     38624    87976    |    30    43+12      14+8   0+0    0+0    
    + heapsort.llvm.lib           0.05 0.0009   0.0020   0.0007   0.0074   0.0306   |   2856     6968     2008     26976    63160    |    *     26+3       7+2    0+0    0+0    
    + hash.llvm.lib               0.05 0.0030   0.0052   0.0040   0.0184   0.0173   |   25728    16608    8208     63576    151680   |    *     117+17     14+6   0+0    0+0    
    + sumarraymalloc.llvm.lib     0.04 0.0009   0.0015   0.0009   0.0067   0.0156   |   7040     2672     2048     25872    54352    |    *     23+5       7+4    0+0    0+0    
    + random.llvm.lib             0.04 0.0009   0.0018   0.0004   0.0060   0.0223   |   2056     5720     1320     22080    45264    |    *     15+2       3+1    0+0    0+0    
    + llubenchmark.llvm.lib       0.04 0.0022   0.0028   0.0015   0.0130   0.0118   |   11072    11760    2624     36480    124344   |    *     31+7       15+5   0+0    0+0    
    + ackermann.llvm.lib          0.04 0.0007   0.0015   0.0004   0.0055   0.0230   |   1744     5728     1200     22056    46448    |    *     13+2       3+1    0+0    0+0    
    + treeadd.llvm.lib            0.03 0.0015   0.0029   0.0009   0.0090   0.0076   |   3856     7384     2200     29784    72064    |    *     25+7       6+3    0+0    0+0    
    + sieve.llvm.lib              0.03 0.0007   0.0013   0.0005   0.0060   0.0140   |   2176     6176     1632     23432    216840   |    *     22+2       12+1   0+0    0+0    
    + printargs.llvm.lib          0.03 0.0005   0.0015   0.0002   0.0034   0.0077   |   1240     1048     696      5128     19160    |    *     6+1        4+1    0+0    0+0    
    + matrixTranspose.llvm.lib    0.03 0.0005   0.0010   0.0003   0.0032   0.0167   |   4272     1144     736      8560     68448    |    *     8+1        5+1    0+0    0+0    
    + matrix.llvm.lib             0.03 0.0013   0.0022   0.0014   0.0092   0.0100   |   8808     8872     3072     33144    69112    |    *     38+9       12+8   0+0    0+0    
    + hello.llvm.lib              0.03 0.0004   0.0014   0.0001   0.0067   0.0123   |   752      2952     472      6512     14160    |    *     2+0        0+0    0+0    0+0    
    + fib2.llvm.lib               0.03 0.0008   0.0015   0.0007   0.0061   0.0135   |   7960     6288     1640     28408    42256    |    *     21+5       8+3    0+0    0+0    
    + ary3.llvm.lib               0.03 0.0012   0.0020   0.0011   0.0086   0.0084   |   10240    13104    10888    45832    73064    |    6     44+5       12+3   0+0    0+0    
    + sumarray.llvm.lib           0.02 0.0003   0.0009   0.0002   0.0028   0.0114   |   904      3192     624      4720     15152    |    *     6+1        4+1    0+0    0+0    
    + pi.llvm.lib                 0.02 0.0008   0.0020   0.0004   0.0050   0.0037   |   5392     1560     1392     8344     36032    |    *     17+2       13+2   0+0    0+0    
    + indvars.llvm.lib            0.02 0.0005   0.0009   0.0003   0.0035   0.0035   |   4744     1072     4208     12544    31336    |    *     13+1       8+1    0+0    0+0    
    + 

    + +


    +

    Nov 11, 2002:

    + + This is the first successful run of all of the benchmarks! This is still + compiled in debug mode, still has lots of tweaks and minor improvements that + could be made, lots of optimizations even, but they will have to wait for a + bit.

    + + Also note that we now include time taken the parse the bytecode file into LLVM + IR, and the space used by the LLVM IR.

    + +

    + Name:                     Anlyz: LocTime: BUTime:  TDTime:  TotTime: BCTime:      LocSize: BUSize:  TDSize:  TotSize: BCSize:    NumFold  NumNodes   main   __main GlobGr
    + 255.vortex.lib             24.44 0.5896   2.7741   11.5906  16.5760  2.3257   |   1381816  1338688  14822760 17543264 11691568 |    7288  7321+3135  166+11 0+0    0+0    
    + 254.gap.lib                19.51 0.8708   4.6071   3.5835   10.6354  2.9075   |   2024600  3155592  2323136  7503328  16555920 |    6934  24027+3950 44+9   0+0    0+0    
    + 300.twolf.lib               3.38 0.2753   0.2930   0.5233   1.5807   0.9966   |   466248   392352   398296   1256896  6936800  |    765   4129+784   91+53  0+0    0+0    
    + 197.parser.lib              1.89 0.1478   0.3243   0.2178   0.8755   0.6667   |   408560   224928   213736   966696   4451256  |    1350  2259+711   14+6   0+0    0+0    
    + burg.llvm.lib               1.23 0.1039   0.1877   0.1779   0.5589   0.4972   |   530224   471200   183504   1184928  3039960  |    790   2239+575   42+7   0+0    0+0    
    + 164.gzip.llvm.lib           0.71 0.0408   0.0578   0.0332   0.1965   0.4323   |   201664   128768   70864    498912   1870880  |    24    971+87     8+2    0+0    0+0    
    + optimizer-eval.llvm.lib     0.51 0.0166   0.0480   0.2086   0.3041   0.1716   |   81584    78352    60304    238616   620296   |    *     309+41     72+27  0+0    0+0    
    + 256.bzip2.lib               0.33 0.0240   0.0383   0.0114   0.1214   0.1565   |   139536   84224    39704    335680   1370784  |    *     563+37     8+2    0+0    0+0    
    + 181.mcf.lib                 0.22 0.0184   0.0286   0.0287   0.0959   0.0874   |   111384   145792   43360    317776   589808   |    156   393+51     23+10  0+0    0+0    
    + sim.llvm.lib                0.20 0.0136   0.0137   0.0130   0.0792   0.0848   |   55376    81000    21960    253344   721520   |    *     261+36     39+22  0+0    0+0    
    + voronoi.llvm.lib            0.17 0.0135   0.0262   0.0289   0.0833   0.0553   |   79696    87968    27128    208568   419920   |    18    299+77     15+8   0+0    0+0    
    + bh.llvm.lib                 0.16 0.0116   0.0164   0.0118   0.0590   0.0665   |   55864    71416    27432    219376   473840   |    61    194+35     6+2    0+0    0+0    
    + sgefa.llvm.lib              0.15 0.0089   0.0222   0.0246   0.0720   0.0530   |   85904    82240    67064    260872   364520   |    *     130+24     24+14  0+0    0+0    
    + health.llvm.lib             0.10 0.0050   0.0096   0.0055   0.0275   0.0450   |   29880    27920    7608     73008    199064   |    71    79+29      10+4   0+0    0+0    
    + tsp.llvm.lib                0.08 0.0049   0.0072   0.0027   0.0224   0.0350   |   25704    14472    4872     52216    176600   |    21    42+15      7+4    0+0    0+0    
    + power.llvm.lib              0.08 0.0041   0.0067   0.0037   0.0222   0.0361   |   28512    17760    7848     61960    214128   |    *     81+18      11+2   0+0    0+0    
    + em3d.llvm.lib               0.08 0.0060   0.0113   0.0055   0.0312   0.0315   |   24280    32960    12536    86576    224616   |    13    172+25     12+4   0+0    0+0    
    + perimeter.llvm.lib          0.07 0.0031   0.0069   0.0020   0.0196   0.0261   |   14936    14112    3928     45592    155208   |    *     35+15      7+4    0+0    0+0    
    + mst.llvm.lib                0.07 0.0039   0.0067   0.0037   0.0216   0.0285   |   27408    16752    7040     66048    178328   |    10    97+15      12+3   0+0    0+0    
    + lists.llvm.lib              0.07 0.0043   0.0128   0.0072   0.0299   0.0276   |   24544    16912    14440    68008    141480   |    30    67+26      3+1    0+0    0+0    
    + hash.llvm.lib               0.06 0.0030   0.0051   0.0054   0.0202   0.0186   |   17936    24808    8216     64232    153552   |    *     117+17     14+6   0+0    0+0    
    + methcall.llvm.lib           0.05 0.0017   0.0047   0.0029   0.0142   0.0174   |   10984    9856     9144     44000    87328    |    30    43+12      14+8   0+0    0+0    
    + objinst.llvm.lib            0.04 0.0019   0.0042   0.0033   0.0147   0.0114   |   11072    15328    10536    50496    87064    |    34    45+14      16+10  0+0    0+0    
    + matrix.llvm.lib             0.04 0.0012   0.0021   0.0016   0.0094   0.0164   |   8720     8784     3048     36600    68048    |    *     38+9       12+8   0+0    0+0    
    + llubenchmark.llvm.lib       0.04 0.0021   0.0027   0.0014   0.0130   0.0117   |   4728     9368     2608     33440    122712   |    *     31+7       15+5   0+0    0+0    
    + bisort.llvm.lib             0.04 0.0029   0.0056   0.0019   0.0160   0.0125   |   13608    11744    3712     45984    126584   |    *     35+13      7+4    0+0    0+0    
    + ary3.llvm.lib               0.04 0.0012   0.0020   0.0011   0.0088   0.0138   |   8648     19856    2976     43080    73064    |    6     44+5       12+3   0+0    0+0    
    + ackermann.llvm.lib          0.04 0.0007   0.0017   0.0004   0.0058   0.0226   |   1744     5728     1200     22056    46448    |    *     13+2       3+1    0+0    0+0    
    + treeadd.llvm.lib            0.03 0.0014   0.0029   0.0009   0.0090   0.0077   |   3856     7384     2200     29784    72064    |    *     25+7       6+3    0+0    0+0    
    + sumarraymalloc.llvm.lib     0.03 0.0009   0.0017   0.0009   0.0069   0.0100   |   7040     2672     2048     25872    54352    |    *     23+5       7+4    0+0    0+0    
    + sieve.llvm.lib              0.03 0.0007   0.0012   0.0005   0.0060   0.0138   |   2176     6176     1632     23432    216840   |    *     22+2       12+1   0+0    0+0    
    + random.llvm.lib             0.03 0.0008   0.0018   0.0004   0.0060   0.0137   |   2056     5720     1320     22080    45264    |    *     15+2       3+1    0+0    0+0    
    + matrixTranspose.llvm.lib    0.03 0.0005   0.0010   0.0003   0.0033   0.0151   |   4248     1144     736      8520     68104    |    *     8+1        5+1    0+0    0+0    
    + hello.llvm.lib              0.03 0.0004   0.0018   0.0001   0.0064   0.0105   |   752      2952     472      6512     12264    |    *     2+0        0+0    0+0    0+0    
    + heapsort.llvm.lib           0.03 0.0009   0.0020   0.0007   0.0074   0.0080   |   7448     7224     1992     28032    62704    |    *     26+3       7+2    0+0    0+0    
    + sumarray2d.llvm.lib         0.02 0.0005   0.0009   0.0002   0.0033   0.0030   |   4208     856      3656     10904    21968    |    *     10+1       7+1    0+0    0+0    
    + printargs.llvm.lib          0.02 0.0004   0.0014   0.0002   0.0033   0.0061   |   1240     1048     696      5128     19160    |    *     6+1        4+1    0+0    0+0    
    + pi.llvm.lib                 0.02 0.0007   0.0019   0.0004   0.0050   0.0037   |   5392     1560     1392     8344     36032    |    *     17+2       13+2   0+0    0+0    
    + indvars.llvm.lib            0.02 0.0011   0.0010   0.0003   0.0043   0.0035   |   1744     4088     1024     9696     31336    |    *     13+1       8+1    0+0    0+0    
    + fib2.llvm.lib               0.02 0.0008   0.0015   0.0007   0.0061   0.0050   |   2416     10376    1648     30088    43792    |    *     21+5       8+3    0+0    0+0    
    + sumarray.llvm.lib           0.01 0.0003   0.0009   0.0002   0.0027   0.0022   |   904      3192     624      4720     15152    |    *     6+1        4+1    0+0    0+0    
    + 

    + + + +


    +

    Nov 10, 2002:

    + + This data set has the prototype Tarjan SCC code in to help with cases that were + causing exponential behavior. This gets Gap working, but Vortex is still either + infinite looping or really slow. I'm almost certain there are a couple of bugs + still remaining in the implementation, so these should be regarded as + preliminary numbers.

    + + Here is some trivia for you: Vortex contains a SCC with 38 nodes, and another + with 19. Gap contains SCCs of size 2, 2, 20, 6, 2.

    + + Also note that the bytecode file for GAP is 3x the size of the bytecode file for + twolf.

    + +

    + Name:                     Anlyz: LocTime: BUTime:  TDTime:  TotTime: BCTime:      LocSize: BUSize:  TDSize:  TotSize: BCSize:    NumFold  NumNodes   main   __main GlobGr
    + 255.vortex.lib              7.56 *        *        *        *        *        |   *        *        *        *        *        |    *     *          *      *      *      
    + 254.gap.lib                22.53 0.8908   7.0430   3.2424   12.8506  3.1879   |   2024600  5229888  3882656  11137144 16555920 |    6959  42275+3949 59+9   0+0    0+0    
    + 300.twolf.lib               3.92 0.3259   0.3470   0.8163   2.0253   1.0287   |   466248   405936   456456   1328640  6936800  |    821   4119+784   90+53  0+0    0+0    
    + 197.parser.lib              2.23 0.1939   0.4020   0.2499   1.0864   0.7768   |   408560   229568   220672   978272   4451256  |    1362  2272+704   16+6   0+0    0+0    
    + burg.llvm.lib               1.28 0.1085   0.1942   0.1954   0.5911   0.5072   |   530224   477440   290376   1298040  3039960  |    796   2248+575   39+7   0+0    0+0    
    + 164.gzip.llvm.lib           0.67 0.0392   0.0506   0.0326   0.1873   0.4044   |   201664   130312   72000    501592   1870880  |    24    988+87     12+2   0+0    0+0    
    + optimizer-eval.llvm.lib     0.43 0.0172   0.0570   0.2122   0.3200   0.0725   |   81584    78640    60384    238984   620296   |    *     299+41     62+27  0+0    0+0    
    + 256.bzip2.lib               0.34 0.0250   0.0374   0.0117   0.1242   0.1508   |   139536   84856    40208    336816   1370784  |    *     569+37     12+2   0+0    0+0    
    + 181.mcf.lib                 0.23 0.0304   0.0296   0.0438   0.1255   0.0685   |   111384   145928   38568    313120   589808   |    161   384+51     27+10  0+0    0+0    
    + sim.llvm.lib                0.22 0.0138   0.0162   0.0146   0.0850   0.0891   |   55376    81680    21784    253848   721520   |    *     259+36     37+22  0+0    0+0    
    + voronoi.llvm.lib            0.20 0.0140   0.0311   0.0293   0.0962   0.0547   |   79696    85176    27272    205920   419920   |    18    294+76     17+8   0+0    0+0    
    + sgefa.llvm.lib              0.17 0.0088   0.0250   0.0223   0.0730   0.0615   |   85904    82240    67064    260872   364520   |    *     130+24     24+14  0+0    0+0    
    + bh.llvm.lib                 0.15 0.0120   0.0173   0.0126   0.0614   0.0548   |   55864    71416    27432    219376   473840   |    61    194+35     6+2    0+0    0+0    
    + em3d.llvm.lib               0.09 0.0066   0.0111   0.0088   0.0350   0.0284   |   24280    32960    12536    86576    224616   |    13    172+25     12+4   0+0    0+0    
    + health.llvm.lib             0.08 0.0052   0.0098   0.0062   0.0287   0.0330   |   29880    27920    7608     73008    199064   |    71    79+29      10+4   0+0    0+0    
    + mst.llvm.lib                0.07 0.0048   0.0068   0.0056   0.0266   0.0218   |   27408    16752    7040     66048    178328   |    10    97+15      12+3   0+0    0+0    
    + tsp.llvm.lib                0.06 0.0049   0.0069   0.0026   0.0222   0.0212   |   25704    14472    4872     52216    176600   |    21    42+15      7+4    0+0    0+0    
    + power.llvm.lib              0.06 0.0042   0.0065   0.0036   0.0217   0.0214   |   28512    17760    7848     61960    214128   |    *     81+18      11+2   0+0    0+0    
    + lists.llvm.lib              0.06 0.0042   0.0113   0.0071   0.0293   0.0146   |   24544    16912    14440    68008    141480   |    30    67+26      3+1    0+0    0+0    
    + perimeter.llvm.lib          0.05 0.0030   0.0058   0.0020   0.0186   0.0161   |   14936    14112    3928     45592    155208   |    *     35+15      7+4    0+0    0+0    
    + methcall.llvm.lib           0.05 0.0017   0.0042   0.0028   0.0137   0.0099   |   10984    9856     9144     44000    87328    |    30    43+12      14+8   0+0    0+0    
    + hash.llvm.lib               0.05 0.0031   0.0050   0.0039   0.0187   0.0163   |   17936    24808    8216     64232    153552   |    *     117+17     14+6   0+0    0+0    
    + bisort.llvm.lib             0.05 0.0048   0.0053   0.0018   0.0188   0.0125   |   13608    11744    3712     45984    126584   |    *     35+13      7+4    0+0    0+0    
    + objinst.llvm.lib            0.04 0.0018   0.0044   0.0032   0.0163   0.0103   |   11072    15328    10536    50496    87064    |    34    45+14      16+10  0+0    0+0    
    + llubenchmark.llvm.lib       0.04 0.0021   0.0022   0.0014   0.0125   0.0124   |   4728     9520     2624     33608    122712   |    *     31+7       15+5   0+0    0+0    
    + treeadd.llvm.lib            0.03 0.0015   0.0024   0.0009   0.0085   0.0077   |   3856     7384     2200     29784    72064    |    *     25+7       6+3    0+0    0+0    
    + sumarraymalloc.llvm.lib     0.03 0.0009   0.0035   0.0009   0.0088   0.0058   |   7040     2672     2048     25872    54352    |    *     23+5       7+4    0+0    0+0    
    + sieve.llvm.lib              0.03 0.0007   0.0011   0.0005   0.0060   0.0144   |   2176     6176     1632     23432    216840   |    *     22+2       12+1   0+0    0+0    
    + random.llvm.lib             0.03 0.0008   0.0016   0.0004   0.0063   0.0050   |   2056     5720     1320     22080    45264    |    *     15+2       3+1    0+0    0+0    
    + matrix.llvm.lib             0.03 0.0012   0.0021   0.0014   0.0093   0.0081   |   8720     8784     3048     36600    68048    |    *     38+9       12+8   0+0    0+0    
    + heapsort.llvm.lib           0.03 0.0010   0.0018   0.0006   0.0084   0.0064   |   7448     7224     1992     28032    62704    |    *     26+3       7+2    0+0    0+0    
    + fib2.llvm.lib               0.03 0.0008   0.0016   0.0007   0.0063   0.0048   |   2416     10376    1648     30088    43792    |    *     21+5       8+3    0+0    0+0    
    + ary3.llvm.lib               0.03 0.0012   0.0019   0.0011   0.0086   0.0073   |   8648     19856    2976     43080    73064    |    6     44+5       12+3   0+0    0+0    
    + sumarray2d.llvm.lib         0.02 0.0004   0.0008   0.0003   0.0031   0.0029   |   4208     856      3656     10904    21968    |    *     10+1       7+1    0+0    0+0    
    + printargs.llvm.lib          0.02 0.0005   0.0012   0.0002   0.0031   0.0024   |   1240     1048     696      5128     19160    |    *     6+1        4+1    0+0    0+0    
    + pi.llvm.lib                 0.02 0.0007   0.0015   0.0004   0.0050   0.0035   |   5392     1560     1392     8344     36032    |    *     17+2       13+2   0+0    0+0    
    + matrixTranspose.llvm.lib    0.02 0.0006   0.0011   0.0003   0.0036   0.0051   |   4248     1144     736      8520     68104    |    *     8+1        5+1    0+0    0+0    
    + indvars.llvm.lib            0.02 0.0005   0.0009   0.0003   0.0035   0.0037   |   1744     4088     1024     9696     31336    |    *     13+1       8+1    0+0    0+0    
    + ackermann.llvm.lib          0.02 0.0008   0.0014   0.0004   0.0056   0.0060   |   1744     5728     1200     22056    46448    |    *     13+2       3+1    0+0    0+0    
    + sumarray.llvm.lib           0.01 0.0014   0.0008   0.0002   0.0036   0.0021   |   904      3192     624      4720     15152    |    *     6+1        4+1    0+0    0+0    
    + hello.llvm.lib              0.01 0.0004   0.0015   0.0001   0.0028   0.0019   |   752      2952     472      6512     12264    |    *     2+0        0+0    0+0    0+0    
    + 

    + + +


    +

    Nov 9, 2002 #2:

    + + This has the first part of the globals graph implemented, this simply deletes + the nodes that should be moved to the globals graph, without saving them and + then later merging them back in (The GlobGr size indicates the size of the + globals graph: right now it is empty, this will be fixed in the future). From + this we can get some best case times that the final algorithm will not be + able to match, but it is interesting to see badly how the N2 case + hurts the TD pass.

    + + Note that I now know that gap and vortex are not working because of an infinite + loop in the algorithm, now that this is identified, hopefully it will be fixed + shortly.

    + + Note that these numbers are still with a debug build. Compiling with + optimizations and without assertions improves run time 3-4x.

    + +

    + Name:                     Anlyz: LocTime: BUTime:  TDTime:  TotTime:      LocSize: BUSize:  TDSize:    TotSize:     NumFold  NumNodes   main   __main GlobGr
    + 254.gap.lib                 4.92 *        *        *        *        |    *        *        *          *          |    *     *          *      *      *      
    + 255.vortex.lib              2.78 *        *        *        *        |    *        *        *          *          |    *     *          *      *      *      
    + 300.twolf.lib               3.50 0.2890   0.3094   0.5272   1.6337   |    487976   434248   418472     1340696    |    794   4223+808   88+45  0+0    0+0    
    + 197.parser.lib              1.70 0.1517   0.1978   0.2152   0.7588   |    408560   243688   213776     985496     |    1327  2257+706   14+6   0+0    0+0    
    + burg.llvm.lib               1.14 0.1056   0.1296   0.1720   0.5084   |    530224   478880   179080     1188184    |    722   2167+577   30+7   0+0    0+0    
    + 164.gzip.llvm.lib           0.65 0.0406   0.0256   0.0328   0.1651   |    201664   129304   70864      499448     |    24    971+87     8+2    0+0    0+0    
    + optimizer-eval.llvm.lib     0.40 0.0170   0.0366   0.2099   0.3047   |    81584    79352    62232      241544     |    *     309+41     72+27  0+0    0+0    
    + 256.bzip2.lib               0.29 0.0249   0.0107   0.0112   0.0943   |    139536   84752    39720      336224     |    *     563+37     8+2    0+0    0+0    
    + 181.mcf.lib                 0.20 0.0185   0.0247   0.0285   0.1042   |    111384   145912   43544      318080     |    156   393+51     23+10  0+0    0+0    
    + sim.llvm.lib                0.18 0.0143   0.0106   0.0129   0.0765   |    55376    83072    21968      255424     |    *     261+36     39+22  0+0    0+0    
    + voronoi.llvm.lib            0.15 0.0152   0.0203   0.0309   0.0807   |    79696    87280    27336      208088     |    18    299+77     15+8   0+0    0+0    
    + bh.llvm.lib                 0.13 0.0120   0.0100   0.0110   0.0506   |    55864    72480    27632      220640     |    61    194+35     6+2    0+0    0+0    
    + sgefa.llvm.lib              0.12 0.0088   0.0165   0.0199   0.0616   |    85904    82032    67032      260632     |    *     130+24     24+14  0+0    0+0    
    + health.llvm.lib             0.07 0.0051   0.0065   0.0054   0.0243   |    29880    31328    7816       76624      |    71    79+29      10+4   0+0    0+0    
    + em3d.llvm.lib               0.07 0.0059   0.0058   0.0058   0.0254   |    24280    33360    13344      87784      |    10    179+27     12+4   0+0    0+0    
    + power.llvm.lib              0.06 0.0043   0.0029   0.0051   0.0197   |    28512    17808    8008       62168      |    *     81+18      11+2   0+0    0+0    
    + tsp.llvm.lib                0.05 0.0051   0.0031   0.0027   0.0185   |    25704    14576    5040       52488      |    21    42+15      7+4    0+0    0+0    
    + perimeter.llvm.lib          0.05 0.0030   0.0036   0.0020   0.0163   |    14936    22008    4296       53856      |    *     35+15      7+4    0+0    0+0    
    + mst.llvm.lib                0.05 0.0051   0.0033   0.0038   0.0193   |    27408    16880    7216       66352      |    10    97+15      12+3   0+0    0+0    
    + lists.llvm.lib              0.05 0.0042   0.0058   0.0071   0.0227   |    24544    17384    13696      67736      |    30    67+26      3+1    0+0    0+0    
    + hash.llvm.lib               0.05 0.0030   0.0033   0.0041   0.0168   |    17936    25000    8544       64752      |    *     117+17     14+6   0+0    0+0    
    + objinst.llvm.lib            0.04 0.0018   0.0018   0.0033   0.0122   |    11072    16344    12040      53016      |    35    45+14      16+10  0+0    0+0    
    + methcall.llvm.lib           0.04 0.0017   0.0015   0.0029   0.0111   |    10984    9816     11880      46696      |    30    43+12      14+8   0+0    0+0    
    + llubenchmark.llvm.lib       0.04 0.0021   0.0010   0.0015   0.0115   |    4728     9384     2808       33656      |    *     31+7       15+5   0+0    0+0    
    + bisort.llvm.lib             0.04 0.0029   0.0022   0.0019   0.0128   |    13608    11840    3888       46256      |    *     35+13      7+4    0+0    0+0    
    + treeadd.llvm.lib            0.03 0.0014   0.0009   0.0010   0.0071   |    3856     12496    2392       35088      |    *     25+7       6+3    0+0    0+0    
    + sumarraymalloc.llvm.lib     0.03 0.0009   0.0008   0.0010   0.0063   |    7040     2192     2656       26000      |    *     23+5       7+4    0+0    0+0    
    + sieve.llvm.lib              0.03 0.0007   0.0005   0.0006   0.0063   |    2176     5832     1968       23424      |    *     22+2       12+1   0+0    0+0    
    + matrixTranspose.llvm.lib    0.03 0.0005   0.0002   0.0003   0.0026   |    4248     792      1088       8520       |    *     8+1        5+1    0+0    0+0    
    + matrix.llvm.lib             0.03 0.0013   0.0013   0.0015   0.0085   |    8720     8704     3416       36888      |    *     38+9       12+8   0+0    0+0    
    + ary3.llvm.lib               0.03 0.0012   0.0012   0.0012   0.0078   |    8648     14136    3328       37712      |    6     44+5       12+3   0+0    0+0    
    + random.llvm.lib             0.02 0.0008   0.0004   0.0005   0.0047   |    2056     4720     1656       21416      |    *     15+2       3+1    0+0    0+0    
    + pi.llvm.lib                 0.02 0.0007   0.0003   0.0005   0.0036   |    5392     1384     4768       11544      |    *     17+2       13+2   0+0    0+0    
    + hello.llvm.lib              0.02 0.0004   0.0001   0.0001   0.0015   |    752      2952     472        6512       |    *     2+0        0+0    0+0    0+0    
    + heapsort.llvm.lib           0.02 0.0009   0.0006   0.0007   0.0062   |    7448     6864     2360       28040      |    *     26+3       7+2    0+0    0+0    
    + fib2.llvm.lib               0.02 0.0008   0.0007   0.0007   0.0055   |    2416     5680     2000       25744      |    *     21+5       8+3    0+0    0+0    
    + ackermann.llvm.lib          0.02 0.0007   0.0004   0.0005   0.0046   |    1744     5368     1552       22048      |    *     13+2       3+1    0+0    0+0    
    + sumarray.llvm.lib           0.01 0.0003   0.0002   0.0002   0.0021   |    904      2232     624        3760       |    *     6+1        4+1    0+0    0+0    
    + sumarray2d.llvm.lib         0.01 0.0004   0.0002   0.0003   0.0026   |    4208     856      3656       10904      |    *     10+1       7+1    0+0    0+0    
    + printargs.llvm.lib          0.01 0.0004   0.0002   0.0003   0.0023   |    1240     704      1064       5152       |    *     6+1        4+1    0+0    0+0    
    + indvars.llvm.lib            0.01 0.0005   0.0003   0.0003   0.0030   |    1744     4088     1032       9704       |    *     13+1       8+1    0+0    0+0    
    + 

    + + +


    +

    Nov 9, 2002:

    + + Same as the
    previous run, but now with a small tweak: + constants are never put into the scalar map for a function. This is in + preparation for the global graph work, but it does speed analysis up + marginally:

    + +

    + Name:                     Anlyz: LocTime: BUTime:  TDTime:  TotTime:      LocSize: BUSize:  TDSize:    TotSize:     NumFold  NumNodes   main   __main
    + 254.gap.lib                 2.16 *        *        *        *        |    *        *        *          *          |    *     *          *      *      
    + 255.vortex.lib              1.11 *        *        *        *        |    *        *        *          *          |    *     *          *      *      
    + 300.twolf.lib              11.63 0.2468   0.7464   7.5333   9.2461   |    595576   795896   10397040   11788512   |    3577  161901+1222 854+0  854+0  
    + 197.parser.lib             10.97 0.1258   0.4903   8.6508   9.5864   |    464920   621904   12987664   14309904   |    2643  197546+1185 601+0  601+0  
    + burg.llvm.lib               5.18 0.0904   0.2948   3.7480   4.3338   |    576064   893240   4821880    6356592    |    1557  72659+919  436+0  436+0  
    + 164.gzip.llvm.lib           1.28 0.0355   0.1037   0.5037   0.7448   |    228456   511192   1971048    2809016    |    70    16642+233  171+0  171+0  
    + 256.bzip2.lib               0.69 0.0201   0.0535   0.3301   0.4626   |    163016   284360   1450312    1970944    |    20    11464+202  148+0  148+0  
    + optimizer-eval.llvm.lib     0.57 0.0195   0.0846   0.3000   0.4423   |    86832    180296   702840     988152     |    *     3693+101   63+0   63+0   
    + sim.llvm.lib                0.26 0.0137   0.0195   0.0619   0.1439   |    92280    106632   330888     602464     |    *     2738+67    99+0   99+0   
    + 181.mcf.lib                 0.23 0.0164   0.0294   0.0572   0.1265   |    133872   128088   229576     508384     |    180   1923+73    44+0   44+0   
    + voronoi.llvm.lib            0.19 0.0119   0.0245   0.0606   0.1138   |    83592    93192    211920     402648     |    17    1734+106   30+0   30+0   
    + sgefa.llvm.lib              0.17 0.0071   0.0333   0.0406   0.0994   |    88880    102320   133176     349144     |    *     634+55     31+0   31+0   
    + bh.llvm.lib                 0.15 0.0102   0.0154   0.0239   0.0697   |    77528    80672    110160     316400     |    66    716+64     13+0   13+0   
    + em3d.llvm.lib               0.09 0.0045   0.0105   0.0229   0.0477   |    37816    55256    123168     232944     |    8     1032+59    28+0   28+0   
    + mst.llvm.lib                0.07 0.0033   0.0056   0.0115   0.0310   |    30744    21600    62072      129088     |    10    471+36     21+0   21+0   
    + health.llvm.lib             0.07 0.0042   0.0080   0.0105   0.0313   |    31520    31784    45624      123896     |    71    362+40     14+0   14+0   
    + tsp.llvm.lib                0.06 0.0046   0.0047   0.0060   0.0240   |    19552    26040    25800      85696      |    19    248+31     10+0   10+0   
    + power.llvm.lib              0.06 0.0034   0.0050   0.0086   0.0254   |    30904    31232    29704      99512      |    *     277+35     9+0    9+0    
    + perimeter.llvm.lib          0.05 0.0025   0.0044   0.0037   0.0195   |    15760    24296    8552       61448      |    *     106+24     4+0    4+0    
    + lists.llvm.lib              0.05 0.0037   0.0075   0.0105   0.0283   |    25912    29360    28352      101472     |    50    252+34     10+0   10+0   
    + hash.llvm.lib               0.05 0.0025   0.0040   0.0059   0.0194   |    18464    25408    24192      81464      |    *     242+23     7+0    7+0    
    + llubenchmark.llvm.lib       0.04 0.0017   0.0022   0.0038   0.0198   |    12040    13368    17600      54016      |    *     145+20     15+0   15+0   
    + bisort.llvm.lib             0.04 0.0024   0.0035   0.0051   0.0176   |    14648    28160    22256      76136      |    *     211+27     10+0   10+0   
    + treeadd.llvm.lib            0.03 0.0011   0.0015   0.0020   0.0090   |    9320     8552     10120      44152      |    *     77+14      5+0    5+0    
    + sieve.llvm.lib              0.03 0.0006   0.0006   0.0008   0.0063   |    8032     1720     2552       22672      |    *     31+4       2+0    2+0    
    + objinst.llvm.lib            0.03 0.0015   0.0021   0.0036   0.0129   |    11272    19896    6096       50920      |    33    74+17      3+0    3+0    
    + methcall.llvm.lib           0.03 0.0014   0.0018   0.0028   0.0111   |    10936    15720    5152       45064      |    26    59+14      2+0    2+0    
    + matrix.llvm.lib             0.03 0.0014   0.0023   0.0025   0.0118   |    8984     8096     4352       37776      |    *     47+11      1+0    1+0    
    + ary3.llvm.lib               0.03 0.0010   0.0014   0.0014   0.0084   |    8992     8624     4344       37624      |    6     52+7       1+0    1+0    
    + sumarraymalloc.llvm.lib     0.02 0.0007   0.0009   0.0012   0.0069   |    2936     6984     7216       31496      |    *     39+8       2+0    2+0    
    + random.llvm.lib             0.02 0.0006   0.0006   0.0008   0.0057   |    2336     6000     2856       26944      |    *     32+5       3+0    3+0    
    + pi.llvm.lib                 0.02 0.0006   0.0006   0.0013   0.0047   |    5816     7240     6688       19744      |    *     34+6       3+0    3+0    
    + heapsort.llvm.lib           0.02 0.0007   0.0009   0.0012   0.0070   |    3128     7336     4008       29640      |    *     46+6       3+0    3+0    
    + fib2.llvm.lib               0.02 0.0007   0.0008   0.0008   0.0056   |    5704     1928     2520       22440      |    *     26+6       1+0    1+0    
    + sumarray.llvm.lib           0.01 0.0003   0.0002   0.0003   0.0022   |    960      3176     608        6856       |    *     7+2        0+0    0+0    
    + sumarray2d.llvm.lib         0.01 0.0003   0.0003   0.0004   0.0028   |    1736     6056     1064       11176      |    *     15+3       1+0    1+0    
    + printargs.llvm.lib          0.01 0.0003   0.0004   0.0005   0.0026   |    1464     848      3512       5824       |    *     13+4       1+0    1+0    
    + matrixTranspose.llvm.lib    0.01 0.0004   0.0004   0.0005   0.0030   |    4384     1248     3824       9456       |    *     17+4       3+0    3+0    
    + indvars.llvm.lib            0.01 0.0004   0.0005   0.0005   0.0033   |    4800     7440     1224       13464      |    *     18+3       1+0    1+0    
    + hello.llvm.lib              0.01 0.0003   0.0003   0.0003   0.0021   |    976      3024     2968       9224       |    *     8+3        1+0    1+0    
    + ackermann.llvm.lib          0.00 0.0000   0.0000   0.0001   0.0004   |    72       0        832        904        |    *     0+0        *      *      
    + 

    + +


    +

    Nov 8, 2002 #3:

    + + Same as the
    previous run, but now we automatically + collapse arrays down to a single element in the representation. The graphs + produced should be exactly the same, it's just memory consumption that goes + dramatically down, for example: 197.parser (64M->14M), 164.gzip + (14M->2.7M), 256.bzip (9M -> 1.9M), etc.

    + + With reduced memory consumption comes higher performance of course (better cache + behavior n stuff).

    + +

    + Name:                     Anlyz: LocTime: BUTime:  TDTime:  TotTime:      LocSize: BUSize:  TDSize:    TotSize:     NumFold  NumNodes   main   __main
    + 254.gap.lib                71.65 *        *        *        *        |    *        *        *          *          |    *     *          *      *      
    + 255.vortex.lib              4.62 *        *        *        *        |    *        *        *          *          |    *     *          *      *      
    + 300.twolf.lib              12.22 0.2369   0.8840   8.0785   9.9177   |    573880   770752   10364040   11708672   |    3514  161528+1101 854+0  854+0  
    + 197.parser.lib             11.73 0.1216   0.5217   9.3368   10.3099  |    461720   619960   12948496   14266336   |    2641  196932+1184 601+0  601+0  
    + burg.llvm.lib               5.35 0.0857   0.2873   3.9878   4.5484   |    650608   906016   4691952    6248576    |    1555  72533+902  436+0  436+0  
    + 164.gzip.llvm.lib           1.33 0.0309   0.1085   0.5445   0.7708   |    284312   521048   1877416    2779368    |    67    16632+232  171+0  171+0  
    + 256.bzip2.lib               0.73 0.0191   0.0588   0.3611   0.4995   |    156760   336272   1390240    1956528    |    20    11456+201  148+0  148+0  
    + optimizer-eval.llvm.lib     0.56 0.0129   0.0957   0.2881   0.4359   |    85720    178016   750424     1032352    |    *     3693+101   63+0   63+0   
    + sim.llvm.lib                0.29 0.0126   0.0237   0.0731   0.1630   |    93240    106144   331688     626088     |    *     2739+67    99+0   99+0   
    + 181.mcf.lib                 0.28 0.0153   0.0379   0.0649   0.1457   |    136744   155416   202496     511544     |    178   1914+72    44+0   44+0   
    + voronoi.llvm.lib            0.22 0.0122   0.0296   0.0728   0.1324   |    83568    94008    212560     404128     |    17    1733+106   30+0   30+0   
    + sgefa.llvm.lib              0.19 0.0072   0.0375   0.0491   0.1131   |    102144   109744   117064     353720     |    *     634+55     31+0   31+0   
    + bh.llvm.lib                 0.17 0.0098   0.0164   0.0260   0.0728   |    78048    82616    86688      311168     |    66    715+64     13+0   13+0   
    + em3d.llvm.lib               0.11 0.0046   0.0114   0.0327   0.0590   |    36344    64760    125360     243088     |    9     1031+59    28+0   28+0   
    + power.llvm.lib              0.09 0.0043   0.0053   0.0100   0.0296   |    22840    33912    30440      103016     |    *     277+35     9+0    9+0    
    + tsp.llvm.lib                0.08 0.0043   0.0057   0.0066   0.0276   |    20640    25416    25784      86464      |    19    247+31     10+0   10+0   
    + mst.llvm.lib                0.08 0.0033   0.0060   0.0123   0.0308   |    29088    31400    51632      126792     |    10    470+36     21+0   21+0   
    + lists.llvm.lib              0.08 0.0035   0.0080   0.0111   0.0294   |    25048    33872    25520      96760      |    50    246+34     10+0   10+0   
    + health.llvm.lib             0.08 0.0043   0.0083   0.0120   0.0344   |    31232    31256    45008      122464     |    71    361+40     14+0   14+0   
    + perimeter.llvm.lib          0.07 0.0036   0.0047   0.0049   0.0251   |    15336    22904    15968      66864      |    *     105+24     4+0    4+0    
    + objinst.llvm.lib            0.06 0.0016   0.0024   0.0090   0.0191   |    11032    15560    12416      52664      |    33    73+17      3+0    3+0    
    + bisort.llvm.lib             0.06 0.0023   0.0036   0.0065   0.0202   |    14376    20968    22152      68568      |    *     210+27     10+0   10+0   
    + llubenchmark.llvm.lib       0.05 0.0018   0.0024   0.0042   0.0166   |    11824    15464    23480      61776      |    *     144+20     15+0   15+0   
    + hash.llvm.lib               0.05 0.0026   0.0044   0.0062   0.0206   |    18192    24928    23976      80496      |    *     241+23     7+0    7+0    
    + methcall.llvm.lib           0.04 0.0014   0.0019   0.0031   0.0120   |    10824    9704     11128      45312      |    26    58+14      2+0    2+0    
    + ary3.llvm.lib               0.04 0.0010   0.0015   0.0014   0.0102   |    8752     17136    4168       45720      |    6     50+7       1+0    1+0    
    + treeadd.llvm.lib            0.03 0.0011   0.0016   0.0023   0.0098   |    9080     8408     9944       39424      |    *     76+14      5+0    5+0    
    + sieve.llvm.lib              0.03 0.0006   0.0006   0.0009   0.0063   |    7856     6056     2480       26760      |    *     30+4       2+0    2+0    
    + pi.llvm.lib                 0.03 0.0006   0.0007   0.0012   0.0050   |    5696     5272     5584       16552      |    *     34+6       3+0    3+0    
    + matrix.llvm.lib             0.03 0.0010   0.0017   0.0018   0.0096   |    8584     17680    4208       46232      |    *     46+11      1+0    1+0    
    + heapsort.llvm.lib           0.03 0.0010   0.0009   0.0013   0.0076   |    2936     7224     3912       29240      |    *     45+6       3+0    3+0    
    + sumarraymalloc.llvm.lib     0.02 0.0007   0.0009   0.0015   0.0072   |    2720     6872     7128       31152      |    *     38+8       2+0    2+0    
    + sumarray.llvm.lib           0.02 0.0003   0.0002   0.0003   0.0025   |    864      3144     592        6712       |    *     7+2        0+0    0+0    
    + random.llvm.lib             0.02 0.0006   0.0006   0.0009   0.0057   |    6184     1808     2752       23600      |    *     31+5       3+0    3+0    
    + printargs.llvm.lib          0.02 0.0003   0.0004   0.0006   0.0028   |    1360     816      3480       5656       |    *     13+4       1+0    1+0    
    + matrixTranspose.llvm.lib    0.02 0.0004   0.0004   0.0006   0.0034   |    5888     1224     4864       11976      |    *     17+4       3+0    3+0    
    + indvars.llvm.lib            0.02 0.0005   0.0005   0.0005   0.0037   |    4680     3552     1200       9432       |    *     18+3       1+0    1+0    
    + fib2.llvm.lib               0.02 0.0007   0.0008   0.0009   0.0059   |    6176     1808     2400       23008      |    *     25+6       1+0    1+0    
    + sumarray2d.llvm.lib         0.01 0.0004   0.0004   0.0004   0.0030   |    1648     6024     4144       14136      |    *     15+3       1+0    1+0    
    + hello.llvm.lib              0.01 0.0003   0.0003   0.0003   0.0022   |    880      592      2944       6672       |    *     8+3        1+0    1+0    
    + ackermann.llvm.lib          0.00 0.0000   0.0000   0.0002   0.0004   |    0        0        832        832        |    *     0+0        *      *      
    + 

    + + + +


    +

    Nov 8, 2002 #2:

    + + Same as the
    previous run, but with a huge bug fix: + before, all of the call nodes (from the local pass) were being passed up in the + BU pass, causing graph exposions. Now these call sites are not propagated. The + times and sized of graphs are all much smaller now.

    + +

    + Name:                     Anlyz: LocTime: BUTime:  TDTime:  TotTime:      LocSize: BUSize:  TDSize:    TotSize:     NumFold  NumNodes   main   __main
    + 254.gap.lib               130.47 *        *        *        *        |    *        *        *          *          |    *     *          *      *      
    + 255.vortex.lib             86.17 *        *        *        *        |    *        *        *          *          |    *     *          *      *      
    + 197.parser.lib             26.50 0.1601   1.4931   22.7485  24.7647  |    2187656  4037056  57704672   64165544   |    4550  196932+1184 601+0  601+0  
    + 300.twolf.lib              14.33 0.2311   1.0000   10.1733  12.1591  |    629008   1085616  15564712   17279336   |    4655  161528+1101 854+0  854+0  
    + burg.llvm.lib               6.71 0.0904   0.3799   5.1871   5.8809   |    745152   1254280  6822216    8821648    |    3253  72533+902  436+0  436+0  
    + 164.gzip.llvm.lib           6.07 0.1158   0.9992   4.1925   5.3966   |    2113120  2772872  9043760    14026344   |    233   16632+232  171+0  171+0  
    + 256.bzip2.lib               2.16 0.0239   0.1987   1.6047   1.8899   |    372776   1059888  7503640    9009560    |    132   11456+201  148+0  148+0  
    + sim.llvm.lib                1.54 0.0163   0.2356   1.0723   1.3738   |    106096   124280   400760     726152     |    41    2739+67    99+0   99+0   
    + optimizer-eval.llvm.lib     0.58 0.0126   0.0890   0.3282   0.4696   |    110464   188584   1055832    1373072    |    287   3693+101   63+0   63+0   
    + 181.mcf.lib                 0.33 0.0155   0.0465   0.1437   0.2308   |    156864   225184   805584     1204520    |    209   1914+72    44+0   44+0   
    + voronoi.llvm.lib            0.19 0.0111   0.0253   0.0644   0.1178   |    83248    93616    238648     429504     |    31    1733+106   30+0   30+0   
    + sgefa.llvm.lib              0.18 0.0069   0.0398   0.0492   0.1156   |    104712   108472   178920     416872     |    67    634+55     31+0   31+0   
    + bh.llvm.lib                 0.16 0.0100   0.0177   0.0355   0.0838   |    81376    93656    190104     428952     |    66    715+64     13+0   13+0   
    + health.llvm.lib             0.10 0.0230   0.0084   0.0138   0.0551   |    31232    31552    56984      134736     |    75    361+40     14+0   14+0   
    + em3d.llvm.lib               0.09 0.0045   0.0117   0.0255   0.0519   |    37336    67808    126960     248728     |    50    1031+59    28+0   28+0   
    + power.llvm.lib              0.07 0.0035   0.0053   0.0105   0.0287   |    23432    31680    42680      113616     |    3     277+35     9+0    9+0    
    + mst.llvm.lib                0.07 0.0033   0.0060   0.0145   0.0333   |    29080    31400    56720      131872     |    35    470+36     21+0   21+0   
    + lists.llvm.lib              0.07 0.0079   0.0129   0.0170   0.0453   |    27616    39648    75280      154864     |    54    246+34     10+0   10+0   
    + indvars.llvm.lib            0.07 0.0020   0.0257   0.0269   0.0569   |    85496    87560    161216     334272     |    *     18+3       1+0    1+0    
    + tsp.llvm.lib                0.06 0.0041   0.0049   0.0065   0.0250   |    19360    26216    26712      86912      |    23    247+31     10+0   10+0   
    + perimeter.llvm.lib          0.05 0.0024   0.0045   0.0039   0.0194   |    15336    22904    16288      67184      |    *     105+24     4+0    4+0    
    + hash.llvm.lib               0.05 0.0029   0.0043   0.0066   0.0211   |    25880    18176    28168      85624      |    2     241+23     7+0    7+0    
    + bisort.llvm.lib             0.05 0.0022   0.0036   0.0064   0.0192   |    14376    28616    22416      76480      |    3     210+27     10+0   10+0   
    + llubenchmark.llvm.lib       0.04 0.0017   0.0026   0.0045   0.0169   |    11824    24304    18168      65304      |    8     144+20     15+0   15+0   
    + treeadd.llvm.lib            0.03 0.0013   0.0016   0.0023   0.0101   |    9080     8408     11224      40704      |    2     76+14      5+0    5+0    
    + sumarray2d.llvm.lib         0.03 0.0014   0.0097   0.0106   0.0238   |    42056    46440    83192      174008     |    *     15+3       1+0    1+0    
    + sieve.llvm.lib              0.03 0.0008   0.0021   0.0032   0.0103   |    16064    14264    35312      76008      |    *     30+4       2+0    2+0    
    + objinst.llvm.lib            0.03 0.0015   0.0024   0.0037   0.0134   |    11032    15488    11440      51616      |    39    73+17      3+0    3+0    
    + methcall.llvm.lib           0.03 0.0014   0.0018   0.0030   0.0115   |    10824    9704     11128      45312      |    31    58+14      2+0    2+0    
    + matrix.llvm.lib             0.03 0.0011   0.0017   0.0018   0.0109   |    8584     17680    4208       46232      |    *     46+11      1+0    1+0    
    + ary3.llvm.lib               0.03 0.0010   0.0014   0.0014   0.0085   |    8752     17136    4168       45720      |    6     50+7       1+0    1+0    
    + sumarraymalloc.llvm.lib     0.02 0.0007   0.0009   0.0013   0.0070   |    2720     12824    3376       33352      |    *     38+8       2+0    2+0    
    + random.llvm.lib             0.02 0.0006   0.0009   0.0009   0.0060   |    6184     1808     2752       23600      |    *     31+5       3+0    3+0    
    + pi.llvm.lib                 0.02 0.0006   0.0007   0.0011   0.0049   |    5696     5272     6544       17512      |    *     34+6       3+0    3+0    
    + matrixTranspose.llvm.lib    0.02 0.0007   0.0033   0.0034   0.0095   |    14088    9424     29480      52992      |    *     17+4       3+0    3+0    
    + heapsort.llvm.lib           0.02 0.0008   0.0009   0.0013   0.0076   |    2936     7224     3912       29240      |    *     45+6       3+0    3+0    
    + fib2.llvm.lib               0.02 0.0014   0.0008   0.0009   0.0067   |    6176     1808     2400       23008      |    *     25+6       1+0    1+0    
    + sumarray.llvm.lib           0.01 0.0003   0.0003   0.0003   0.0022   |    1280     3552     584        7528       |    3     7+2        0+0    0+0    
    + printargs.llvm.lib          0.01 0.0005   0.0004   0.0006   0.0030   |    1360     816      4760       6936       |    *     13+4       1+0    1+0    
    + hello.llvm.lib              0.01 0.0003   0.0003   0.0003   0.0022   |    880      592      2944       6672       |    *     8+3        1+0    1+0    
    + ackermann.llvm.lib          0.01 0.0000   0.0000   0.0001   0.0004   |    0        0        832        832        |    *     0+0        *      *      
    + 

    + +


    +

    Nov 8, 2002:

    + + Same as the
    previous run, but now the Top-Down pass + has been rewritten to:

    + +

      +
    • Actually work on all of the benchmarks +
    • Require less book-keeping +
    • Only clone a caller graph into a particular callee graph once +
    • Not prune nodes as aggressively, this is probably the reason for many + slowdowns below. +

    + + Looking deeper into the results, gzip got slower by a factor of 4, optimizer + eval got slower by a factor of 3, sim slowed down just a little bit.

    + + Note that without the globals graph, some benchmarks are still VERY slow (those + with heavy use of globals).

    + +

    + Name:                     Anlyz: LocTime: BUTime:  TDTime:  TotTime:      LocSize: BUSize:  TDSize:    TotSize:     NumFold  NumNodes   main   __main
    + 254.gap.lib               330.50 *        *        *        *        |    *        *        *          *          |    *     *          *      *      
    + 255.vortex.lib                 * *        *        *        *        |    *        *        *          *          |    *     *          *      *      
    + 197.parser.lib            120.10 0.1649   11.8198  105.3900 118.0119 |    2188536  4525320  60972272   67921544   |    22575 202604+8604 601+0  601+0  
    + 300.twolf.lib              72.38 0.2431   1.8500   30.5671  72.3845  |    629008   1375352  16515832   18520192   |    18090 163168+3906 854+0  854+0  
    + burg.llvm.lib              34.18 0.0871   1.0919   15.8467  34.1754  |    749304   1755232  7209416    9779360    |    21707 78464+4387 393+0  393+0  
    + 164.gzip.llvm.lib          21.81 0.1149   1.2083   19.6981  21.1201  |    2055024  3145544  8929008    14227896   |    2387  18236+1588 171+0  171+0  
    + 256.bzip2.lib               7.44 0.0250   0.3032   6.2987   7.4430   |    372776   1205520  7660752    9312304    |    1765  11947+1011 148+0  148+0  
    + optimizer-eval.llvm.lib     3.24 0.0131   1.0648   1.9117   3.0792   |    110456   343032   1971952    2443624    |    5293  4186+1033  63+0   63+0   
    + sim.llvm.lib                2.27 0.0170   0.2274   1.7720   2.0708   |    104728   130376   451320     759088     |    62    2755+122   99+0   99+0   
    + 181.mcf.lib                 0.61 0.0162   0.0556   0.3631   0.4646   |    156648   234864   866704     1275064    |    243   2023+163   44+0   44+0   
    + voronoi.llvm.lib            0.45 0.0117   0.0447   0.2557   0.3385   |    83088    150936   337552     585520     |    157   2063+390   30+0   30+0   
    + bh.llvm.lib                 0.38 0.0101   0.0253   0.1778   0.2394   |    79736    129328   245408     502512     |    66    858+198    13+0   13+0   
    + sgefa.llvm.lib              0.27 0.0071   0.0396   0.0780   0.1465   |    104712   112576   204600     446656     |    130   640+103    31+0   31+0   
    + power.llvm.lib              0.14 0.0035   0.0080   0.0451   0.0675   |    31272    49768    66968      155680     |    6     359+96     9+0    9+0    
    + em3d.llvm.lib               0.13 0.0046   0.0140   0.0524   0.0825   |    37096    65320    122624     241744     |    141   920+127    21+0   21+0   
    + mst.llvm.lib                0.13 0.0033   0.0084   0.0381   0.0605   |    29104    36104    70496      150376     |    100   506+91     21+0   21+0   
    + lists.llvm.lib              0.12 0.0036   0.0118   0.0328   0.0664   |    27880    33064    98728      177520     |    58    270+63     10+0   10+0   
    + bisort.llvm.lib             0.11 0.0023   0.0047   0.0125   0.0270   |    14376    29520    33808      88776      |    6     226+42     10+0   10+0   
    + indvars.llvm.lib            0.11 0.0020   0.0254   0.0310   0.0606   |    85520    88232    161216     334968     |    *     18+3       1+0    1+0    
    + health.llvm.lib             0.10 0.0044   0.0113   0.0255   0.0519   |    31232    44592    53456      144248     |    79    385+69     14+0   14+0   
    + tsp.llvm.lib                0.10 0.0042   0.0062   0.0176   0.0382   |    27840    19008    51376      112528     |    27    271+55     10+0   10+0   
    + hash.llvm.lib               0.10 0.0026   0.0056   0.0168   0.0336   |    25880    29936    35312      104528     |    6     271+44     7+0    7+0    
    + heapsort.llvm.lib           0.09 0.0007   0.0009   0.0015   0.0429   |    2936     7384     4064       29552      |    *     47+7       3+0    3+0    
    + perimeter.llvm.lib          0.08 0.0025   0.0064   0.0090   0.0271   |    15432    25616    18552      72440      |    *     121+39     4+0    4+0    
    + objinst.llvm.lib            0.08 0.0015   0.0027   0.0076   0.0180   |    11032    16088    19848      60624      |    39    78+25      3+0    3+0    
    + sumarray2d.llvm.lib         0.06 0.0011   0.0098   0.0111   0.0241   |    42056    46440    83192      174008     |    *     15+3       1+0    1+0    
    + ary3.llvm.lib               0.06 0.0010   0.0016   0.0021   0.0096   |    8752     17528    4696       46640      |    6     55+10      1+0    1+0    
    + llubenchmark.llvm.lib       0.05 0.0018   0.0034   0.0063   0.0199   |    11824    20384    28056      71272      |    32    141+31     15+0   15+0   
    + treeadd.llvm.lib            0.05 0.0012   0.0023   0.0036   0.0121   |    9120     17640    10960      53880      |    4     82+18      5+0    5+0    
    + sumarray.llvm.lib           0.04 0.0003   0.0003   0.0003   0.0022   |    1280     3552     584        7528       |    3     7+2        0+0    0+0    
    + methcall.llvm.lib           0.03 0.0014   0.0021   0.0045   0.0147   |    10680    16000    11784      51720      |    31    63+19      2+0    2+0    
    + sieve.llvm.lib              0.03 0.0008   0.0022   0.0047   0.0120   |    16064    14528    39672      80632      |    *     32+5       2+0    2+0    
    + fib2.llvm.lib               0.03 0.0007   0.0009   0.0011   0.0063   |    5512     6088     2544       26432      |    *     27+7       1+0    1+0    
    + matrix.llvm.lib             0.02 0.0010   0.0017   0.0021   0.0100   |    8760     8104     8976       42184      |    *     48+12      1+0    1+0    
    + matrixTranspose.llvm.lib    0.02 0.0007   0.0034   0.0037   0.0098   |    14088    9424     29480      52992      |    *     17+4       3+0    3+0    
    + sumarraymalloc.llvm.lib     0.02 0.0007   0.0010   0.0016   0.0075   |    2720     12928    3536       33544      |    *     40+9       2+0    2+0    
    + pi.llvm.lib                 0.02 0.0006   0.0007   0.0014   0.0052   |    5696     5368     5680       16744      |    *     35+7       3+0    3+0    
    + random.llvm.lib             0.02 0.0006   0.0007   0.0012   0.0061   |    2136     6040     7248       31176      |    *     33+6       3+0    3+0    
    + printargs.llvm.lib          0.02 0.0003   0.0004   0.0007   0.0030   |    1360     1024     1728       4112       |    *     14+5       1+0    1+0    
    + hello.llvm.lib              0.02 0.0003   0.0003   0.0005   0.0023   |    880      648      768        4552       |    *     9+4        1+0    1+0    
    + ackermann.llvm.lib          0.02 0.0000   0.0000   0.0002   0.0004   |    0        0        832        832        |    *     0+0        *      *      
    + 

    + + +


    +

    Nov 7, 2002 #2:

    + + Same as the
    previous run, but now we actually handle + constants (especially constantexprs) correctly in the local and all subsequent + passes. This seems to dramatically improve many benchmarks, only slowing down + gzip significantly.

    + +

    + Name:                     Anlyz: LocTime: BUTime:  TDTime:  TotTime:      LocSize: BUSize:  TDSize:    TotSize:     NumFold  NumNodes   main   __main
    + 300.twolf.lib              30.88 *        *        *        *        |    *        *        *          *          |    *     *          *      *      
    + 255.vortex.lib             15.71 *        *        *        *        |    *        *        *          *          |    *     *          *      *      
    + 254.gap.lib                 6.07 analyze: ../../../include/llvm/Analysis/DSNode.h:77: DSNode::~DSNode(): Assertion `Referrers.empty() && "Referrers to dead node exist!"' failed.
    + 164.gzip.llvm.lib           5.32 0.1157   1.0296   3.4025   4.6326   |    2054352  2631576  7804656    12588904   |    398   13372+217  174+3  174+3  
    + 256.bzip2.lib               2.36 0.0250   0.1913   1.8190   2.0966   |    371928   1045320  7533440    9023600    |    407   11415+149  151+2  151+2  
    + sim.llvm.lib                1.97 0.0174   0.2155   1.4731   1.7539   |    104584   120112   449736     747416     |    46    2745+52    101+2  101+2  
    + 197.parser.lib              1.27 analyze: ../../../include/llvm/Analysis/DSNode.h:77: DSNode::~DSNode(): Assertion `Referrers.empty() && "Referrers to dead node exist!"' failed.
    + optimizer-eval.llvm.lib     1.09 0.0132   0.0926   0.8104   0.9528   |    109416   186592   1827184    2141376    |    1709  8189+43    63+0   63+0   
    + burg.llvm.lib               0.81 analyze: ../../../include/llvm/Analysis/DSNode.h:77: DSNode::~DSNode(): Assertion `Referrers.empty() && "Referrers to dead node exist!"' failed.
    + 181.mcf.lib                 0.38 0.0163   0.0470   0.1847   0.2714   |    156304   219896   808112     1201160    |    226   1859+0     44+0   44+0   
    + voronoi.llvm.lib            0.22 0.0118   0.0241   0.0776   0.1293   |    82728    87872    214584     399128     |    31    1650+0     30+0   30+0   
    + sgefa.llvm.lib              0.19 0.0074   0.0324   0.0716   0.1303   |    104560   104744   200024     434096     |    89    610+1      32+0   32+0   
    + bh.llvm.lib                 0.17 0.0106   0.0158   0.0344   0.0813   |    80112    86984    210008     425144     |    66    678+3      16+0   16+0   
    + em3d.llvm.lib               0.16 0.0067   0.0111   0.0619   0.0899   |    37600    55936    217632     327872     |    90    1584+522   38+3   38+3   
    + health.llvm.lib             0.10 0.0044   0.0071   0.0117   0.0322   |    31120    38712    35248      120048     |    81    328+0      14+0   14+0   
    + lists.llvm.lib              0.09 0.0037   0.0075   0.0296   0.0477   |    27792    32968    83288      162264     |    61    222+0      10+0   10+0   
    + llubenchmark.llvm.lib       0.09 0.0018   0.0021   0.0060   0.0178   |    11104    12176    32552      66840      |    35    152+22     17+1   17+1   
    + power.llvm.lib              0.08 0.0036   0.0045   0.0139   0.0308   |    21672    31000    40512      109008     |    5     246+0      9+0    9+0    
    + mst.llvm.lib                0.07 0.0033   0.0051   0.0125   0.0296   |    28368    27552    49088      119680     |    54    435+1      21+0   21+0   
    + indvars.llvm.lib            0.07 0.0020   0.0199   0.0281   0.0521   |    85496    84840    164280     334616     |    *     15+0       1+0    1+0    
    + perimeter.llvm.lib          0.06 0.0027   0.0035   0.0037   0.0180   |    15312    12112    14536      54800      |    *     83+0       4+0    4+0    
    + tsp.llvm.lib                0.05 0.0045   0.0041   0.0063   0.0254   |    27736    15016    25296      82352      |    28    228+1      11+0   11+0   
    + hash.llvm.lib               0.04 0.0025   0.0038   0.0054   0.0202   |    18288    24528    26104      82320      |    2     220+0      7+0    7+0    
    + bisort.llvm.lib             0.04 0.0025   0.0030   0.0050   0.0178   |    14296    19056    28384      72808      |    5     186+0      10+0   10+0   
    + sumarray2d.llvm.lib         0.04 0.0011   0.0077   0.0102   0.0210   |    42032    46264    83960      174576     |    *     12+0       1+0    1+0    
    + treeadd.llvm.lib            0.04 0.0011   0.0013   0.0017   0.0086   |    9008     7360     10264      42432      |    2     64+0       5+0    5+0    
    + objinst.llvm.lib            0.03 0.0021   0.0019   0.0049   0.0147   |    10928    15344    24592      64520      |    31    151+72     9+4    9+4    
    + methcall.llvm.lib           0.03 0.0014   0.0016   0.0030   0.0111   |    15520    8928     8032       45736      |    27    99+44      8+4    8+4    
    + matrix.llvm.lib             0.03 0.0010   0.0015   0.0017   0.0086   |    8680     8424     8200       41304      |    *     39+0       1+0    1+0    
    + sieve.llvm.lib              0.03 0.0007   0.0021   0.0032   0.0101   |    10320    13864    34512      72456      |    *     26+0       2+0    2+0    
    + sumarraymalloc.llvm.lib     0.03 0.0007   0.0008   0.0008   0.0060   |    2656     6144     6848       30024      |    *     31+0       2+0    2+0    
    + matrixTranspose.llvm.lib    0.03 0.0006   0.0027   0.0034   0.0087   |    14064    9080     28600      51744      |    *     14+0       3+0    3+0    
    + ary3.llvm.lib               0.02 0.0011   0.0013   0.0012   0.0081   |    8720     6968     8256       39992      |    6     44+0       1+0    1+0    
    + heapsort.llvm.lib           0.02 0.0008   0.0008   0.0008   0.0077   |    2896     13464    2552       33728      |    *     39+0       3+0    3+0    
    + random.llvm.lib             0.02 0.0007   0.0006   0.0006   0.0056   |    6296     4848     6112       29856      |    *     26+0       3+0    3+0    
    + fib2.llvm.lib               0.01 0.0007   0.0007   0.0006   0.0052   |    5488     5408     1344       24888      |    *     19+0       1+0    1+0    
    + pi.llvm.lib                 0.01 0.0006   0.0006   0.0009   0.0043   |    5656     4768     5416       15840      |    *     29+0       3+0    3+0    
    + printargs.llvm.lib          0.01 0.0003   0.0003   0.0003   0.0023   |    1336     560      728        2624       |    *     9+0        1+0    1+0    
    + sumarray.llvm.lib           0.01 0.0003   0.0003   0.0002   0.0022   |    1256     2456     456        6280       |    3     5+0        0+0    0+0    
    + hello.llvm.lib              0.01 0.0003   0.0003   0.0002   0.0019   |    840      2872     3136       6848       |    *     5+0        1+0    1+0    
    + ackermann.llvm.lib          0.01 *        *        *        *        |    *        *        *          *          |    *     0+0        *      *      
    + 

    + + +


    +

    Nov 7, 2002:

    + + Notes: Debug build, no globals graph, no array collapsing.

    + + Things are a big slower than before due to corrected handling of global + variables. + +

    + Name:                     Anlyz: LocTime: BUTime:  TDTime:  TotTime:      LocSize: BUSize:  TDSize:    TotSize:     NumFold  NumNodes   main   __main
    + 254.gap.lib                 6.23 analyze: ../../../include/llvm/Analysis/DSNode.h:77: DSNode::~DSNode(): Assertion `Referrers.empty() && "Referrers to dead node exist!"' failed.
    + sim.llvm.lib                3.77 0.0156   0.3313   1.6634   2.0787   |    63080    98008    192424     426656     |    *     1825+84    63+2   63+2   
    + 300.twolf.lib             374.15 *        *        *        *        |    *        *        *          *          |    *     *          *      *      
    + 255.vortex.lib            185.26 *        *        *        *        |    *        *        *          *          |    *     *          *      *      
    + 256.bzip2.lib               1.10 0.0158   0.0679   0.7397   0.8794   |    213592   385312   3368648    4040464    |    18    5238+257   64+1   64+1   
    + 164.gzip.llvm.lib           1.08 0.0260   0.0797   0.3326   0.5279   |    235048   421744   1484408    2237792    |    21    9628+634   113+1  113+1  
    + 197.parser.lib              1.06 analyze: ../../../include/llvm/Analysis/DSNode.h:77: DSNode::~DSNode(): Assertion `Referrers.empty() && "Referrers to dead node exist!"' failed.
    + burg.llvm.lib               0.71 analyze: ../../../include/llvm/Analysis/DSNode.h:77: DSNode::~DSNode(): Assertion `Referrers.empty() && "Referrers to dead node exist!"' failed.
    + optimizer-eval.llvm.lib     0.67 0.0115   0.0793   0.4125   0.5422   |    78080    141896   372592     610760     |    58    666+27     2+0    2+0    
    + 181.mcf.lib                 0.32 0.0125   0.0418   0.1271   0.2052   |    120504   192920   545696     876008     |    186   753+0      14+0   14+0   
    + voronoi.llvm.lib            0.18 0.0098   0.0204   0.0661   0.1116   |    78560    83344    116304     292200     |    19    1006+0     16+0   16+0   
    + sgefa.llvm.lib              0.16 0.0064   0.0340   0.0413   0.0999   |    82280    96016    67960      270944     |    *     125+2      2+0    2+0    
    + sieve.llvm.lib              0.16 0.0007   0.0028   0.0209   0.0295   |    9872     13808    38872      76312      |    *     22+0       1+0    1+0    
    + lists.llvm.lib              0.15 0.0027   0.0061   0.0042   0.0217   |    22256    14256    3208       51720      |    52    38+0       0+0    0+0    
    + bh.llvm.lib                 0.14 0.0082   0.0140   0.0171   0.0630   |    73320    75448    42920      255160     |    74    402+4      10+0   10+0   
    + em3d.llvm.lib               0.14 0.0037   0.0091   0.0303   0.0522   |    33816    50768    109200     202192     |    10    925+410    19+3   19+3   
    + hash.llvm.lib               0.14 0.0020   0.0033   0.0036   0.0154   |    17488    23928    12584      67400      |    *     131+0      2+0    2+0    
    + llubenchmark.llvm.lib       0.13 0.0013   0.0011   0.0019   0.0128   |    9680     2144     10072      32904      |    *     51+10      4+1    4+1    
    + indvars.llvm.lib            0.12 0.0022   0.0248   0.0422   0.0713   |    82040    87944    160872     333400     |    *     12+0       0+0    0+0    
    + ary3.llvm.lib               0.12 0.0008   0.0011   0.0009   0.0072   |    7992     7808     2416       34264      |    6     37+0       0+0    0+0    
    + health.llvm.lib             0.10 0.0035   0.0067   0.0067   0.0280   |    28432    27984    12640      83984      |    72    151+1      6+0    6+0    
    + hello.llvm.lib              0.10 0.0002   0.0002   0.0002   0.0016   |    504      2816     336        3656       |    *     2+0        0+0    0+0    
    + ackermann.llvm.lib          0.09 0.0004   0.0005   0.0004   0.0045   |    6976     992      840        18736      |    *     10+0       0+0    0+0    
    + objinst.llvm.lib            0.08 0.0014   0.0019   0.0052   0.0137   |    9480     19064    12216      54416      |    25    148+80     7+4    7+4    
    + sumarray2d.llvm.lib         0.08 0.0012   0.0096   0.0109   0.0235   |    41416    47080    80696      171512     |    *     9+0        0+0    0+0    
    + methcall.llvm.lib           0.08 0.0011   0.0016   0.0032   0.0108   |    3952     17528    8584       43720      |    23    104+52     7+4    7+4    
    + heapsort.llvm.lib           0.08 0.0006   0.0008   0.0007   0.0063   |    2264     13720    2216       33016      |    *     33+0       2+0    2+0    
    + fib2.llvm.lib               0.08 0.0005   0.0006   0.0004   0.0048   |    1776     5312     1080       23992      |    *     14+0       0+0    0+0    
    + tsp.llvm.lib                0.07 0.0036   0.0035   0.0041   0.0197   |    17304    13808    17968      63704      |    18    95+1       4+0    4+0    
    + random.llvm.lib             0.07 0.0005   0.0006   0.0005   0.0066   |    1584     4704     5752       25264      |    *     21+0       2+0    2+0    
    + pi.llvm.lib                 0.07 0.0004   0.0004   0.0005   0.0031   |    4744     1248     4368       10360      |    *     14+0       0+0    0+0    
    + power.llvm.lib              0.06 0.0031   0.0063   0.0070   0.0251   |    19440    28024    23544      86832      |    *     146+0      4+0    4+0    
    + bisort.llvm.lib             0.06 0.0019   0.0036   0.0026   0.0168   |    12776    18296    6808       48952      |    *     89+0       4+0    4+0    
    + matrixTranspose.llvm.lib    0.06 0.0005   0.0019   0.0025   0.0065   |    9136     14520    25336      48992      |    *     10+0       1+0    1+0    
    + printargs.llvm.lib          0.06 0.0003   0.0003   0.0003   0.0021   |    888      504      512        1904       |    *     5+0        0+0    0+0    
    + perimeter.llvm.lib          0.05 0.0026   0.0042   0.0044   0.0220   |    13968    12464    3928       43016      |    *     35+0       1+0    1+0    
    + mst.llvm.lib                0.05 0.0026   0.0040   0.0052   0.0227   |    16520    25840    14016      71048      |    10    217+1      9+0    9+0    
    + sumarray.llvm.lib           0.05 0.0002   0.0003   0.0002   0.0020   |    976      3424     464        6976       |    3     5+0        0+0    0+0    
    + treeadd.llvm.lib            0.03 0.0010   0.0011   0.0009   0.0085   |    7928     6424     2088       28432      |    *     27+0       1+0    1+0    
    + matrix.llvm.lib             0.02 0.0020   0.0013   0.0014   0.0090   |    7856     10416    2200       36232      |    *     32+0       0+0    0+0    
    + sumarraymalloc.llvm.lib     0.02 0.0006   0.0007   0.0005   0.0056   |    2032     5984     1368       23472      |    *     17+0       0+0    0+0    
    + 

    + + + +


    +

    Nov 6, 2002:

    + + Notes: Debug build, no globals graph, no array collapsing.

    + +

    + Name:                         LocTime:  BUTime:   TDTime:   TotTime:  AnlzTime:      LocSize:  BUSize:   TDSize:   TotSize:    NumFold NumNodes  main    __main  
    + ackermann.llvm.lib            0.0004    0.0005    0.0004    0.0045    0m0.040s  |    6976      992       840       18736     |    *    10+0      0+0     0+0     
    + ary3.llvm.lib                 0.0008    0.0012    0.0012    0.0074    0m0.034s  |    7992      7808      2416      34264     |    6    37+0      0+0     0+0     
    + fib2.llvm.lib                 0.0005    0.0006    0.0004    0.0047    0m0.019s  |    1776      5312      1080      23992     |    *    14+0      0+0     0+0     
    + hash.llvm.lib                 0.0020    0.0031    0.0036    0.0157    0m0.046s  |    17488     23928     12584     67400     |    *    131+0     2+0     2+0     
    + heapsort.llvm.lib             0.0006    0.0008    0.0007    0.0061    0m0.023s  |    2264      13720     2216      33016     |    *    33+0      2+0     2+0     
    + hello.llvm.lib                0.0002    0.0002    0.0002    0.0015    0m0.014s  |    504       2816      336       3656      |    *    2+0       0+0     0+0     
    + lists.llvm.lib                0.0029    0.0057    0.0057    0.0203    0m0.077s  |    22272     14264     12128     60688     |    57   38+0      0+0     0+0     
    + llubenchmark.llvm.lib         0.0012    0.0011    0.0017    0.0111    0m0.036s  |    9680      2144      9944      32776     |    *    49+8      4+1     4+1     
    + matrix.llvm.lib               0.0008    0.0013    0.0014    0.0079    0m0.038s  |    7848      10416     2200      36176     |    *    32+0      0+0     0+0     
    + matrixTranspose.llvm.lib      0.0004    0.0015    0.0019    0.0054    0m0.031s  |    9136      14520     25336     48992     |    *    10+0      1+0     1+0     
    + methcall.llvm.lib             0.0010    0.0018    0.0030    0.0108    0m0.080s  |    3952      17528     9024      44160     |    30   112+52    7+4     7+4     
    + objinst.llvm.lib              0.0011    0.0018    0.0058    0.0149    0m0.061s  |    9480      19064     13192     55392     |    37   163+80    7+4     7+4     
    + pi.llvm.lib                   0.0005    0.0004    0.0005    0.0032    0m0.027s  |    4744      1248      4368      10360     |    *    14+0      0+0     0+0     
    + printargs.llvm.lib            0.0003    0.0005    0.0003    0.0023    0m0.042s  |    888       504       512       1904      |    *    5+0       0+0     0+0     
    + random.llvm.lib               0.0005    0.0005    0.0005    0.0056    0m0.032s  |    1584      4704      5752      25264     |    *    21+0      2+0     2+0     
    + sumarray.llvm.lib             0.0002    0.0003    0.0002    0.0020    0m0.034s  |    976       3424      464       6976      |    3    5+0       0+0     0+0     
    + sumarray2d.llvm.lib           0.0010    0.0077    0.0111    0.0216    0m0.047s  |    41416     47080     80696     171512    |    *    9+0       0+0     0+0     
    + sumarraymalloc.llvm.lib       0.0007    0.0007    0.0005    0.0054    0m0.032s  |    2032      5984      1368      23472     |    *    17+0      0+0     0+0     
    + indvars.llvm.lib              0.0018    0.0189    0.0264    0.0490    0m0.065s  |    82040     87944     160872    333400    |    *    12+0      0+0     0+0     
    + bh.llvm.lib                   0.0113    0.0128    0.0163    0.0597    0m0.148s  |    55112     75768     42928     240056    |    74   400+5     11+0    11+0    
    + bisort.llvm.lib               0.0018    0.0024    0.0024    0.0123    0m0.051s  |    12776     18296     6808      48952     |    *    89+0      4+0     4+0     
    + em3d.llvm.lib                 0.0035    0.0098    0.0196    0.0490    0m0.103s  |    33816     49744     54144     146112    |    10   518+33    14+1    14+1    
    + health.llvm.lib               0.0033    0.0061    0.0057    0.0226    0m0.088s  |    28432     27992     12640     83992     |    72   151+1     6+0     6+0     
    + mst.llvm.lib                  0.0025    0.0039    0.0050    0.0192    0m0.074s  |    16520     25840     14016     71048     |    10   217+1     9+0     9+0     
    + perimeter.llvm.lib            0.0020    0.0032    0.0025    0.0154    0m0.045s  |    13968     12720     3928      43272     |    *    35+0      1+0     1+0     
    + power.llvm.lib                0.0027    0.0039    0.0060    0.0232    0m0.062s  |    20960     30136     23504     82696     |    *    146+0     4+0     4+0     
    + treeadd.llvm.lib              0.0009    0.0010    0.0008    0.0070    0m0.054s  |    7928      6424      2088      28432     |    *    27+0      1+0     1+0     
    + tsp.llvm.lib                  0.0035    0.0034    0.0032    0.0187    0m0.064s  |    17304     13808     17968     63704     |    18   95+1      4+0     4+0     
    + voronoi.llvm.lib              0.0093    0.0193    0.0567    0.1033    0m0.199s  |    78560     83336     116312    292200    |    19   1006+0    16+0    16+0    
    + optimizer-eval.llvm.lib       0.0099    0.1017    0.4073    0.5492    0m0.674s  |    76736     140000    409448    644528    |    58   1259+23   7+0     7+0     
    + sgefa.llvm.lib                0.0057    0.0283    0.0357    0.0863    0m0.153s  |    82280     96016     67728     270712    |    *    121+2     2+0     2+0     
    + sieve.llvm.lib                0.0006    0.0020    0.0030    0.0096    0m0.033s  |    9872      13808     38872     76312     |    *    22+0      1+0     1+0     
    + sim.llvm.lib                  0.0134    0.2127    1.1230    1.3938    0m1.559s  |    62864     98984     200600    457536    |    *    1807+206  71+7    71+7    
    + 164.gzip.llvm.lib             0.0225    0.0727    0.2910    0.4651    0m1.003s  |    235048    421864    1439120   2192624   |    17   9181+106  114+1   114+1   
    + 181.mcf.lib                   0.0121    0.0354    0.1096    0.1780    0m0.292s  |    120504    192920    545720    876032    |    195  753+0     14+0    14+0    
    + 197.parser.lib                analyze: ../../../include/llvm/Analysis/DSNode.h:74: DSNode::~DSNode(): Assertion `Referrers.empty() && "Referrers to dead node exist!"' failed.
    + 254.gap.lib                   analyze: ../../../include/llvm/Analysis/DSNode.h:74: DSNode::~DSNode(): Assertion `Referrers.empty() && "Referrers to dead node exist!"' failed.
    + 255.vortex.lib                analyze: ../../../include/llvm/Analysis/DSNode.h:74: DSNode::~DSNode(): Assertion `Referrers.empty() && "Referrers to dead node exist!"' failed.
    + 256.bzip2.lib                 0.0149    0.0604    0.6503    0.7810    0m1.027s  |    210880    387776    3371632   4041800   |    18   5005+76   65+1    65+1    
    + 300.twolf.lib                 0.1806    0.5248    42.5463   43.8329   0m45.785s |    522056    653816    10076992  11252864  |    1269 78066+4900 410+12  410+12  
    + burg.llvm.lib                 analyze: ../../../include/llvm/Analysis/DSNode.h:74: DSNode::~DSNode(): Assertion `Referrers.empty() && "Referrers to dead node exist!"' failed.
    + 
    + +
    +
    Chris Lattner
    + The LLVM Compiler Infrastructure +
    + + + Last modified: Thu Nov 14 20:00:50 CST 2002 + + + Index: llvm-www/releases/1.0/FAQ.html diff -c /dev/null llvm-www/releases/1.0/FAQ.html:1.1 *** /dev/null Fri Oct 24 15:51:50 2003 --- llvm-www/releases/1.0/FAQ.html Fri Oct 24 15:51:39 2003 *************** *** 0 **** --- 1,162 ---- + + +

    +
    + LLVM: Frequently Asked Questions +
    +

    + +
    + + +

    + Source Code +

    + + +
    +
    In what language is LLVM written? +
    + All of the LLVM tools and libraries are written in C++ with extensive use + of the STL. +

    + +

    How portable is the LLVM source code? +
    + The LLVM source code should be portable to most modern UNIX-like operating + systems. Most of the code is written in standard C++ with operating + system services abstracted to a support library. The tools required to + build and test LLVM have been ported to a plethora of platforms. +

    + Some porting problems may exist in the following areas: +

      +
    • The GCC front end code is not as portable as the LLVM suite, so it + may not compile as well on unsupported platforms. + +

      + +

    • The Python test classes are more UNIX-centric than they should be, + so porting to non-UNIX like platforms (i.e. Windows, MacOS 9) will + require some effort. +

      + +

    • The LLVM build system relies heavily on UNIX shell tools, like the + Bourne Shell and sed. Porting to systems without these tools (MacOS 9, + Plan 9) will require more effort. +
    +
    + +
    + + +

    + Build Problems +

    + + +
    +
    When I run configure, it finds the wrong C compiler. +
    + The configure script attempts to locate first gcc and + then cc, unless it finds compiler paths set in CC and + CXX for the C and C++ compiler, respectively. + + If configure finds the wrong compiler, either adjust your + PATH environment variable or set CC and CXX + explicitly. +

    + +

    I compile the code, and I get some error about /localhome. +
    + There are several possible causes for this. The first is that you + didn't set a pathname properly when using configure, and it + defaulted to a pathname that we use on our research machines. +

    + Another possibility is that we hardcoded a path in our Makefiles. If + you see this, please email the LLVM bug mailing list with the name of + the offending Makefile and a description of what is wrong with it. + +

    The configure script finds the right C compiler, but it + uses the LLVM linker from a previous build. What do I do? +
    + The configure script uses the PATH to find + executables, so if it's grabbing the wrong linker/assembler/etc, there + are two ways to fix it: +
      +
    1. Adjust your PATH environment variable so that the + correct program appears first in the PATH. This may work, + but may not be convenient when you want them first in your + path for other work. +

      + +

    2. Run configure with an alternative PATH that + is correct. In a Borne compatible shell, the syntax would be: +

      + PATH= ./configure ... +

      + This is still somewhat inconvenient, but it allows + configure to do its work without having to adjust your + PATH permanently. +

    + +
    When creating a dynamic library, I get a strange GLIBC error. +
    + Under some operating systems (i.e. Linux), libtool does not work correctly + if GCC was compiled with the --disable-shared option. To work around this, + install your own version of GCC that has shared libraries enabled by + default. +

    + +

    I've updated my source tree from CVS, and now my build is trying to + use a file/directory that doesn't exist. +
    + You need to re-run configure in your object directory. When new Makefiles + are added to the source tree, they have to be copied over to the object + tree in order to be used by the build. +

    + +

    I've modified a Makefile in my source tree, but my build tree keeps + using the old version. What do I do? +
    + If the Makefile already exists in your object tree, you can just run the + following command in the top level directory of your object tree: +

    + ./config.status <relative path to Makefile> +

    + If the Makefile is new, you will have to modify the configure script to copy + it over. +

    + +

    I've upgraded to a new version of LLVM, and I get strange build + errors. +
    + Sometimes changes to the LLVM source code alters how the build system + works. Changes in libtool, autoconf, or header file dependencies are + especially prone to this sort of problem. +

    + The best thing to try is to remove the old files and re-build. In most + cases, this takes care of the problem. To do this, just type make + clean and then make in the directory that fails to build. +

    + +

    I've built LLVM and am testing it, but the tests freeze. +
    + This is most likely occurring because you built a profile or release + (optimized) build of LLVM and have not specified the same information on + the gmake command line. +

    + For example, if you built LLVM with the command: +

    + gmake ENABLE_PROFILING=1 +

    + ...then you must run the tests with the following commands: +

    + cd llvm/test
    gmake ENABLE_PROFILING=1
    +

    +
    + + The LLVM Compiler Infrastructure +
    + + + Index: llvm-www/releases/1.0/GettingStarted.html diff -c /dev/null llvm-www/releases/1.0/GettingStarted.html:1.1 *** /dev/null Fri Oct 24 15:51:50 2003 --- llvm-www/releases/1.0/GettingStarted.html Fri Oct 24 15:51:39 2003 *************** *** 0 **** --- 1,1049 ---- + + + + Getting Started with LLVM System + + + +

    Getting Started with the LLVM System
    By: Guochun Shi, + Chris Lattner, + John Criswell, + Misha Brukman, and + Vikram Adve +

    + + +

    Contents

    + + + + + + +
    +

    Overview

    +
    +
    + + + Welcome to LLVM! In order to get started, you first need to know some + basic information. + +

    + First, LLVM comes in two pieces. The first piece is the LLVM suite. This + contains all of the tools, libraries, and header files needed to use the + low level virtual machine. It contains an assembler, disassembler, + bytecode analyzer, and bytecode optimizer. It also contains a test suite + that can be used to test the LLVM tools and the GCC front end. +

    + The second piece is the GCC front end. This component provides a version + of GCC that compiles C and C++ code into LLVM bytecode. Currently, the + GCC front end is a modified version of GCC 3.4 (we track the GCC 3.4 + development). Once compiled into LLVM bytecode, a program can be + manipulated with the LLVM tools from the LLVM suite. + + +

    +

    Getting Started Quickly (A Summary)

    +
    +
    + + + Here's the short story for getting up and running quickly with LLVM: +
      +
    1. Install the GCC front end: +
        +
      1. cd where-you-want-the-C-front-end-to-live +
      2. gunzip --stdout cfrontend.platform.tar.gz | tar -xvf + - +
      3. Sparc Only:
        + + cd cfrontend/sparc
        + ./fixheaders +
        +
      + +

      + +

    2. Get the Source Code +
        +
      • With the distributed files: +
          +
        1. cd where-you-want-llvm-to-live +
        2. gunzip --stdout llvm.tar.gz | tar -xvf - +
        3. cd llvm +
        + +

        + +

      • With anonymous CVS access: +
          +
        1. cd where-you-want-llvm-to-live +
        2. cvs -d :pserver:anon at llvm-cvs.cs.uiuc.edu:/var/cvs/llvm login +
        3. Hit the return key when prompted for the password. +
        4. cvs -d :pserver:anon at llvm-cvs.cs.uiuc.edu:/var/cvs/llvm co llvm +
        5. cd llvm +
        +
      + + +

      + +

    3. Configure the LLVM Build Environment +
        +
      1. Change directory to where you want to store the LLVM object + files and run configure to configure the Makefiles and + header files for the default platform. + Useful options include: +
          +
        • --with-llvmgccdir=directory +
          + Specify where the LLVM GCC frontend is installed. +

          + +

        • --enable-spec2000=directory +
          + Enable the SPEC2000 benchmarks for testing. The SPEC2000 + benchmarks should be available in directory. +
        +
      + +

      + +

    4. Build the LLVM Suite +
        +
      1. Set your LLVM_LIB_SEARCH_PATH environment variable. +
      2. gmake -k |& tee gnumake.out +    # this is csh or tcsh syntax +
      + +

      + +

    + +

    + Consult the Getting Started with LLVM section for + detailed information on configuring and compiling LLVM. See + Setting Up Your Environment for tips that + simplify working with the GCC front end and LLVM tools. Go to + Program Layout to learn about the layout of the + source code tree. + + +

    +

    Requirements

    +
    +
    + + + Before you begin to use the LLVM system, review the requirements given + below. This may save you some trouble by knowing ahead of time what + hardware and software you will need. + + +

    Hardware

    + + LLVM is known to work on the following platforms: +
      +
    • Linux on x86 (Pentium and above) +
        +
      • Approximately 760 MB of Free Disk Space +
          +
        • Source code: 30 MB +
        • Object code: 670 MB +
        • GCC front end: 60 MB +
        +
      + +

      + +

    • Solaris on SparcV9 (Ultrasparc) +
        +
      • Approximately 1.24 GB of Free Disk Space +
          +
        • Source code: 30 MB +
        • Object code: 1000 MB +
        • GCC front end: 210 MB +
        +
      +
    + + The LLVM suite may compile on other platforms, but it is not + guaranteed to do so. If compilation is successful, the LLVM utilities + should be able to assemble, disassemble, analyze, and optimize LLVM + bytecode. Code generation should work as well, although the generated + native code may not work on your platform. +

    + The GCC front end is not very portable at the moment. If you want to get + it to work on another platform, you can download a copy of the source + and try to compile it on your platform. +

    + + +

    Software

    + +

    + + Compiling LLVM requires that you have several software packages installed: + +

    + +

    + There are some additional tools that you may want to have when working with + LLVM: +

    + +
      +
    • GNU Autoconf +
    • GNU M4 +

      + If you want to make changes to the configure scripts, you will need + GNU autoconf (2.57 or higher), and consequently, GNU M4 (version 1.4 + or higher). +

      + +
    • QMTest +
    • Python +

      + These are needed to use the LLVM test suite. +

    + + +

    The remainder of this guide is meant to get you up and running with + LLVM and to give you some basic information about the LLVM environment. + A complete guide to installation is provided in the + next section. + +

    The later sections of this guide describe the general layout of the the LLVM source tree, a simple example using the LLVM tool chain, and links to find more information about LLVM or to get + help via e-mail. + + +

    +

    Getting Started with LLVM

    +
    +
    + + + +

    Terminology and Notation

    + + +

    Throughout this manual, the following names are used to denote paths + specific to the local system and working environment. These are not + environment variables you need to set but just strings used in the rest + of this document below. In any of the examples below, simply replace + each of these names with the appropriate pathname on your local system. + All these paths are absolute:

    +
    +
    SRC_ROOT +
    + This is the top level directory of the LLVM source tree. +

    + +

    OBJ_ROOT +
    + This is the top level directory of the LLVM object tree (i.e. the + tree where object files and compiled programs will be placed. It + can be the same as SRC_ROOT). +

    + +

    LLVMGCCDIR +
    + This is the where the LLVM GCC Front End is installed. +

    + For the pre-built GCC front end binaries, the LLVMGCCDIR is + cfrontend/platform/llvm-gcc. +

    + + +

    Setting Up Your Environment

    + + +

    + In order to compile and use LLVM, you will need to set some environment + variables. There are also some shell aliases which you may find useful. + You can set these on the command line, or better yet, set them in your + .cshrc or .profile. + +

    +
    LLVM_LIB_SEARCH_PATH=LLVMGCCDIR/llvm-gcc/bytecode-libs +
    + This environment variable helps the LLVM GCC front end find bytecode + libraries that it will need for compilation. +

    + +

    alias llvmgcc LLVMGCCDIR/llvm-gcc/bin/gcc +
    alias llvmg++ LLVMGCCDIR/llvm-gcc/bin/g++ +
    + This alias allows you to use the LLVM C and C++ front ends without putting + them in your PATH or typing in their complete pathnames. +
    + + +

    Unpacking the LLVM Archives

    + + +

    + If you have the LLVM distribution, you will need to unpack it before you + can begin to compile it. LLVM is distributed as a set of three files. Each + file is a TAR archive that is compressed with the gzip program. +

    + +

    The three files are as follows: +

    +
    llvm.tar.gz +
    This is the source code to the LLVM suite. +

    + +

    cfrontend.sparc.tar.gz +
    This is the binary release of the GCC front end for Solaris/Sparc. +

    + +

    cfrontend.x86.tar.gz +
    This is the binary release of the GCC front end for Linux/x86. +
    + + +

    Checkout LLVM from CVS

    + + +

    If you have access to our CVS repository, you can get a fresh copy of + the entire source code. All you need to do is check it out from CVS as + follows: +

      +
    • cd where-you-want-llvm-to-live +
    • cvs -d :pserver:anon at llvm-cvs.cs.uiuc.edu:/var/cvs/llvm login +
    • Hit the return key when prompted for the password. +
    • cvs -d :pserver:anon at llvm-cvs.cs.uiuc.edu:/var/cvs/llvm co llvm +
    + +

    This will create an 'llvm' directory in the current + directory and fully populate it with the LLVM source code, Makefiles, + test directories, and local copies of documentation files.

    + +

    + Note that the GCC front end is not included in the CVS repository. You + should have downloaded the binary distribution for your platform. +

    + + +

    Install the GCC Front End

    + + +

    + Before configuring and compiling the LLVM suite, you need to extract the + LLVM GCC front end from the binary distribution. It is used for building + the + bytecode libraries later used by the GCC front end for linking programs, and + its location must be specified when the LLVM suite is configured. +

    + +

    + To install the GCC front end, do the following: +

      +
    1. cd where-you-want-the-front-end-to-live +
    2. gunzip --stdout cfrontend.platform.tar.gz | tar -xvf + - +
    + + If you are on a Sparc/Solaris machine, you will need to fix the header + files: + +

    + + + cd cfrontend/sparc +
    + ./fixheaders +
    + +

    + The binary versions of the GCC front end may not suit all of your needs. + For example, the binary distribution may include an old version of a system + header file, not "fix" a header file that needs to be fixed for GCC, or it + may be linked with libraries not available on your system. +

    + +

    + In cases like these, you may want to try + building the GCC front end from source. + This is not for the faint of heart, so be forewarned. +

    + +

    Local LLVM Configuration

    + + +

    Once checked out from the CVS repository, the LLVM suite source code + must be configured via the configure script. This script sets + variables in llvm/Makefile.config and + llvm/include/Config/config.h. It also populates OBJ_ROOT + with the Makefiles needed to build LLVM. + +

    + The following environment variables are used by the configure + script to configure the build system: +

    + + + + + + + + + + + + + + + + +
    Variable + Purpose +
    CC + Tells configure which C compiler to use. By default, + configure will look for the first GCC C compiler in + PATH. Use this variable to override + configure's default behavior. +
    CXX + Tells configure which C++ compiler to use. By default, + configure will look for the first GCC C++ compiler in + PATH. Use this variable to override + configure's default behavior. +
    + +

    + The following options can be used to set or enable LLVM specific options: +

    + +
    +
    --with-llvmgccdir=LLVMGCCDIR +
    + Path to the location where the LLVM C front end binaries and + associated libraries will be installed. +

    +

    --enable-optimized +
    + Enables optimized compilation by default (debugging symbols are removed + and GCC optimization flags are enabled). The default is to use an + unoptimized build (also known as a debug build). +

    +

    --enable-jit +
    + Compile the Just In Time (JIT) functionality. This is not available + on all platforms. The default is dependent on platform, so it is best + to explicitly enable it if you want it. +

    +

    --enable-spec2000 +
    --enable-spec2000=<directory> +
    + Enable the use of SPEC2000 when testing LLVM. This is disabled by default + (unless configure finds SPEC2000 installed). By specifying + directory, you can tell configure where to find the SPEC2000 + benchmarks. If directory is left unspecified, configure + uses the default value + /home/vadve/shared/benchmarks/speccpu2000/benchspec. +
    + +

    + To configure LLVM, follow these steps: +

      +
    1. Change directory into the object root directory: +
      + cd OBJ_ROOT +

      + +

    2. Run the configure script located in the LLVM source tree: +
      + SRC_ROOT/configure +

      +

    +

    + + In addition to running configure, you must set the + LLVM_LIB_SEARCH_PATH environment variable in your startup scripts. + This environment variable is used to locate "system" libraries like + "-lc" and "-lm" when linking. This variable should be set + to the absolute path for the bytecode-libs subdirectory of the GCC front end + install, or LLVMGCCDIR/llvm-gcc/bytecode-libs. For example, one might + set LLVM_LIB_SEARCH_PATH to + /home/vadve/lattner/local/x86/llvm-gcc/bytecode-libs for the X86 + version of the GCC front end on our research machines.

    + + +

    Compiling the LLVM Suite Source Code

    + + + Once you have configured LLVM, you can build it. There are three types of + builds: + +
    +
    Debug Builds +
    + These builds are the default when one types gmake (unless the + --enable-optimized option was used during configuration). The + build system will compile the tools and libraries with debugging + information. +

    + +

    Release (Optimized) Builds +
    + These builds are enabled with the --enable-optimized option to + configure or by specifying ENABLE_OPTIMIZED=1 on the + gmake command line. For these builds, the build system will + compile the tools and libraries with GCC optimizations enabled and strip + debugging information from the libraries and executables it generates. +

    + +

    Profile Builds +
    + These builds are for use with profiling. They compile profiling + information into the code for use with programs like gprof. + Profile builds must be started by specifying ENABLE_PROFILING=1 + on the gmake command line. +
    + + Once you have LLVM configured, you can build it by entering the + OBJ_ROOT directory and issuing the following command: +

    + gmake + +

    + If you have multiple processors in your machine, you may wish to use some + of the parallel build options provided by GNU Make. For example, you could + use the command: +

    + +

    + gmake -j2 + +

    + There are several special targets which are useful when working with the LLVM + source code: + +

    +
    gmake clean +
    + Removes all files generated by the build. This includes object files, + generated C/C++ files, libraries, and executables. +

    + +

    gmake distclean +
    + Removes everything that gmake clean does, but also removes + files generated by configure. It attempts to return the + source tree to the original state in which it was shipped. +

    + +

    gmake install +
    + Installs LLVM files into the proper location. For the most part, + this does nothing, but it does install bytecode libraries into the + GCC front end's bytecode library directory. If you need to update + your bytecode libraries, this is the target to use once you've built + them. +

    + +

    + + It is also possible to override default values from configure by + declaring variables on the command line. The following are some examples: + +
    +
    gmake ENABLE_OPTIMIZED=1 +
    + Perform a Release (Optimized) build. +

    + +

    gmake ENABLE_PROFILING=1 +
    + Perform a Profiling build. +

    + +

    gmake VERBOSE=1 +
    + Print what gmake is doing on standard output. +

    +

    + + Every directory in the LLVM object tree includes a Makefile to + build it and any subdirectories that it contains. Entering any directory + inside the LLVM object tree and typing gmake should rebuild + anything in or below that directory that is out of date. + + +

    The Location of LLVM Object Files

    + + +

    + The LLVM build system is capable of sharing a single LLVM source tree among + several LLVM builds. Hence, it is possible to build LLVM for several + different platforms or configurations using the same source tree. +

    + This is accomplished in the typical autoconf manner: +

      +
    • Change directory to where the LLVM object files should live: +

      + cd OBJ_ROOT + +

    • Run the configure script found in the LLVM source directory: +

      + SRC_ROOT/configure +

    + +

    + The LLVM build will place files underneath OBJ_ROOT in directories + named after the build type: +

    + +
    +
    Debug Builds +
    +
    +
    Tools +
    OBJ_ROOT/tools/Debug +
    Libraries +
    OBJ_ROOT/lib/Debug +
    +

    + +

    Release Builds +
    +
    +
    Tools +
    OBJ_ROOT/tools/Release +
    Libraries +
    OBJ_ROOT/lib/Release +
    +

    + +

    Profile Builds +
    +
    +
    Tools +
    OBJ_ROOT/tools/Profile +
    Libraries +
    OBJ_ROOT/lib/Profile +
    +
    + + +
    +

    Program Layout

    +
    +
    + + +

    + One useful source of information about the LLVM source base is the LLVM doxygen documentation, available at http://llvm.cs.uiuc.edu/doxygen/. + The following is a brief introduction to code layout: +

    + + +

    CVS directories

    + + + Every directory checked out of CVS will contain a CVS directory; + for the most part these can just be ignored. + + + +

    llvm/include

    + + + This directory contains public header files exported from the LLVM + library. The three main subdirectories of this directory are:

    + +

      +
    1. llvm/include/llvm - This directory contains all of the LLVM + specific header files. This directory also has subdirectories for + different portions of LLVM: Analysis, CodeGen, + Target, Transforms, etc... + +
    2. llvm/include/Support - This directory contains generic + support libraries that are independent of LLVM, but are used by LLVM. + For example, some C++ STL utilities and a Command Line option processing + library store their header files here. + +
    3. llvm/include/Config - This directory contains header files + configured by the configure script. They wrap "standard" UNIX + and C header files. Source code can include these header files which + automatically take care of the conditional #includes that the + configure script generates. +
    + + +

    llvm/lib

    + + + This directory contains most of the source files of the LLVM system. In + LLVM, almost all + code exists in libraries, making it very easy to share code among the + different tools.

    + +

    +
    llvm/lib/VMCore/
    This directory holds the core LLVM + source files that implement core classes like Instruction and BasicBlock. + +
    llvm/lib/AsmParser/
    This directory holds the source code + for the LLVM assembly language parser library. + +
    llvm/lib/ByteCode/
    This directory holds code for reading + and write LLVM bytecode. + +
    llvm/lib/CWriter/
    This directory implements the LLVM to C + converter. + +
    llvm/lib/Analysis/
    This directory contains a variety of + different program analyses, such as Dominator Information, Call Graphs, + Induction Variables, Interval Identification, Natural Loop Identification, + etc... + +
    llvm/lib/Transforms/
    This directory contains the source + code for the LLVM to LLVM program transformations, such as Aggressive Dead + Code Elimination, Sparse Conditional Constant Propagation, Inlining, Loop + Invariant Code Motion, Dead Global Elimination, and many others... + +
    llvm/lib/Target/
    This directory contains files that + describe various target architectures for code generation. For example, + the llvm/lib/Target/Sparc directory holds the Sparc machine + description.
    + +
    llvm/lib/CodeGen/
    This directory contains the major parts + of the code generator: Instruction Selector, Instruction Scheduling, and + Register Allocation. + +
    llvm/lib/Support/
    This directory contains the source code + that corresponds to the header files located in + llvm/include/Support/. +
    + + +

    llvm/runtime

    + + +

    + This directory contains libraries which are compiled into LLVM bytecode and + used when linking programs with the GCC front end. Most of these libraries + are skeleton versions of real libraries; for example, libc is a stripped down + version of glibc. +

    + +

    + Unlike the rest of the LLVM suite, this directory needs the LLVM GCC front end + to compile. +

    + + +

    llvm/test

    + + +

    This directory contains regression tests and source code that is used to + test the LLVM infrastructure. +

    + + +

    llvm/tools

    + + +

    The tools directory contains the executables built out of the + libraries above, which form the main part of the user interface. You can + always get help for a tool by typing tool_name --help. The + following is a brief introduction to the most important tools.

    + +
    +
    + +
    analyze
    analyze is used to run a specific + analysis on an input LLVM bytecode file and print out the results. It is + primarily useful for debugging analyses, or familiarizing yourself with + what an analysis does.

    + +

    bugpoint
    bugpoint is used to debug + optimization passes or code generation backends by narrowing down the + given test case to the minimum number of passes and/or instructions that + still cause a problem, whether it is a crash or miscompilation. See HowToSubmitABug.html for more information + on using bugpoint.

    + +

    llvm-ar
    The archiver produces an archive containing + the given LLVM bytecode files, optionally with an index for faster + lookup.

    + +

    llvm-as
    The assembler transforms the human readable + LLVM assembly to LLVM bytecode.

    + +

    llvm-dis
    The disassembler transforms the LLVM + bytecode to human readable LLVM assembly. Additionally, it can convert + LLVM bytecode to C, which is enabled with the -c option.

    + +

    llvm-link
    llvm-link, not surprisingly, + links multiple LLVM modules into a single program.

    + +

    lli
    lli is the LLVM interpreter, which + can directly execute LLVM bytecode (although very slowly...). In addition + to a simple interpreter, lli also has a tracing mode (entered by + specifying -trace on the command line). Finally, for + architectures that support it (currently only x86 and Sparc), by default, + lli will function as a Just-In-Time compiler (if the + functionality was compiled in), and will execute the code much + faster than the interpreter.

    + +

    llc
    llc is the LLVM backend compiler, + which translates LLVM bytecode to a SPARC or x86 assembly file.

    + +

    llvmgcc
    llvmgcc is a GCC-based C frontend + that has been retargeted to emit LLVM code as the machine code output. It + works just like any other GCC compiler, taking the typical -c, -S, -E, + -o options that are typically used. The source code for the + llvmgcc tool is currently not included in the LLVM cvs tree + because it is quite large and not very interesting.

    + +

      +
      gccas
      This tool is invoked by the + llvmgcc frontend as the "assembler" part of the compiler. This + tool actually assembles LLVM assembly to LLVM bytecode, + performs a variety of optimizations, and outputs LLVM bytecode. Thus + when you invoke llvmgcc -c x.c -o x.o, you are causing + gccas to be run, which writes the x.o file (which is + an LLVM bytecode file that can be disassembled or manipulated just like + any other bytecode file). The command line interface to gccas + is designed to be as close as possible to the system + `as' utility so that the gcc frontend itself did not have to be + modified to interface to a "weird" assembler.

      + +

      gccld
      gccld links together several LLVM + bytecode files into one bytecode file and does some optimization. It is + the linker invoked by the GCC frontend when multiple .o files need to be + linked together. Like gccas, the command line interface of + gccld is designed to match the system linker, to aid + interfacing with the GCC frontend.

      +

    + +
    opt
    opt reads LLVM bytecode, applies a + series of LLVM to LLVM transformations (which are specified on the command + line), and then outputs the resultant bytecode. The 'opt --help' + command is a good way to get a list of the program transformations + available in LLVM.

    + +

    + + +

    llvm/utils

    + + + This directory contains utilities for working with LLVM source code, and some + of the utilities are actually required as part of the build process because + they are code generators for parts of LLVM infrastructure. + +
    + Burg/
    Burg is an instruction selector + generator -- it builds trees on which it then performs pattern-matching to + select instructions according to the patterns the user has specified. Burg + is currently used in the Sparc V9 backend.

    + +

    codegen-diff
    codegen-diff is a script + that finds differences between code that LLC generates and code that LLI + generates. This is a useful tool if you are debugging one of them, + assuming that the other generates correct output. For the full user + manual, run `perldoc codegen-diff'.

    + +

    cvsupdate
    cvsupdate is a script that will + update your CVS tree, but produce a much cleaner and more organized output + than simply running `cvs up -dP' will. For example, it will group + together all the new and updated files and modified files in separate + sections, so you can see at a glance what has changed. If you are at the + top of your LLVM CVS tree, running utils/cvsupdate is the + preferred way of updating the tree.

    + +

    emacs/
    The emacs directory contains + syntax-highlighting files which will work with Emacs and XEmacs editors, + providing syntax highlighting support for LLVM assembly files and TableGen + description files. For information on how to use the syntax files, consult + the README file in that directory.

    + +

    getsrcs.sh
    The getsrcs.sh script finds + and outputs all non-generated source files, which is useful if one wishes + to do a lot of development across directories and does not want to + individually find each file. One way to use it is to run, for example: + xemacs `utils/getsources.sh` from the top of your LLVM source + tree.

    + +

    makellvm
    The makellvm script compiles all + files in the current directory and then compiles and links the tool that + is the first argument. For example, assuming you are in the directory + llvm/lib/Target/Sparc, if makellvm is in your path, + simply running makellvm llc will make a build of the current + directory, switch to directory llvm/tools/llc and build it, + causing a re-linking of LLC.

    + +

    NightlyTest.pl and + NightlyTestTemplate.html
    These files are used in a + cron script to generate nightly status reports of the functionality of + tools, and the results can be seen by following the appropriate link on + the LLVM homepage.

    + +

    TableGen/
    The TableGen directory contains + the tool used to generate register descriptions, instruction set + descriptions, and even assemblers from common TableGen description + files.

    + +

    vim/
    The vim directory contains + syntax-highlighting files which will work with the VIM editor, providing + syntax highlighting support for LLVM assembly files and TableGen + description files. For information on how to use the syntax files, consult + the README file in that directory.

    + +

    + + +

    +
    An Example Using the LLVM Tool Chain
    +

    +
    + + +
      +
    1. First, create a simple C file, name it 'hello.c': +
      +    #include <stdio.h>
      +    int main() {
      +      printf("hello world\n");
      +      return 0;
      +    }
      +        
      + +
    2. Next, compile the C file into a LLVM bytecode file:

      + + % llvmgcc hello.c -o hello

      + + This will create two result files: hello and + hello.bc. The hello.bc is the LLVM bytecode that + corresponds the the compiled program and the library facilities that it + required. hello is a simple shell script that runs the bytecode + file with lli, making the result directly executable.

      + +

    3. Run the program. To make sure the program ran, execute one of the + following commands:

      + + % ./hello

      + + or

      + + % lli hello.bc

      + +

    4. Use the llvm-dis utility to take a look at the LLVM assembly + code:

      + + % llvm-dis < hello.bc | less

      + +

    5. Compile the program to native Sparc assembly using the code + generator (assuming you are currently on a Sparc system):

      + + % llc hello.bc -o hello.s

      + +

    6. Assemble the native sparc assemble file into a program:

      + + % /opt/SUNWspro/bin/cc -xarch=v9 hello.s -o hello.sparc

      + +

    7. Execute the native sparc program:

      + + % ./hello.sparc

      + +

    + + + +

    +
    Common Problems
    +

    +
    + + + If you are having problems building or using LLVM, or if you have any other + general questions about LLVM, please consult the + Frequently Asked Questions page. + + +

    Links

    +
    + + +

    This document is just an introduction to how to use LLVM to do + some simple things... there are many more interesting and complicated things + that you can do that aren't documented here (but we'll gladly accept a patch + if you want to write something up!). For more information about LLVM, check + out:

    + + + +
    + + If you have any questions or run into any snags (or you have any + additions...), please send an email to + Chris Lattner.

    + The LLVM Compiler Infrastructure +
    + + + + Last modified: Mon Aug 11 13:52:22 CDT 2003 + + + Index: llvm-www/releases/1.0/HowToSubmitABug.html diff -c /dev/null llvm-www/releases/1.0/HowToSubmitABug.html:1.1 *** /dev/null Fri Oct 24 15:51:50 2003 --- llvm-www/releases/1.0/HowToSubmitABug.html Fri Oct 24 15:51:39 2003 *************** *** 0 **** --- 1,282 ---- + + How to submit an LLVM bug report + + + + + +
      How to submit an LLVM bug report
    + + + +
    +

    +

      +
    1. Introduction - Got bugs? +
    2. Crashing Bugs + +
    3. Miscompilations +
    4. Incorrect code generation (JIT and LLC) + +

      Written by Chris Lattner and + Misha Brukman

      +

    +

    + +
    + + + + +
    + Introduction - Got bugs? +
      + + + If you're working with LLVM and run into a bug, we definitely want to know about + it. This document describes what you can do to increase the odds of getting it + fixed quickly.

      + + Basically you have to do two things at a minimum. First, decide whether the bug + crashes the compiler (or an LLVM pass), or if the + compiler is miscompiling the program. Based on + what type of bug it is, follow the instructions in the linked section to narrow + down the bug so that the person who fixes it will be able to find the problem + more easily.

      + + Once you have a reduced test-case, go to + + the LLVM Bug Tracking System, + + select the catagory in which the bug falls, and fill out the form with the + necessary details. The bug description should contain the following + information: +

        +
      • All information necessary to reproduce the problem.
      • +
      • The reduced test-case that triggers the bug.
      • +
      • The location where you obtained LLVM (if not from our CVS + repository).
      • +
      + +

      + Thanks for helping us make LLVM better!

      + + + +

    +
    + Crashing Bugs +
      + + + More often than not, bugs in the compiler cause it to crash - often due to an + assertion failure of some sort. If you are running opt or + analyze directly, and something crashes, jump to the section on + bugs in LLVM passes. Otherwise, the most important + piece of the puzzle is to figure out if it is the GCC-based front-end that is + buggy or if it's one of the LLVM tools that has problems.

      + + To figure out which program is crashing (the front-end, gccas, + or gccld), run the llvm-gcc command line as you + were when the crash occurred, but add a -v option to the command line. + The compiler will print out a bunch of stuff, and should end with telling you + that one of cc1, gccas, or gccld + crashed.

      + +

      + + + +

    +
       + + Front-end bugs +
      + + If the problem is in the front-end, you should re-run the same + llvm-gcc command that resulted in the crash, but add the + -save-temps option. The compiler will crash again, but it + will leave behind a foo.i file (containing preprocessed + C source code) and possibly foo.s (containing LLVM + assembly code), for each compiled foo.c file. Send us + the foo.i file, along with a brief description of the + error it caused.

      + + +

    +
       + + GCCAS bugs +
      + + If you find that a bug crashes in the gccas stage of + compilation, compile your test-case to a .s file with the + -save-temps option to llvm-gcc. Then run:

      + +

      +   gccas -debug-pass=Arguments < /dev/null -o - > /dev/null
      + 

      + + ... which will print a list of arguments, indicating the list of passes that + gccas runs. Once you have the input file and the list of + passes, go to the section on debugging bugs in LLVM + passes.

      + + + +

    +
       + + GCCLD bugs +
      + + If you find that a bug crashes in the gccld stage of + compilation, gather all of the .o bytecode files and libraries that are + being linked together (the "llvm-gcc -v" output should include + the full list of objects linked). Then run:

      + +

      +   llvm-as < /dev/null > null.bc
      +   gccld -debug-pass=Arguments null.bc
      + 

      + + ... which will print a list of arguments, indicating the list of passes that + gccld runs. Once you have the input files and the list of + passes, go to the section on debugging bugs in LLVM + passes.

      + + +

    +
       + + Bugs in LLVM passes +
      + + At this point, you should have some number of LLVM assembly files or bytecode + files and a list of passes which crash when run on the specified input. In + order to reduce the list of passes (which is probably large) and the input to + something tractable, use the bugpoint tool as follows:

      + +

      +   bugpoint <input files> <list of passes>
      + 

      + + bugpoint will print a bunch of output as it reduces the + test-case, but it should eventually print something like this:

      + +

      +   ...
      +   Emitted bytecode to 'bugpoint-reduced-simplified.bc'
      + 
      +   *** You can reproduce the problem with: opt bugpoint-reduced-simplified.bc -licm
      + 

      + + Once you complete this, please send the LLVM bytecode file and the command line + to reproduce the problem to the llvmbugs mailing list.

      + + + +

    +
    + Miscompilations +
      + + + A miscompilation occurs when a pass does not correctly transform a program, thus + producing errors that are only noticed during execution. This is different from + producing invalid LLVM code (i.e., code not in SSA form, using values before + defining them, etc.) which the verifier will check for after a pass finishes its + run.

      + + To debug a miscompilation, you should choose which program you wish to run the + output through, e.g. C backend, the JIT, or LLC, and a selection of passes, one + of which may be causing the error, and run, for example: + +

      +   bugpoint -run-cbe [... optimization passes ...] file-to-test.bc
      + 
      + + bugpoint will try to narrow down your list of passes to the one pass + that causes an error, and simplify the bytecode file as much as it can to assist + you. It will print a message letting you know how to reproduce the resulting + error. + + +
    +
    + Incorrect code generation +
      + + + Similarly to debugging incorrect compilation by mis-behaving passes, you can + debug incorrect code generation by either LLC or the JIT, using + bugpoint. The process bugpoint follows in this case is to try + to narrow the code down to a function that is miscompiled by one or the other + method, but since for correctness, the entire program must be run, + bugpoint will compile the code it deems to not be affected with the C + Backend, and then link in the shared object it generates.

      + + To debug the JIT: +

      +   bugpoint -run-jit -output=[correct output file] [bytecodefile]
      + 
      + + Similarly, to debug the LLC, one would run: +
      +   bugpoint -run-llc -output=[correct output file] [bytecodefile]
      + 
      + + At the end of a successful bugpoint run, you will be presented + with two bytecode files: a safe file which can be compiled with the C + backend and the test file which either LLC or the JIT + mis-codegenerates, and thus causes the error.

      + + To reproduce the error that bugpoint found, it is sufficient to do the + following: + +

        +
      1. Regenerate the shared object from the safe bytecode file:
        +
        +   llvm-dis -c safe.bc -o safe.c
        + gcc -shared safe.c -o safe.so +
      2. +
      3. If debugging LLC, compile test bytecode native and link with the shared object:
        +
        +   llc test.bc -o test.s -f
        + gcc test.s safe.so -o test.llc
        + ./test.llc [program options] +
      4. +

        + If debugging the JIT, load the shared object and supply the test bytecode:
        +

        +   lli -load=safe.so test.bc [program options]
        + 
        +
      + + +
    + + +
    +
    Chris Lattner
    + The LLVM Compiler Infrastructure +
    + + + Last modified: Tue Oct 14 15:57:47 CDT 2003 + +
    Index: llvm-www/releases/1.0/LangRef.html diff -c /dev/null llvm-www/releases/1.0/LangRef.html:1.1 *** /dev/null Fri Oct 24 15:51:51 2003 --- llvm-www/releases/1.0/LangRef.html Fri Oct 24 15:51:39 2003 *************** *** 0 **** --- 1,1957 ---- + + LLVM Assembly Language Reference Manual + + + + +
      LLVM Language Reference Manual
    + +
      +
    1. Abstract +
    2. Introduction +
    3. Identifiers +
    4. Type System +
        +
      1. Primitive Types +
          +
        1. Type Classifications +
        +
      2. Derived Types +
          +
        1. Array Type +
        2. Function Type +
        3. Pointer Type +
        4. Structure Type + +
        +
      +
    5. High Level Structure +
        +
      1. Module Structure +
      2. Global Variables +
      3. Function Structure +
      +
    6. Instruction Reference +
        +
      1. Terminator Instructions +
          +
        1. 'ret' Instruction +
        2. 'br' Instruction +
        3. 'switch' Instruction +
        4. 'invoke' Instruction +
        5. 'unwind' Instruction +
        +
      2. Binary Operations +
          +
        1. 'add' Instruction +
        2. 'sub' Instruction +
        3. 'mul' Instruction +
        4. 'div' Instruction +
        5. 'rem' Instruction +
        6. 'setcc' Instructions +
        +
      3. Bitwise Binary Operations +
          +
        1. 'and' Instruction +
        2. 'or' Instruction +
        3. 'xor' Instruction +
        4. 'shl' Instruction +
        5. 'shr' Instruction +
        +
      4. Memory Access Operations +
          +
        1. 'malloc' Instruction +
        2. 'free' Instruction +
        3. 'alloca' Instruction +
        4. 'load' Instruction +
        5. 'store' Instruction +
        6. 'getelementptr' Instruction +
        +
      5. Other Operations +
          +
        1. 'phi' Instruction +
        2. 'cast .. to' Instruction +
        3. 'call' Instruction +
        4. 'vanext' Instruction +
        5. 'vaarg' Instruction +
        +
      +
    7. Intrinsic Functions +
        +
      1. Variable Argument Handling Intrinsics +
          +
        1. 'llvm.va_start' Intrinsic +
        2. 'llvm.va_end' Intrinsic +
        3. 'llvm.va_copy' Intrinsic +
        +
      + +

      Written by Chris Lattner and Vikram Adve

      + + +

    + + + +

    +
    + Abstract +

      + + +
      + This document is a reference manual for the LLVM assembly language. LLVM is + an SSA based representation that provides type safety, low-level operations, + flexibility, and the capability of representing 'all' high-level languages + cleanly. It is the common code representation used throughout all phases of + the LLVM compilation strategy. +
      + + + + + +
    +
    + Introduction +
      + + + The LLVM code representation is designed to be used in three different forms: as + an in-memory compiler IR, as an on-disk bytecode representation (suitable for + fast loading by a Just-In-Time compiler), and as a human readable assembly + language representation. This allows LLVM to provide a powerful intermediate + representation for efficient compiler transformations and analysis, while + providing a natural means to debug and visualize the transformations. The three + different forms of LLVM are all equivalent. This document describes the human + readable representation and notation.

      + + The LLVM representation aims to be a light-weight and low-level while being + expressive, typed, and extensible at the same time. It aims to be a "universal + IR" of sorts, by being at a low enough level that high-level ideas may be + cleanly mapped to it (similar to how microprocessors are "universal IR's", + allowing many source languages to be mapped to them). By providing type + information, LLVM can be used as the target of optimizations: for example, + through pointer analysis, it can be proven that a C automatic variable is never + accessed outside of the current function... allowing it to be promoted to a + simple SSA value instead of a memory location.

      + + +


    Well Formedness

    +
    + Identifiers +
      + + + LLVM uses three different forms of identifiers, for different purposes:

      + +

        +
      1. Numeric constants are represented as you would expect: 12, -3 123.421, etc. + Floating point constants have an optional hexidecimal notation. + +
      2. Named values are represented as a string of characters with a '%' prefix. + For example, %foo, %DivisionByZero, %a.really.long.identifier. The actual + regular expression used is '%[a-zA-Z$._][a-zA-Z$._0-9]*'. Identifiers + which require other characters in their names can be surrounded with quotes. In + this way, anything except a " character can be used in a name. + +
      3. Unnamed values are represented as an unsigned numeric value with a '%' + prefix. For example, %12, %2, %44. +

      + + LLVM requires the values start with a '%' sign for two reasons: Compilers don't + need to worry about name clashes with reserved words, and the set of reserved + words may be expanded in the future without penalty. Additionally, unnamed + identifiers allow a compiler to quickly come up with a temporary variable + without having to avoid symbol table conflicts.

      + + Reserved words in LLVM are very similar to reserved words in other languages. + There are keywords for different opcodes ('add', + 'cast', 'ret', + etc...), for primitive type names ('void', + 'uint', etc...), and others. These reserved + words cannot conflict with variable names, because none of them start with a '%' + character.

      + + Here is an example of LLVM code to multiply the integer variable '%X' + by 8:

      + + The easy way: +

      +   %result = mul uint %X, 8
      + 
      + + After strength reduction: +
      +   %result = shl uint %X, ubyte 3
      + 
      + + And the hard way: +
      +   add uint %X, %X           ; yields {uint}:%0
      +   add uint %0, %0           ; yields {uint}:%1
      +   %result = add uint %1, %1
      + 
      + + This last way of multiplying %X by 8 illustrates several important lexical features of LLVM:

      + +

        +
      1. Comments are delimited with a ';' and go until the end of line. +
      2. Unnamed temporaries are created when the result of a computation is not + assigned to a named value. +
      3. Unnamed temporaries are numbered sequentially +

      + + ...and it also show a convention that we follow in this document. When + demonstrating instructions, we will follow an instruction with a comment that + defines the type and name of value produced. Comments are shown in italic + text.

      + + The one non-intuitive notation for constants is the optional hexidecimal form of + floating point constants. For example, the form 'double + 0x432ff973cafa8000' is equivalent to (but harder to read than) 'double + 4.5e+15' which is also supported by the parser. The only time hexadecimal + floating point constants are useful (and the only time that they are generated + by the disassembler) is when an FP constant has to be emitted that is not + representable as a decimal floating point number exactly. For example, NaN's, + infinities, and other special cases are represented in their IEEE hexadecimal + format so that assembly and disassembly do not cause any bits to change in the + constants.

      + + + +

    +
    + Type System +
      + + + The LLVM type system is one of the most important features of the intermediate + representation. Being typed enables a number of optimizations to be performed + on the IR directly, without having to do extra analyses on the side before the + transformation. A strong type system makes it easier to read the generated code + and enables novel analyses and transformations that are not feasible to perform + on normal three address code representations.

      + + + + + + +

    +
       + Primitive Types +
      + + The primitive types are the fundemental building blocks of the LLVM system. The + current set of primitive types are as follows:

      + +
      + + + + + + + + + +
      void No value
      ubyte Unsigned 8 bit value
      ushortUnsigned 16 bit value
      uint Unsigned 32 bit value
      ulong Unsigned 64 bit value
      float 32 bit floating point value
      label Branch destination
      + +
      + + + + + + + + +
      bool True or False value
      sbyte Signed 8 bit value
      short Signed 16 bit value
      int Signed 32 bit value
      long Signed 64 bit value
      double64 bit floating point value
      + +

      + + + + +


    Type Classifications

      + + These different primitive types fall into a few useful classifications:

      + + + + + + + + +
      signed sbyte, short, int, long, float, double
      unsignedubyte, ushort, uint, ulong
      integerubyte, sbyte, ushort, short, uint, int, ulong, long
      integralbool, ubyte, sbyte, ushort, short, uint, int, ulong, long
      floating pointfloat, double
      first classbool, ubyte, sbyte, ushort, short,
      uint, int, ulong, long, float, double, pointer

      + + + + + + +

       + Derived Types +
      + + The real power in LLVM comes from the derived types in the system. This is what + allows a programmer to represent arrays, functions, pointers, and other useful + types. Note that these derived types may be recursive: For example, it is + possible to have a two dimensional array.

      + + + + +


    Array Type

      + +
      Overview:
      + + The array type is a very simple derived type that arranges elements sequentially + in memory. The array type requires a size (number of elements) and an + underlying data type.

      + +

      Syntax:
      +
      +   [<# elements> x <elementtype>]
      + 
      + + The number of elements is a constant integer value, elementtype may be any type + with a size.

      + +

      Examples:
      +
        + [40 x int ]: Array of 40 integer values.
        + [41 x int ]: Array of 41 integer values.
        + [40 x uint]: Array of 40 unsigned integer values.

        +

      + + Here are some examples of multidimensional arrays:

      +

        + + + + +
        [3 x [4 x int]]: 3x4 array integer values.
        [12 x [10 x float]]: 12x10 array of single precision floating point values.
        [2 x [3 x [4 x uint]]]: 2x3x4 array of unsigned integer values.
        +
      + + + +


    Function Type


    Structure Type


    Pointer Type

      + +
      Overview:
      + + As in many languages, the pointer type represents a pointer or reference to + another object, which must live in memory.

      + +

      Syntax:
      +
      +   <type> *
      + 
      + +
      Examples:
      + + + + + + + +
      [4x int]*: pointer to array of four int values
      int (int *) *: A pointer to a + function that takes an int, returning an + int.
      +

      + + + + + + + +

    +
    + High Level Structure +
      + + + + +
    +
       + Module Structure +
    +
       + Global Variables +
    +
       + Functions +
    +
    + Instruction Reference +
    +
       + Terminator Instructions +
      + + As mentioned previously, every basic block in a + program ends with a "Terminator" instruction, which indicates which block should + be executed after the current block is finished. These terminator instructions + typically yield a 'void' value: they produce control flow, not values + (the one exception being the 'invoke' + instruction).

      + + There are five different terminator instructions: the 'ret' instruction, the 'br' instruction, the 'switch' instruction, the 'invoke' instruction, and the 'unwind' instruction.

      + + + +


    'ret' Instruction


    'br' Instruction


    'switch' Instruction


    'invoke' Instruction


    'unwind' Instruction

       + Binary Operations +
      + + Binary operators are used to do most of the computation in a program. They + require two operands, execute an operation on them, and produce a single value. + The result value of a binary operator is not necessarily the same type as its + operands.

      + + There are several different binary operators:

      + + + +


    'add' Instruction


    'sub' Instruction


    'mul' Instruction


    'div' Instruction


    'rem' Instruction


    'setcc' Instructions

    +
       + Bitwise Binary Operations +
      + + Bitwise binary operators are used to do various forms of bit-twiddling in a + program. They are generally very efficient instructions, and can commonly be + strength reduced from other instructions. They require two operands, execute an + operation on them, and produce a single value. The resulting value of the + bitwise binary operators is always the same type as its first operand.

      + + +


    'and' Instruction


    'or' Instruction


    'xor' Instruction


    'shl' Instruction


    'shr' Instruction

    +
       + Memory Access Operations +
      + + A key design point of an SSA-based representation is how it represents memory. + In LLVM, no memory locations are in SSA form, which makes things very simple. + This section describes how to read, write, allocate and free memory in LLVM.

      + + + +


    'malloc' Instruction


    'free' Instruction


    'alloca' Instruction


    'load' Instruction


    'store' Instruction


    'getelementptr' Instruction

    +
       + Other Operations +
      + + The instructions in this catagory are the "miscellaneous" instructions, which defy better classification.

      + + + +


    'phi' Instruction


    'cast .. to' Instruction

      + +
      Syntax:
      +
      +   <result> = cast <ty> <value> to <ty2>             ; yields ty2
      + 
      + +
      Overview:
      + + The 'cast' instruction is used as the primitive means to convert + integers to floating point, change data type sizes, and break type safety (by + casting pointers).

      + +

      Arguments:
      + + The 'cast' instruction takes a value to cast, which must be a first + class value, and a type to cast it to, which must also be a first class type.

      + +

      Semantics:
      + + This instruction follows the C rules for explicit casts when determining how the + data being cast must change to fit in its new container.

      + + When casting to bool, any value that would be considered true in the context of + a C 'if' condition is converted to the boolean 'true' values, + all else are 'false'.

      + + When extending an integral value from a type of one signness to another (for + example 'sbyte' to 'ulong'), the value is sign-extended if the + source value is signed, and zero-extended if the source value is + unsigned. bool values are always zero extended into either zero or + one.

      + +

      Example:
      +
      +   %X = cast int 257 to ubyte              ; yields ubyte:1
      +   %Y = cast int 123 to bool               ; yields bool:true
      + 
      + + + + +


    'call' Instruction


    'vanext' Instruction


    'vaarg' Instruction

    +
    + Intrinsic Functions +
      + + + LLVM supports the notion of an "intrinsic function". These functions have well + known names and semantics, and are required to follow certain restrictions. + Overall, these instructions represent an extension mechanism for the LLVM + language that does not require changing all of the transformations in LLVM to + add to the language (or the bytecode reader/writer, the parser, etc...).

      + + Intrinsic function names must all start with an "llvm." prefix, this + prefix is reserved in LLVM for intrinsic names, thus functions may not be named + this. Intrinsic functions must always be external functions: you cannot define + the body of intrinsic functions. Intrinsic functions may only be used in call + or invoke instructions: it is illegal to take the address of an intrinsic + function. Additionally, because intrinsic functions are part of the LLVM + language, it is required that they all be documented here if any are added.

      + + Unless an intrinsic function is target-specific, there must be a lowering pass + to eliminate the intrinsic or all backends must support the intrinsic + function.

      + + + +

    +
       + Variable Argument Handling Intrinsics +
      + + Variable argument support is defined in LLVM with the vanext instruction and these three intrinsic + functions. These functions are related to the similarly named macros defined in + the <stdarg.h> header file.

      + + All of these functions operate on arguments that use a target-specific value + type "va_list". The LLVM assembly language reference manual does not + define what this type is, so all transformations should be prepared to handle + intrinsics with any type used.

      + + This example shows how the vanext instruction + and the variable argument handling intrinsic functions are used.

      + +

      + int %test(int %X, ...) {
      +   ; Initialize variable argument processing
      +   %ap = call sbyte*()* %llvm.va_start()
      + 
      +   ; Read a single integer argument
      +   %tmp = vaarg sbyte* %ap, int
      + 
      +   ; Advance to the next argument
      +   %ap2 = vanext sbyte* %ap, int
      + 
      +   ; Demonstrate usage of llvm.va_copy and llvm.va_end
      +   %aq = call sbyte* (sbyte*)* %llvm.va_copy(sbyte* %ap2)
      +   call void %llvm.va_end(sbyte* %aq)
      + 
      +   ; Stop processing of arguments.
      +   call void %llvm.va_end(sbyte* %ap2)
      +   ret int %tmp
      + }
      + 
      + + +


    'llvm.va_start' Intrinsic

      + +
      Syntax:
      +
      +   call va_list ()* %llvm.va_start()
      + 
      + +
      Overview:
      + + The 'llvm.va_start' intrinsic returns a new <arglist> + for subsequent use by the variable argument intrinsics.

      + +

      Semantics:
      + + The 'llvm.va_start' intrinsic works just like the va_start + macro available in C. In a target-dependent way, it initializes and returns a + va_list element, so that the next vaarg will produce the first + variable argument passed to the function. Unlike the C va_start macro, + this intrinsic does not need to know the last argument of the function, the + compiler can figure that out.

      + + Note that this intrinsic function is only legal to be called from within the + body of a variable argument function.

      + + + +


    'llvm.va_end' Intrinsic


    'llvm.va_copy' Intrinsic

    + + + +
    + +
    Chris Lattner
    + The LLVM Compiler Infrastructure +
    + + + Last modified: Tue Oct 21 10:43:36 CDT 2003 + +
    + Index: llvm-www/releases/1.0/OpenProjects.html diff -c /dev/null llvm-www/releases/1.0/OpenProjects.html:1.1 *** /dev/null Fri Oct 24 15:51:51 2003 --- llvm-www/releases/1.0/OpenProjects.html Fri Oct 24 15:51:39 2003 *************** *** 0 **** --- 1,284 ---- + + Open LLVM Projects + + +

    Open LLVM Projects

    + + + +

    + + + +
    + What is this? +
      + + + This document is meant to be a sort of "big TODO list" for LLVM. Each project + in this document is something that would be useful for LLVM to have, and would + also be a great way to get familiar with the system. Some of these projects are + small and self-contained, which may be implemented in a couple of days, others + are larger. Several of these projects may lead to interesting research projects + in their own right. In any case, we welcome all contributions.

      + + If you are thinking about tackling one of these projects, please send a mail to + the LLVM + Developer's mailing list, so that we know the project is being worked on. + Additionally this is a good way to get more information about a specific project + or to suggest other projects to add to this page.

      + + + +

    +
    + Improving the current system +
      + + + Improvements to the current infrastructure are always very welcome and tend to + be fairly straight-forward to implement. Here are some of the key areas that + can use improvement...

      + + +

    +
       + + Port glibc to LLVM +
      + + It would be very useful to port glibc to LLVM. This would allow a + variety of interprocedural algorithms to be much more effective in the face of + library calls. The most important pieces to port are things like the string + library and the stdio related functions... low-level system calls like + 'read' should stay unimplemented in LLVM.

      + + + +

    +
       + + Improving the Nightly Tester +
      + + The Nightly Tester is a simple perl script (located + in utils/NightlyTest.pl) which runs every night to generate a daily report. It + could use the following improvements:

      + +

        +
      1. Olden timings - Time the compilation and execution times for the Olden + benchmark suite, keeping track of these values over time. + +
      2. Graphs - It would be great to have gnuplot graphs to keep track of how the + tree is changing over time. We already gather a several statistics, it + just necessary to add the script-fu to gnuplotize it. + +
      3. Regression tests - We should run the regression tests in addition to the + program tests... +

      + + + +

    +
       + + Compile programs with the LLVM Compiler +
      + + We are always looking for new testcases and benchmarks for use with LLVM. In + particular, it is useful to try compiling your favorite C source code with LLVM. + If it doesn't compile, try to figure out why or report it to the llvm-bugs list. If you + get the program to compile, it would be extremely useful to convert the build + system to be compatible with the LLVM Programs testsuite so that we can check it + into CVS and the automated tester can use it to track progress of the + compiler.

      + + When testing a code, try running it with a variety of optimizations, and with + all the back-ends: CBE, llc, and lli.

      + + + +

    +
       + + Extend the LLVM intermediate representation +
      + +
        +
      1. Add a new conditional move instruction: X = select bool Cond, Y, Z +
      2. Add support for platform independent prefetch support. The GCC prefetch project page + has a good survey of the prefetching capabilities of a variety of modern + processors. +
      + + + +
    +
       + + Miscellaneous Improvements +
      + +
        +
      1. Someone needs to look into getting the ranlib tool to index LLVM + bytecode files, so that linking in .a files is not hideously slow. They + would also then have to implement the reader for this index in + gccld.
        + +
      2. Improve the efficiency of the bytecode loader/writer
        +
      3. Extend the FunctionPassManager to use a ModuleProvider to stream functions + in on demand. This would improve the efficiency of the JIT. +
      4. Rework the PassManager to be more flexible +
      5. Some transformations and analyses only work on reducible flow graphs. It + would be nice to have a transformation which could be "required" by these passes + which makes irreducible graphs reducible. This can easily be accomplished + through code duplication. See Making Graphs Reducible + with Controlled Node Splitting and perhaps Nesting of Reducible and + Irreducible Loops. +
      + + + +
    +
    + Adding new capabilities to LLVM +
      + + + Sometimes creating new things is more fun that improving existing things. These + projects tend to be more involved and perhaps require more work, but can also be + very rewarding.

      + + +

    +
       + + Pointer and Alias Analysis +
      + + We have a strong base for development of both + pointer analysis based optimizations as well as pointer analyses themselves. It + seems natural to want to take advantage of this...

      + +

        +
      1. Implement a flow-sensitive context-sensitive alias analysis algorithm
        + - Pick one of the somewhat efficient algorithms, but strive for maximum + precision +
      2. Implement a flow-sensitive context-insensitive alias analysis algorithm
        + - Just an efficient local algorithm perhaps? + +
      3. Implement an interface to update analyses in response to common code motion + transformations +
      4. Implement alias analysis based optimizations: +
          +
        • Dead store elimination +
        +
      + + +
    +
       + + Profile Guided Optimization +
      + + We are getting to the point where we really need a unified infrastructure for + profile guided optimizations. It would be wonderful to be able to write profile + guided transformations which can be performed either at static compile time + (compile time or offline optimization time) or at runtime in a JIT type setup. + The LLVM transformation itself shouldn't need to know how it is being used.

      + + Ideas for profile guided transformations:

      + +

        +
      1. Superblock formation (with many optimizations) +
      2. Loop unrolling/peeling +
      3. Profile directed inlining +
      4. Code layout +
      5. ... +

      + + + +

    +
       + + New Transformations and Analyses +
      + +
        +
      1. Implement a Dependence Analysis Infrastructure
        + - Design some way to represent and query dep analysis +
      2. Implement a faster Dominator Set Construction Algorithm
        + - A linear time or nearly so algorithm +
      3. Implement a strength reduction pass +
      4. Value range propagation pass +
      5. Implement an unswitching pass +
      6. Write a loop unroller, with a simple heuristic for when to unroll +
      + + +
    +
       + + X86 Back-end Improvements +
      + +
        +
      1. Implement a global register allocator +
      2. Implement a better instruction selector +
      3. Implement support for the "switch" instruction without requiring the + lower-switches pass. +
      + + +
    +
       + + Miscellaneous Additions +
      + +
        +
      1. Write a new frontend for some language (Java? OCaml? Forth?) +
      2. Write a new backend for a target (IA64? MIPS? MMIX?) +
      + + + +
    + + +
    +
    Chris Lattner
    + The LLVM Compiler Infrastructure +
    + + + Last modified: Wed Oct 1 16:48:54 CDT 2003 + +
    Index: llvm-www/releases/1.0/ProgrammersManual.html diff -c /dev/null llvm-www/releases/1.0/ProgrammersManual.html:1.1 *** /dev/null Fri Oct 24 15:51:51 2003 --- llvm-www/releases/1.0/ProgrammersManual.html Fri Oct 24 15:51:39 2003 *************** *** 0 **** --- 1,1796 ---- + + LLVM Programmer's Manual + + + + + +
      LLVM Programmer's Manual
    + +
      +
    1. Introduction +
    2. General Information + +
    3. Important and useful LLVM APIs + +
    4. Helpful Hints for Common Operations + +
    5. The Core LLVM Class Hierarchy Reference + + +

      Written by Chris Lattner, + Dinakar Dhurjati, and + Joel Stanley

      +

    + + + + +
    + Introduction +
      + + + This document is meant to highlight some of the important classes and interfaces + available in the LLVM source-base. This manual is not intended to explain what + LLVM is, how it works, and what LLVM code looks like. It assumes that you know + the basics of LLVM and are interested in writing transformations or otherwise + analyzing or manipulating the code.

      + + This document should get you oriented so that you can find your way in the + continuously growing source code that makes up the LLVM infrastructure. Note + that this manual is not intended to serve as a replacement for reading the + source code, so if you think there should be a method in one of these classes to + do something, but it's not listed, check the source. Links to the doxygen sources are provided to make this as easy as + possible.

      + + The first section of this document describes general information that is useful + to know when working in the LLVM infrastructure, and the second describes the + Core LLVM classes. In the future this manual will be extended with information + describing how to use extension libraries, such as dominator information, CFG + traversal routines, and useful utilities like the InstVisitor template.

      + + + +

    +
    + General Information +
      + + + This section contains general information that is useful if you are working in + the LLVM source-base, but that isn't specific to any particular API.

      + + + +

    +
       + + The C++ Standard Template Library +
      + + LLVM makes heavy use of the C++ Standard Template Library (STL), perhaps much + more than you are used to, or have seen before. Because of this, you might want + to do a little background reading in the techniques used and capabilities of the + library. There are many good pages that discuss the STL, and several books on + the subject that you can get, so it will not be discussed in this document.

      + + Here are some useful links:

      +

        +
      1. Dinkumware C++ + Library reference - an excellent reference for the STL and other parts of + the standard C++ library. + +
      2. C++ In a Nutshell - This is an + O'Reilly book in the making. It has a decent Standard Library + Reference that rivals Dinkumware's, and is actually free until the book is + published. + +
      3. C++ Frequently Asked + Questions + +
      4. SGI's STL Programmer's Guide - + Contains a useful Introduction to the + STL. + +
      5. Bjarne Stroustrup's C++ + Page + +

      + + You are also encouraged to take a look at the LLVM Coding Standards guide which focuses on how + to write maintainable code more than where to put your curly braces.

      + + + +

    +
    + Important and useful LLVM APIs +
      + + + Here we highlight some LLVM APIs that are generally useful and good to know + about when writing transformations.

      + + +

    +
       + + The isa<>, cast<> and dyn_cast<> templates +
      + + The LLVM source-base makes extensive use of a custom form of RTTI. These + templates have many similarities to the C++ dynamic_cast<> + operator, but they don't have some drawbacks (primarily stemming from the fact + that dynamic_cast<> only works on classes that have a v-table). + Because they are used so often, you must know what they do and how they work. + All of these templates are defined in the Support/Casting.h file (note + that you very rarely have to include this file directly).

      + +

      + +
      isa<>: + +
      The isa<> operator works exactly like the Java + "instanceof" operator. It returns true or false depending on whether a + reference or pointer points to an instance of the specified class. This can be + very useful for constraint checking of various sorts (example below).

      + + +

      cast<>: + +
      The cast<> operator is a "checked cast" operation. It + converts a pointer or reference from a base class to a derived cast, causing an + assertion failure if it is not really an instance of the right type. This + should be used in cases where you have some information that makes you believe + that something is of the right type. An example of the isa<> and + cast<> template is:

      + +

      + static bool isLoopInvariant(const Value *V, const Loop *L) {
      +   if (isa<Constant>(V) || isa<Argument>(V) || isa<GlobalValue>(V))
      +     return true;
      + 
      +   // Otherwise, it must be an instruction...
      +   return !L->contains(cast<Instruction>(V)->getParent());
      + 

      + + Note that you should not use an isa<> test followed by a + cast<>, for that use the dyn_cast<> operator.

      + + +

      dyn_cast<>: + +
      The dyn_cast<> operator is a "checking cast" operation. It + checks to see if the operand is of the specified type, and if so, returns a + pointer to it (this operator does not work with references). If the operand is + not of the correct type, a null pointer is returned. Thus, this works very much + like the dynamic_cast operator in C++, and should be used in the same + circumstances. Typically, the dyn_cast<> operator is used in an + if statement or some other flow control statement like this:

      + +

      +   if (AllocationInst *AI = dyn_cast<AllocationInst>(Val)) {
      +     ...
      +   }
      + 

      + + This form of the if statement effectively combines together a call to + isa<> and a call to cast<> into one statement, + which is very convenient.

      + + Another common example is:

      + +

      +   // Loop over all of the phi nodes in a basic block
      +   BasicBlock::iterator BBI = BB->begin();
      +   for (; PHINode *PN = dyn_cast<PHINode>(BBI); ++BBI)
      +     cerr << *PN;
      + 

      + + Note that the dyn_cast<> operator, like C++'s + dynamic_cast or Java's instanceof operator, can be abused. In + particular you should not use big chained if/then/else blocks to check + for lots of different variants of classes. If you find yourself wanting to do + this, it is much cleaner and more efficient to use the InstVisitor class to + dispatch over the instruction type directly.

      + + +

      cast_or_null<>: + +
      The cast_or_null<> operator works just like the + cast<> operator, except that it allows for a null pointer as an + argument (which it then propagates). This can sometimes be useful, allowing you + to combine several null checks into one.

      + + +

      dyn_cast_or_null<>: + +
      The dyn_cast_or_null<> operator works just like the + dyn_cast<> operator, except that it allows for a null pointer as + an argument (which it then propagates). This can sometimes be useful, allowing + you to combine several null checks into one.

      + +

      + + These five templates can be used with any classes, whether they have a v-table + or not. To add support for these templates, you simply need to add + classof static methods to the class you are interested casting to. + Describing this is currently outside the scope of this document, but there are + lots of examples in the LLVM source base.

      + + + +

    +
       + + The DEBUG() macro & -debug option +
      + + Often when working on your pass you will put a bunch of debugging printouts and + other code into your pass. After you get it working, you want to remove + it... but you may need it again in the future (to work out new bugs that you run + across).

      + + Naturally, because of this, you don't want to delete the debug printouts, but + you don't want them to always be noisy. A standard compromise is to comment + them out, allowing you to enable them if you need them in the future.

      + + The "Support/Debug.h" file + provides a macro named DEBUG() that is a much nicer solution to this + problem. Basically, you can put arbitrary code into the argument of the + DEBUG macro, and it is only executed if 'opt' (or any other + tool) is run with the '-debug' command line argument: + +

      +      ... 
      +      DEBUG(std::cerr << "I am here!\n");
      +      ...
      + 

      + + Then you can run your pass like this:

      + +

      +   $ opt < a.bc > /dev/null -mypass
      +     <no output>
      +   $ opt < a.bc > /dev/null -mypass -debug
      +     I am here!
      +   $
      + 

      + + Using the DEBUG() macro instead of a home-brewed solution allows you to + now have to create "yet another" command line option for the debug output for + your pass. Note that DEBUG() macros are disabled for optimized builds, + so they do not cause a performance impact at all (for the same reason, they + should also not contain side-effects!).

      + + One additional nice thing about the DEBUG() macro is that you can + enable or disable it directly in gdb. Just use "set DebugFlag=0" or + "set DebugFlag=1" from the gdb if the program is running. If the + program hasn't been started yet, you can always just run it with + -debug.

      + + +


    Fine grained debug info with + DEBUG_TYPE() and the -debug-only option

      + + Sometimes you may find yourself in a situation where enabling -debug + just turns on too much information (such as when working on the code + generator). If you want to enable debug information with more fine-grained + control, you define the DEBUG_TYPE macro and the -debug only + option as follows:

      + +

      +      ...
      +      DEBUG(std::cerr << "No debug type\n");
      +      #undef  DEBUG_TYPE
      +      #define DEBUG_TYPE "foo"
      +      DEBUG(std::cerr << "'foo' debug type\n");
      +      #undef  DEBUG_TYPE
      +      #define DEBUG_TYPE "bar"
      +      DEBUG(std::cerr << "'bar' debug type\n");
      +      #undef  DEBUG_TYPE
      +      #define DEBUG_TYPE ""
      +      DEBUG(std::cerr << "No debug type (2)\n");
      +      ...
      + 

      + + Then you can run your pass like this:

      + +

      +   $ opt < a.bc > /dev/null -mypass
      +     <no output>
      +   $ opt < a.bc > /dev/null -mypass -debug
      +     No debug type
      +     'foo' debug type
      +     'bar' debug type
      +     No debug type (2)
      +   $ opt < a.bc > /dev/null -mypass -debug-only=foo
      +     'foo' debug type
      +   $ opt < a.bc > /dev/null -mypass -debug-only=bar
      +     'bar' debug type
      +   $
      + 

      + + Of course, in practice, you should only set DEBUG_TYPE at the top of a + file, to specify the debug type for the entire module (if you do this before you + #include "Support/Debug.h", you don't have to insert the ugly + #undef's). Also, you should use names more meaningful that "foo" and + "bar", because there is no system in place to ensure that names do not conflict: + if two different modules use the same string, they will all be turned on when + the name is specified. This allows all, say, instruction scheduling, debug + information to be enabled with -debug-type=InstrSched, even if the + source lives in multiple files.

      + + + +

    +
       + + The Statistic template & -stats + option +
      + + The "Support/Statistic.h" + file provides a template named Statistic that is used as a unified way + to keeping track of what the LLVM compiler is doing and how effective various + optimizations are. It is useful to see what optimizations are contributing to + making a particular program run faster.

      + + Often you may run your pass on some big program, and you're interested to see + how many times it makes a certain transformation. Although you can do this with + hand inspection, or some ad-hoc method, this is a real pain and not very useful + for big programs. Using the Statistic template makes it very easy to + keep track of this information, and the calculated information is presented in a + uniform manner with the rest of the passes being executed.

      + + There are many examples of Statistic users, but this basics of using it + are as follows:

      + +

        +
      1. Define your statistic like this:

        + +

        + static Statistic<> NumXForms("mypassname", "The # of times I did stuff");
        + 

        + + The Statistic template can emulate just about any data-type, but if you + do not specify a template argument, it defaults to acting like an unsigned int + counter (this is usually what you want).

        + +

      2. Whenever you make a transformation, bump the counter:

        + +

        +    ++NumXForms;   // I did stuff
        + 

        + +

      + + That's all you have to do. To get 'opt' to print out the statistics + gathered, use the '-stats' option:

      + +

      +    $ opt -stats -mypassname < program.bc > /dev/null
      +     ... statistic output ...
      + 

      + + When running gccas on a C file from the SPEC benchmark suite, it gives + a report that looks like this:

      + +

      +    7646 bytecodewriter  - Number of normal instructions
      +     725 bytecodewriter  - Number of oversized instructions
      +  129996 bytecodewriter  - Number of bytecode bytes written
      +    2817 raise           - Number of insts DCEd or constprop'd
      +    3213 raise           - Number of cast-of-self removed
      +    5046 raise           - Number of expression trees converted
      +      75 raise           - Number of other getelementptr's formed
      +     138 raise           - Number of load/store peepholes
      +      42 deadtypeelim    - Number of unused typenames removed from symtab
      +     392 funcresolve     - Number of varargs functions resolved
      +      27 globaldce       - Number of global variables removed
      +       2 adce            - Number of basic blocks removed
      +     134 cee             - Number of branches revectored
      +      49 cee             - Number of setcc instruction eliminated
      +     532 gcse            - Number of loads removed
      +    2919 gcse            - Number of instructions removed
      +      86 indvars         - Number of canonical indvars added
      +      87 indvars         - Number of aux indvars removed
      +      25 instcombine     - Number of dead inst eliminate
      +     434 instcombine     - Number of insts combined
      +     248 licm            - Number of load insts hoisted
      +    1298 licm            - Number of insts hoisted to a loop pre-header
      +       3 licm            - Number of insts hoisted to multiple loop preds (bad, no loop pre-header)
      +      75 mem2reg         - Number of alloca's promoted
      +    1444 cfgsimplify     - Number of blocks simplified
      + 

      + + Obviously, with so many optimizations, having a unified framework for this stuff + is very nice. Making your pass fit well into the framework makes it more + maintainable and useful.

      + + + +

    +
    + Helpful Hints for Common Operations +
      + + This section describes how to perform some very simple transformations of LLVM + code. This is meant to give examples of common idioms used, showing the + practical side of LLVM transformations.

      + + Because this is a "how-to" section, you should also read about the main classes + that you will be working with. The Core LLVM Class + Hierarchy Reference contains details and descriptions of the main classes + that you should know about.

      + + + + + +

    +
       + + Basic Inspection and Traversal Routines +
      + + The LLVM compiler infrastructure have many different data structures that may be + traversed. Following the example of the C++ standard template library, the + techniques used to traverse these various data structures are all basically the + same. For a enumerable sequence of values, the XXXbegin() function (or + method) returns an iterator to the start of the sequence, the XXXend() + function returns an iterator pointing to one past the last valid element of the + sequence, and there is some XXXiterator data type that is common + between the two operations.

      + + Because the pattern for iteration is common across many different aspects of the + program representation, the standard template library algorithms may be used on + them, and it is easier to remember how to iterate. First we show a few common + examples of the data structures that need to be traversed. Other data + structures are traversed in very similar ways.

      + + + +


    Iterating over the
    BasicBlocks in a Function

      + + It's quite common to have a Function instance that you'd like + to transform in some way; in particular, you'd like to manipulate its + BasicBlocks. To facilitate this, you'll need to iterate over + all of the BasicBlocks that constitute the Function. + The following is an example that prints the name of a + BasicBlock and the number of Instructions it + contains: + +
      +   // func is a pointer to a Function instance
      +   for (Function::iterator i = func->begin(), e = func->end(); i != e; ++i) {
      + 
      +       // print out the name of the basic block if it has one, and then the
      +       // number of instructions that it contains
      + 
      +       cerr << "Basic block (name=" << i->getName() << ") has " 
      +            << i->size() << " instructions.\n";
      +   }
      + 
      + + Note that i can be used as if it were a pointer for the purposes of + invoking member functions of the Instruction class. This is + because the indirection operator is overloaded for the iterator + classes. In the above code, the expression i->size() is + exactly equivalent to (*i).size() just like you'd expect. + + +


    Iterating over the
    Instructions in a BasicBlock

      + + Just like when dealing with BasicBlocks in + Functions, it's easy to iterate over the individual + instructions that make up BasicBlocks. Here's a code snippet + that prints out each instruction in a BasicBlock: + +
      +   // blk is a pointer to a BasicBlock instance
      +   for (BasicBlock::iterator i = blk->begin(), e = blk->end(); i != e; ++i)
      +      // the next statement works since operator<<(ostream&,...) 
      +      // is overloaded for Instruction&
      +      cerr << *i << "\n";
      + 
      + + However, this isn't really the best way to print out the contents of a + BasicBlock! Since the ostream operators are overloaded for + virtually anything you'll care about, you could have just invoked the + print routine on the basic block itself: cerr << *blk << + "\n";.

      + + Note that currently operator<< is implemented for Value*, so it + will print out the contents of the pointer, instead of + the pointer value you might expect. This is a deprecated interface that will + be removed in the future, so it's best not to depend on it. To print out the + pointer value for now, you must cast to void*.

      + + + +


    Iterating over the
    Instructions in a Function

      + + If you're finding that you commonly iterate over a Function's + BasicBlocks and then that BasicBlock's + Instructions, InstIterator should be used instead. + You'll need to include llvm/Support/InstIterator.h, and then + instantiate InstIterators explicitly in your code. Here's a + small example that shows how to dump all instructions in a function to + stderr (Note: Dereferencing an InstIterator yields an + Instruction*, not an Instruction&!): + +
      + #include "llvm/Support/InstIterator.h"
      + ...
      + // Suppose F is a ptr to a function
      + for (inst_iterator i = inst_begin(F), e = inst_end(F); i != e; ++i)
      +   cerr << **i << "\n";
      + 
      + + Easy, isn't it? You can also use InstIterators to fill a + worklist with its initial contents. For example, if you wanted to + initialize a worklist to contain all instructions in a + Function F, all you would need to do is something like: + +
      + std::set<Instruction*> worklist;
      + worklist.insert(inst_begin(F), inst_end(F));
      + 
      + + The STL set worklist would now contain all instructions in + the Function pointed to by F. + + +


    Turning an iterator into a class + pointer (and vice-versa)


    Finding call sites: a slightly + more complex example


    Iterating over def-use & + use-def chains

      + + Frequently, we might have an instance of the Value Class and we want to + determine which Users use the Value. The list of + all Users of a particular Value is called a + def-use chain. For example, let's say we have a + Function* named F to a particular function + foo. Finding all of the instructions that use + foo is as simple as iterating over the def-use chain of + F: + +
      + Function* F = ...;
      + 
      + for (Value::use_iterator i = F->use_begin(), e = F->use_end(); i != e; ++i) {
      +     if (Instruction *Inst = dyn_cast<Instruction>(*i)) {
      +         cerr << "F is used in instruction:\n";
      +         cerr << *Inst << "\n";
      +     }
      + }
      + 
      + + Alternately, it's common to have an instance of the User Class and need to know what + Values are used by it. The list of all Values used + by a User is known as a use-def chain. Instances of + class Instruction are common Users, so we might want + to iterate over all of the values that a particular instruction uses + (that is, the operands of the particular Instruction): + +
      + Instruction* pi = ...;
      + 
      + for (User::op_iterator i = pi->op_begin(), e = pi->op_end(); i != e; ++i) {
      +     Value* v = *i;
      +     ...
      + }
      + 
      + + + + + +
    +
       + + Making simple changes +
      + + There are some primitive transformation operations present in the LLVM + infrastructure that are worth knowing about. When performing + transformations, it's fairly common to manipulate the contents of + basic blocks. This section describes some of the common methods for + doing so and gives example code. + + +


    Creating and inserting + new Instructions

      + + Instantiating Instructions + +

      Creation of Instructions is straightforward: simply call the + constructor for the kind of instruction to instantiate and provide the + necessary parameters. For example, an AllocaInst only + requires a (const-ptr-to) Type. Thus: + +

      AllocaInst* ai = new AllocaInst(Type::IntTy);
      + + will create an AllocaInst instance that represents the + allocation of one integer in the current stack frame, at runtime. + Each Instruction subclass is likely to have varying default + parameters which change the semantics of the instruction, so refer to + the
      doxygen documentation for + the subclass of Instruction that you're interested in + instantiating.

      + +

      Naming values

      + +

      + It is very useful to name the values of instructions when you're able + to, as this facilitates the debugging of your transformations. If you + end up looking at generated LLVM machine code, you definitely want to + have logical names associated with the results of instructions! By + supplying a value for the Name (default) parameter of the + Instruction constructor, you associate a logical name with + the result of the instruction's execution at runtime. For example, + say that I'm writing a transformation that dynamically allocates space + for an integer on the stack, and that integer is going to be used as + some kind of index by some other code. To accomplish this, I place an + AllocaInst at the first point in the first + BasicBlock of some Function, and I'm intending to + use it within the same Function. I might do: + +

      AllocaInst* pa = new AllocaInst(Type::IntTy, 0, "indexLoc");
      + + where indexLoc is now the logical name of the instruction's + execution value, which is a pointer to an integer on the runtime + stack. +

      + +

      Inserting instructions

      + +

      + There are essentially two ways to insert an Instruction into + an existing sequence of instructions that form a BasicBlock: +

        +
      • Insertion into an explicit instruction list + +

        Given a BasicBlock* pb, an Instruction* pi within + that BasicBlock, and a newly-created instruction + we wish to insert before *pi, we do the following: + +

        +   BasicBlock *pb = ...;
        +   Instruction *pi = ...;
        +   Instruction *newInst = new Instruction(...);
        +   pb->getInstList().insert(pi, newInst); // inserts newInst before pi in pb
        + 
        +

        + +
      • Insertion into an implicit instruction list +

        Instruction instances that are already in + BasicBlocks are implicitly associated with an existing + instruction list: the instruction list of the enclosing basic block. + Thus, we could have accomplished the same thing as the above code + without being given a BasicBlock by doing: +

        +   Instruction *pi = ...;
        +   Instruction *newInst = new Instruction(...);
        +   pi->getParent()->getInstList().insert(pi, newInst);
        + 
        + In fact, this sequence of steps occurs so frequently that the + Instruction class and Instruction-derived classes + provide constructors which take (as a default parameter) a pointer to + an Instruction which the newly-created Instruction + should precede. That is, Instruction constructors are + capable of inserting the newly-created instance into the + BasicBlock of a provided instruction, immediately before that + instruction. Using an Instruction constructor with a + insertBefore (default) parameter, the above code becomes: +
        + Instruction* pi = ...;
        + Instruction* newInst = new Instruction(..., pi);
        + 
        + which is much cleaner, especially if you're creating a lot of + instructions and adding them to BasicBlocks. +

        +

        +
      + + +


    Deleting + Instructions


    Replacing an + Instruction with another Value

      + +

      Replacing individual instructions

      +

      + Including "llvm/Transforms/Utils/BasicBlockUtils.h" permits use of two very useful replace functions: + ReplaceInstWithValue and ReplaceInstWithInst. + +

        + +
      • ReplaceInstWithValue + +

        This function replaces all uses (within a basic block) of a given + instruction with a value, and then removes the original instruction. + The following example illustrates the replacement of the result of a + particular AllocaInst that allocates memory for a single + integer with an null pointer to an integer.

        + +
        + AllocaInst* instToReplace = ...;
        + BasicBlock::iterator ii(instToReplace);
        + ReplaceInstWithValue(instToReplace->getParent()->getInstList(), ii,
        +                      Constant::getNullValue(PointerType::get(Type::IntTy)));
        + 
        + +
      • ReplaceInstWithInst + +

        This function replaces a particular instruction with another + instruction. The following example illustrates the replacement of one + AllocaInst with another.

        + +

        + AllocaInst* instToReplace = ...;
        + BasicBlock::iterator ii(instToReplace);
        + ReplaceInstWithInst(instToReplace->getParent()->getInstList(), ii,
        +                     new AllocaInst(Type::IntTy, 0, "ptrToReplacedInt"));
        + 
        + +
      +

      Replacing multiple uses of Users and + Values

      + + You can use Value::replaceAllUsesWith and + User::replaceUsesOfWith to change more than one use at a + time. See the doxygen documentation for the Value Class and User Class, respectively, for more + information. + + + + +
    +
    + The Core LLVM Class Hierarchy Reference +
      + + + The Core LLVM classes are the primary means of representing the program being + inspected or transformed. The core LLVM classes are defined in header files in + the include/llvm/ directory, and implemented in the lib/VMCore + directory.

      + + + +

    +
       + + The Value class +


    Important Public Members of + the Value class

    +
       + + The User class +
      + + #include "llvm/User.h"
      + doxygen info: User Class
      + Superclass: Value

      + + + The User class is the common base class of all LLVM nodes that may + refer to Values. It exposes a list of "Operands" + that are all of the Values that the User is + referring to. The User class itself is a subclass of + Value.

      + + The operands of a User point directly to the LLVM Value that it refers to. Because LLVM uses Static + Single Assignment (SSA) form, there can only be one definition referred to, + allowing this direct connection. This connection provides the use-def + information in LLVM.

      + + +


    Important Public Members of + the User class

    +
       + + The Instruction class +
      + + #include "llvm/Instruction.h"
      + doxygen info: Instruction Class
      + Superclasses: User, Value

      + + The Instruction class is the common base class for all LLVM + instructions. It provides only a few methods, but is a very commonly used + class. The primary data tracked by the Instruction class itself is the + opcode (instruction type) and the parent BasicBlock the Instruction is embedded + into. To represent a specific type of instruction, one of many subclasses of + Instruction are used.

      + + Because the Instruction class subclasses the User class, its operands can be accessed in the same + way as for other Users (with the + getOperand()/getNumOperands() and + op_begin()/op_end() methods).

      + + An important file for the Instruction class is the + llvm/Instruction.def file. This file contains some meta-data about the + various different types of instructions in LLVM. It describes the enum values + that are used as opcodes (for example Instruction::Add and + Instruction::SetLE), as well as the concrete sub-classes of + Instruction that implement the instruction (for example BinaryOperator and SetCondInst). Unfortunately, the use of macros in + this file confused doxygen, so these enum values don't show up correctly in the + doxygen output.

      + + + +


    Important Public Members of + the Instruction class

      + +
    • BasicBlock *getParent()

      + + Returns the BasicBlock that this + Instruction is embedded into.

      + +

    • bool mayWriteToMemory()

      + + Returns true if the instruction writes to memory, i.e. it is a call, + free, invoke, or store.

      + +

    • unsigned getOpcode()

      + + Returns the opcode for the Instruction.

      + +

    • Instruction *clone() const

      + + Returns another instance of the specified instruction, identical in all ways to + the original except that the instruction has no parent (ie it's not embedded + into a BasicBlock), and it has no name.

      + + + + + + + +

    +
       + + The BasicBlock class +
      + + #include "llvm/BasicBlock.h"
      + doxygen info: BasicBlock Class
      + Superclass: Value

      + + + This class represents a single entry multiple exit section of the code, commonly + known as a basic block by the compiler community. The BasicBlock class + maintains a list of Instructions, which form + the body of the block. Matching the language definition, the last element of + this list of instructions is always a terminator instruction (a subclass of the + TerminatorInst class).

      + + In addition to tracking the list of instructions that make up the block, the + BasicBlock class also keeps track of the Function that it is embedded into.

      + + Note that BasicBlocks themselves are Values, because they are referenced by instructions + like branches and can go in the switch tables. BasicBlocks have type + label.

      + + + +


    Important Public Members of + the BasicBlock class

      + +
    • BasicBlock(const std::string &Name = "", Function *Parent = 0)

      + + The BasicBlock constructor is used to create new basic blocks for + insertion into a function. The constructor simply takes a name for the new + block, and optionally a Function to insert it + into. If the Parent parameter is specified, the new + BasicBlock is automatically inserted at the end of the specified Function, if not specified, the BasicBlock must be + manually inserted into the Function.

      + +

    • BasicBlock::iterator - Typedef for instruction list iterator
      + BasicBlock::const_iterator - Typedef for const_iterator.
      + begin(), end(), front(), back(), + size(), empty(), rbegin(), rend()

      + + These methods and typedefs are forwarding functions that have the same semantics + as the standard library methods of the same names. These methods expose the + underlying instruction list of a basic block in a way that is easy to + manipulate. To get the full complement of container operations (including + operations to update the list), you must use the getInstList() + method.

      + +

    • BasicBlock::InstListType &getInstList()

      + + This method is used to get access to the underlying container that actually + holds the Instructions. This method must be used when there isn't a forwarding + function in the BasicBlock class for the operation that you would like + to perform. Because there are no forwarding functions for "updating" + operations, you need to use this if you want to update the contents of a + BasicBlock.

      + +

    • Function *getParent()

      + + Returns a pointer to Function the block is + embedded into, or a null pointer if it is homeless.

      + +

    • TerminatorInst *getTerminator()

      + + Returns a pointer to the terminator instruction that appears at the end of the + BasicBlock. If there is no terminator instruction, or if the last + instruction in the block is not a terminator, then a null pointer is + returned.

      + + + +

    +
       + + The GlobalValue class +
      + + #include "llvm/GlobalValue.h"
      + doxygen info: GlobalValue Class
      + Superclasses: User, Value

      + + Global values (GlobalVariables or Functions) are the only LLVM values that are + visible in the bodies of all Functions. + Because they are visible at global scope, they are also subject to linking with + other globals defined in different translation units. To control the linking + process, GlobalValues know their linkage rules. Specifically, + GlobalValues know whether they have internal or external linkage.

      + + If a GlobalValue has internal linkage (equivalent to being + static in C), it is not visible to code outside the current translation + unit, and does not participate in linking. If it has external linkage, it is + visible to external code, and does participate in linking. In addition to + linkage information, GlobalValues keep track of which Module they are currently part of.

      + + Because GlobalValues are memory objects, they are always referred to by + their address. As such, the Type of a global is + always a pointer to its contents. This is explained in the LLVM Language + Reference Manual.

      + + + +


    Important Public Members of + the GlobalValue class

    +
       + + The Function class +
      + + #include "llvm/Function.h"
      + doxygen info: Function Class
      + Superclasses: GlobalValue, User, Value

      + + The Function class represents a single procedure in LLVM. It is + actually one of the more complex classes in the LLVM heirarchy because it must + keep track of a large amount of data. The Function class keeps track + of a list of BasicBlocks, a list of formal Arguments, and a SymbolTable.

      + + The list of BasicBlocks is the most commonly + used part of Function objects. The list imposes an implicit ordering + of the blocks in the function, which indicate how the code will be layed out by + the backend. Additionally, the first BasicBlock is the implicit entry node for the + Function. It is not legal in LLVM explicitly branch to this initial + block. There are no implicit exit nodes, and in fact there may be multiple exit + nodes from a single Function. If the BasicBlock list is empty, this indicates that + the Function is actually a function declaration: the actual body of the + function hasn't been linked in yet.

      + + In addition to a list of BasicBlocks, the + Function class also keeps track of the list of formal Arguments that the function receives. This + container manages the lifetime of the Argument + nodes, just like the BasicBlock list does for + the BasicBlocks.

      + + The SymbolTable is a very rarely used LLVM + feature that is only used when you have to look up a value by name. Aside from + that, the SymbolTable is used internally to + make sure that there are not conflicts between the names of Instructions, BasicBlocks, or Arguments in the function body.

      + + + +


    Important Public Members of + the Function class

      + +
    • Function(const FunctionType *Ty, bool isInternal, const std::string &N = "")

      + + Constructor used when you need to create new Functions to add the the + program. The constructor must specify the type of the function to create and + whether or not it should start out with internal or external linkage.

      + +

    • bool isExternal()

      + + Return whether or not the Function has a body defined. If the function + is "external", it does not have a body, and thus must be resolved by linking + with a function defined in a different translation unit.

      + + +

    • Function::iterator - Typedef for basic block list iterator
      + Function::const_iterator - Typedef for const_iterator.
      + begin(), end(), front(), back(), + size(), empty(), rbegin(), rend()

      + + These are forwarding methods that make it easy to access the contents of a + Function object's BasicBlock + list.

      + +

    • Function::BasicBlockListType &getBasicBlockList()

      + + Returns the list of BasicBlocks. This is + necessary to use when you need to update the list or perform a complex action + that doesn't have a forwarding method.

      + + +

    • Function::aiterator - Typedef for the argument list iterator
      + Function::const_aiterator - Typedef for const_iterator.
      + abegin(), aend(), afront(), aback(), + asize(), aempty(), arbegin(), arend()

      + + These are forwarding methods that make it easy to access the contents of a + Function object's Argument list.

      + +

    • Function::ArgumentListType &getArgumentList()

      + + Returns the list of Arguments. This is + necessary to use when you need to update the list or perform a complex action + that doesn't have a forwarding method.

      + + + +

    • BasicBlock &getEntryBlock()

      + + Returns the entry BasicBlock for the + function. Because the entry block for the function is always the first block, + this returns the first block of the Function.

      + +

    • Type *getReturnType()
      + FunctionType *getFunctionType()

      + + This traverses the Type of the Function + and returns the return type of the function, or the FunctionType of the actual function.

      + +

    • SymbolTable *getSymbolTable()

      + + Return a pointer to the SymbolTable for this + Function.

      + + + + +

    +
       + + The GlobalVariable class +
      + + #include "llvm/GlobalVariable.h"
      + doxygen info: GlobalVariable Class
      + Superclasses: GlobalValue, User, Value

      + + Global variables are represented with the (suprise suprise) + GlobalVariable class. Like functions, GlobalVariables are + also subclasses of GlobalValue, and as such + are always referenced by their address (global values must live in memory, so + their "name" refers to their address). Global variables may have an initial + value (which must be a Constant), and if they + have an initializer, they may be marked as "constant" themselves (indicating + that their contents never change at runtime).

      + + + +


    Important Public Members of the + GlobalVariable class

      + +
    • GlobalVariable(const Type *Ty, bool isConstant, bool + isInternal, Constant *Initializer = 0, const std::string + &Name = "")

      + + Create a new global variable of the specified type. If isConstant is + true then the global variable will be marked as unchanging for the program, and + if isInternal is true the resultant global variable will have internal + linkage. Optionally an initializer and name may be specified for the global variable as well.

      + + +

    • bool isConstant() const

      + + Returns true if this is a global variable is known not to be modified at + runtime.

      + + +

    • bool hasInitializer()

      + + Returns true if this GlobalVariable has an intializer.

      + + +

    • Constant *getInitializer()

      + + Returns the intial value for a GlobalVariable. It is not legal to call + this method if there is no initializer.

      + + + +

    +
       + + The Module class +
      + + #include "llvm/Module.h"
      + doxygen info: Module Class

      + + The Module class represents the top level structure present in LLVM + programs. An LLVM module is effectively either a translation unit of the + original program or a combination of several translation units merged by the + linker. The Module class keeps track of a list of Functions, a list of GlobalVariables, and a SymbolTable. Additionally, it contains a few + helpful member functions that try to make common operations easy.

      + + + +


    Important Public Members of the + Module class

    +
       + + The Constant class and subclasses +
      + + Constant represents a base class for different types of constants. It is + subclassed by ConstantBool, ConstantInt, ConstantSInt, ConstantUInt, + ConstantArray etc for representing the various types of Constants.

      + + + +


    Important Public Methods

    +
       + + The Type class and Derived Types +


    Important Public Methods

    +
       + + The Argument class +
    + + +
    +
    By: Dinakar Dhurjati and + Chris Lattner
    + The LLVM Compiler Infrastructure +
    + + + Last modified: Sat Sep 20 09:25:11 CDT 2003 + +
    Index: llvm-www/releases/1.0/Projects.html diff -c /dev/null llvm-www/releases/1.0/Projects.html:1.1 *** /dev/null Fri Oct 24 15:51:51 2003 --- llvm-www/releases/1.0/Projects.html Fri Oct 24 15:51:39 2003 *************** *** 0 **** --- 1,390 ---- + + + + Creating an LLVM Project + + + + +

    Creating an LLVM Project

    + + +

    Overview

    + + + The LLVM build system is designed to facilitate the building of third party + projects that use LLVM header files, libraries, and tools. In order to use + these facilities, a Makefile from a project must do the following things: + +
      +
    1. Set environment variables. +

      + There are several environment variables that a Makefile needs to set to + use the LLVM build system: +

      +
      LLVM_SRC_ROOT +
      + The root of the LLVM source tree. +

      + +

      LLVM_OBJ_ROOT +
      + The root of the LLVM object tree. +

      + +

      BUILD_SRC_ROOT +
      + The root of the project's source tree. +

      + +

      BUILD_OBJ_ROOT +
      + The root of the project's object tree. +

      + +

      BUILD_SRC_DIR +
      + The directory containing the current source to be compiled. +

      + +

      BUILD_OBJ_DIR +
      + The directory where the current source will place the new object + files. This should always be the current directory. +

      + +

      LEVEL +
      + The relative path from the current directory to the root of the + object tree. +

      +

      + +
    2. Include the LLVM Makefile.config from $(LLVM_OBJ_ROOT). +

      + +

    3. Include the LLVM Makefile.rules from $(LLVM_SRC_ROOT). +
    + + There are two ways that you can set all of these variables: +
      +
    1. + You can write your own Makefiles which hard-code these values. + +
    2. + You can use the pre-made LLVM sample project. This sample project + includes Makefiles, a configure script that can be used to configure + the location of LLVM, and the ability to support multiple object + directories from a single source directory. +
    + + This document assumes that you will base your project off of the LLVM + sample project found in llvm/projects/sample. If you want to + devise your own build system, studying the sample project and LLVM + Makefiles will probably provide enough information on how to write your own + Makefiles. +

    + + +

    Create a Project from the Sample Project

    + + + Follow these simple steps to start your project: + +
      +
    1. + Copy the llvm/projects/sample directory to any place + of your choosing. You can place it anywhere you like. Rename the + directory to match the name of your project. +

      + +

    2. + Add your source code and Makefiles to your source tree. +

      + +

    3. + If you want your Makefiles to be configured by the + configure script, or if you want to support multiple + object directories, add your Makefiles to the configure + script by adding them into the autoconf/configure.ac file. + The macro AC_CONFIG_MAKEFILE will copy a file, unmodified, + from the source directory to the object directory. + +

      + After updating autoconf/configure.ac, regenerate the + configure script with these commands: +

      + + cd autoconf
      + autoconf -o ../configure +
      + +

      + + You must be using Autoconf version 2.57 or higher. +

      + +

    4. + Run configure in the directory in which you want to place + object code. Use the following options to tell your project where it + can find LLVM: + +
      +
      --with-llvmsrc=<directory> +
      + Tell your project where the LLVM source tree is located. +

      +

      --with-llvmobj=<directory> +
      + Tell your project where the LLVM object tree is located. +
      +
    + + That's it! Now all you have to do is type gmake in the root of + your object directory, and your project should build. + + +

    Source Tree Layout

    + + + In order to use the LLVM build system, you will want to organize your + source code so that it can benefit from the build system's features. + Mainly, you want your source tree layout to look similar to the LLVM + source tree layout. The best way to do this is to just copy the + project tree from llvm/projects/sample and modify it to meet + your needs, but you can certainly add to it if you want. + + Underneath your top level directory, you should have the following + directories: + +
    +
    lib +
    + This subdirectory should contain all of your library source + code. For each library that you build, you will have one + directory in lib that will contain that library's source + code. + +

    + Libraries can be object files, archives, or dynamic libraries. + The lib directory is just a convenient place for libraries + as it places them all in a directory from which they can be linked + later. + +

    include +
    + This subdirectory should contain any header files that are + global to your project. By global, we mean that they are used + by more than one library or executable of your project. +

    + By placing your header files in include, they will be + found automatically by the LLVM build system. For example, if + you have a file include/jazz/note.h, then your source + files can include it simply with #include "jazz/note.h". + +

    tools +
    + This subdirectory should contain all of your source + code for executables. For each program that you build, you + will have one directory in tools that will contain that + program's source code. +

    + +

    test +
    + This subdirectory should contain tests that verify that your code + works correctly. Automated tests