From gaeke at cs.uiuc.edu Mon May 3 17:06:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon May 3 17:06:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Instrumentation/ProfilingUtils.h ProfilingUtils.cpp Message-ID: <200405032206.RAA05047@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Instrumentation: ProfilingUtils.h updated: 1.1 -> 1.2 ProfilingUtils.cpp updated: 1.2 -> 1.3 --- Log message: In InsertProfilingInitCall(), make it legal to pass in a null array, in which case you'll get a null array and zero passed to the profiling function. --- Diffs of the changes: (+13 -7) Index: llvm/lib/Transforms/Instrumentation/ProfilingUtils.h diff -u llvm/lib/Transforms/Instrumentation/ProfilingUtils.h:1.1 llvm/lib/Transforms/Instrumentation/ProfilingUtils.h:1.2 --- llvm/lib/Transforms/Instrumentation/ProfilingUtils.h:1.1 Mon Mar 8 11:06:13 2004 +++ llvm/lib/Transforms/Instrumentation/ProfilingUtils.h Mon May 3 17:06:33 2004 @@ -24,7 +24,7 @@ class BasicBlock; void InsertProfilingInitCall(Function *MainFn, const char *FnName, - GlobalValue *Arr); + GlobalValue *Arr = 0); void IncrementCounterInBlock(BasicBlock *BB, unsigned CounterNum, ConstantPointerRef *CounterArray); } Index: llvm/lib/Transforms/Instrumentation/ProfilingUtils.cpp diff -u llvm/lib/Transforms/Instrumentation/ProfilingUtils.cpp:1.2 llvm/lib/Transforms/Instrumentation/ProfilingUtils.cpp:1.3 --- llvm/lib/Transforms/Instrumentation/ProfilingUtils.cpp:1.2 Sun Apr 4 20:29:02 2004 +++ llvm/lib/Transforms/Instrumentation/ProfilingUtils.cpp Mon May 3 17:06:33 2004 @@ -23,7 +23,7 @@ void llvm::InsertProfilingInitCall(Function *MainFn, const char *FnName, GlobalValue *Array) { const Type *ArgVTy = PointerType::get(PointerType::get(Type::SByteTy)); - const Type *UIntPtr = PointerType::get(Type::UIntTy); + const PointerType *UIntPtr = PointerType::get(Type::UIntTy); Module &M = *MainFn->getParent(); Function *InitFn = M.getOrInsertFunction(FnName, Type::IntTy, Type::IntTy, ArgVTy, UIntPtr, Type::UIntTy, 0); @@ -39,12 +39,18 @@ BasicBlock::iterator InsertPos = Entry->begin(); while (isa(InsertPos)) ++InsertPos; - ConstantPointerRef *ArrayCPR = ConstantPointerRef::get(Array); std::vector GEPIndices(2, Constant::getNullValue(Type::IntTy)); - Args[2] = ConstantExpr::getGetElementPtr(ArrayCPR, GEPIndices); - - unsigned NumElements = - cast(Array->getType()->getElementType())->getNumElements(); + unsigned NumElements = 0; + if (Array) { + ConstantPointerRef *ArrayCPR = ConstantPointerRef::get(Array); + Args[2] = ConstantExpr::getGetElementPtr(ArrayCPR, GEPIndices); + NumElements = + cast(Array->getType()->getElementType())->getNumElements(); + } else { + // If this profiling instrumentation doesn't have a constant array, just + // pass null. + Args[2] = ConstantPointerNull::get(UIntPtr); + } Args[3] = ConstantUInt::get(Type::UIntTy, NumElements); Instruction *InitCall = new CallInst(InitFn, Args, "newargc", InsertPos); From gaeke at cs.uiuc.edu Mon May 3 17:06:04 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon May 3 17:06:04 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Instrumentation/TraceBasicBlocks.cpp Message-ID: <200405032206.RAA05038@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Instrumentation: TraceBasicBlocks.cpp added (r1.1) --- Log message: Add initial implementation of basic-block tracing instrumentation pass. --- Diffs of the changes: (+76 -0) Index: llvm/lib/Transforms/Instrumentation/TraceBasicBlocks.cpp diff -c /dev/null llvm/lib/Transforms/Instrumentation/TraceBasicBlocks.cpp:1.1 *** /dev/null Mon May 3 17:06:42 2004 --- llvm/lib/Transforms/Instrumentation/TraceBasicBlocks.cpp Mon May 3 17:06:32 2004 *************** *** 0 **** --- 1,76 ---- + //===- TraceBasicBlocks.cpp - Insert basic-block trace instrumentation ----===// + // + // 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 instruments the specified program with calls into a runtime + // library that cause it to output a trace of basic blocks as a side effect + // of normal execution. + // + //===----------------------------------------------------------------------===// + + #include "llvm/Constants.h" + #include "llvm/DerivedTypes.h" + #include "llvm/Module.h" + #include "llvm/Pass.h" + #include "llvm/Transforms/Utils/BasicBlockUtils.h" + #include "llvm/iOther.h" + #include "llvm/iMemory.h" + #include "llvm/iPHINode.h" + #include "ProfilingUtils.h" + #include "Support/Debug.h" + #include + using namespace llvm; + + namespace { + class TraceBasicBlocks : public Pass { + bool run(Module &M); + }; + + RegisterOpt X("trace-basic-blocks", + "Insert instrumentation for basic block tracing"); + } + + static void InsertInstrumentationCall (BasicBlock *BB, + const std::string FnName, + unsigned BBNumber) { + DEBUG (std::cerr << "InsertInstrumentationCall (\"" << BB->getName () + << "\", \"" << FnName << "\", " << BBNumber << ")\n"); + Module &M = *BB->getParent ()->getParent (); + Function *InstrFn = M.getOrInsertFunction (FnName, Type::VoidTy, + Type::UIntTy, 0); + std::vector Args (1); + Args[0] = ConstantUInt::get (Type::UIntTy, BBNumber); + + // Insert the call after any alloca or PHI instructions... + BasicBlock::iterator InsertPos = BB->begin(); + while (isa(InsertPos) || isa(InsertPos)) + ++InsertPos; + + Instruction *InstrCall = new CallInst (InstrFn, Args, "", InsertPos); + } + + bool TraceBasicBlocks::run(Module &M) { + Function *Main = M.getMainFunction(); + if (Main == 0) { + std::cerr << "WARNING: cannot insert basic-block trace instrumentation" + << " into a module with no main function!\n"; + return false; // No main, no instrumentation! + } + + unsigned BBNumber = 0; + for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) + for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { + InsertInstrumentationCall (BB, "llvm_basic_block_trace", BBNumber); + ++BBNumber; + } + + // Add the initialization call to main. + InsertProfilingInitCall(Main, "llvm_start_basic_block_tracing"); + return true; + } + From gaeke at cs.uiuc.edu Mon May 3 18:49:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon May 3 18:49:01 2004 Subject: [llvm-commits] CVS: llvm/runtime/libprofile/exported_symbols.lst Message-ID: <200405032349.SAA07449@zion.cs.uiuc.edu> Changes in directory llvm/runtime/libprofile: exported_symbols.lst updated: 1.1 -> 1.2 --- Log message: Add basic block tracing functions as exported symbols. --- Diffs of the changes: (+2 -0) Index: llvm/runtime/libprofile/exported_symbols.lst diff -u llvm/runtime/libprofile/exported_symbols.lst:1.1 llvm/runtime/libprofile/exported_symbols.lst:1.2 --- llvm/runtime/libprofile/exported_symbols.lst:1.1 Tue Oct 28 12:56:51 2003 +++ llvm/runtime/libprofile/exported_symbols.lst Mon May 3 18:49:17 2004 @@ -1,3 +1,5 @@ llvm_start_func_profiling llvm_start_block_profiling +llvm_start_basic_block_tracing +llvm_trace_basic_block From gaeke at cs.uiuc.edu Mon May 3 18:49:04 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon May 3 18:49:04 2004 Subject: [llvm-commits] CVS: llvm/runtime/libprofile/Profiling.h Message-ID: <200405032349.SAA07442@zion.cs.uiuc.edu> Changes in directory llvm/runtime/libprofile: Profiling.h updated: 1.2 -> 1.3 --- Log message: Add basic block tracing information as a type of "profiling" information. --- Diffs of the changes: (+2 -1) Index: llvm/runtime/libprofile/Profiling.h diff -u llvm/runtime/libprofile/Profiling.h:1.2 llvm/runtime/libprofile/Profiling.h:1.3 --- llvm/runtime/libprofile/Profiling.h:1.2 Tue Feb 10 11:36:25 2004 +++ llvm/runtime/libprofile/Profiling.h Mon May 3 18:49:16 2004 @@ -25,7 +25,8 @@ Function = 2, /* Function profiling information */ Block = 3, /* Block profiling information */ Edge = 4, /* Edge profiling information */ - Path = 5 /* Path profiling information */ + Path = 5, /* Path profiling information */ + BBTrace = 6 /* Basic block trace information */ }; void write_profiling_data(enum ProfilingType PT, unsigned *Start, From gaeke at cs.uiuc.edu Mon May 3 18:52:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon May 3 18:52:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Instrumentation/TraceBasicBlocks.cpp Message-ID: <200405032352.SAA07520@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Instrumentation: TraceBasicBlocks.cpp updated: 1.1 -> 1.2 --- Log message: Fix typo --- Diffs of the changes: (+1 -1) Index: llvm/lib/Transforms/Instrumentation/TraceBasicBlocks.cpp diff -u llvm/lib/Transforms/Instrumentation/TraceBasicBlocks.cpp:1.1 llvm/lib/Transforms/Instrumentation/TraceBasicBlocks.cpp:1.2 --- llvm/lib/Transforms/Instrumentation/TraceBasicBlocks.cpp:1.1 Mon May 3 17:06:32 2004 +++ llvm/lib/Transforms/Instrumentation/TraceBasicBlocks.cpp Mon May 3 18:52:07 2004 @@ -65,7 +65,7 @@ unsigned BBNumber = 0; for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { - InsertInstrumentationCall (BB, "llvm_basic_block_trace", BBNumber); + InsertInstrumentationCall (BB, "llvm_trace_basic_block", BBNumber); ++BBNumber; } From gaeke at cs.uiuc.edu Mon May 3 18:52:03 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon May 3 18:52:03 2004 Subject: [llvm-commits] CVS: llvm/runtime/libprofile/BasicBlockTracing.c Message-ID: <200405032352.SAA07503@zion.cs.uiuc.edu> Changes in directory llvm/runtime/libprofile: BasicBlockTracing.c added (r1.1) --- Log message: Add initial implementation of basic block tracing runtime --- Diffs of the changes: (+67 -0) Index: llvm/runtime/libprofile/BasicBlockTracing.c diff -c /dev/null llvm/runtime/libprofile/BasicBlockTracing.c:1.1 *** /dev/null Mon May 3 18:52:00 2004 --- llvm/runtime/libprofile/BasicBlockTracing.c Mon May 3 18:51:50 2004 *************** *** 0 **** --- 1,67 ---- + /*===-- BasicBlockTracing.c - Support library for basic block tracing -----===*\ + |* + |* 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 call back routines for the basic block tracing + |* instrumentation pass. This should be used with the -trace-basic-blocks + |* LLVM pass. + |* + \*===----------------------------------------------------------------------===*/ + + #include "Profiling.h" + #include + #include + + static unsigned *ArrayStart, *ArrayEnd, *ArrayCursor; + + /* WriteAndFlushBBTraceData - write out the currently accumulated trace data + * and reset the cursor to point to the beginning of the buffer. + */ + static void WriteAndFlushBBTraceData () { + write_profiling_data(BBTrace, ArrayStart, (ArrayCursor - ArrayStart)); + ArrayCursor = ArrayStart; + } + + /* BBTraceAtExitHandler - When the program exits, just write out any remaining + * data and free the trace buffer. + */ + static void BBTraceAtExitHandler() { + WriteAndFlushBBTraceData (); + free (ArrayStart); + } + + /* llvm_trace_basic_block - called upon hitting a new basic block. */ + void llvm_trace_basic_block (unsigned BBNum) { + *ArrayCursor++ = BBNum; + if (ArrayCursor == ArrayEnd) + WriteAndFlushBBTraceData (); + } + + /* llvm_start_basic_block_tracing - This is the main entry point of the basic + * block tracing library. It is responsible for setting up the atexit + * handler and allocating the trace buffer. + */ + int llvm_start_basic_block_tracing(int argc, const char **argv, + unsigned *arrayStart, unsigned numElements) { + int Ret; + const unsigned BufferSize = 128 * 1024; + unsigned ArraySize; + + Ret = save_arguments(argc, argv); + + /* Allocate a buffer to contain BB tracing data */ + ArraySize = BufferSize / sizeof (unsigned); + ArrayStart = malloc (ArraySize * sizeof (unsigned)); + ArrayEnd = ArrayStart + ArraySize; + ArrayCursor = ArrayStart; + + /* Set up the atexit handler. */ + atexit (BBTraceAtExitHandler); + + return Ret; + } From lattner at cs.uiuc.edu Tue May 4 10:19:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue May 4 10:19:02 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200405041519.KAA15727@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.197 -> 1.198 --- Log message: Minor efficiency tweak, suggested by Patrick Meredith --- Diffs of the changes: (+4 -4) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.197 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.198 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.197 Sat May 1 18:27:23 2004 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Tue May 4 10:19:33 2004 @@ -12,10 +12,10 @@ // simplification happens. // // This pass combines things like: -// %Y = add int 1, %X -// %Z = add int 1, %Y +// %Y = add int %X, 1 +// %Z = add int %Y, 1 // into: -// %Z = add int 2, %X +// %Z = add int %X, 2 // // This is a simple worklist driven algorithm. // @@ -887,7 +887,7 @@ // if so, convert to a bitwise and. if (ConstantUInt *C = dyn_cast(RHS)) if (uint64_t Val = C->getValue()) // Don't break X % 0 (divide by zero) - if (Log2(Val)) + if (!(Val & Val-1)) // Power of 2 return BinaryOperator::create(Instruction::And, I.getOperand(0), ConstantUInt::get(I.getType(), Val-1)); } From lattner at cs.uiuc.edu Tue May 4 10:47:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue May 4 10:47:02 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200405041547.KAA16345@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.242 -> 1.243 --- Log message: Improve code generated for integer multiplications by 2,3,5,9 --- Diffs of the changes: (+16 -2) Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.242 llvm/lib/Target/X86/InstSelectSimple.cpp:1.243 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.242 Sat May 1 16:29:16 2004 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Tue May 4 10:47:14 2004 @@ -2196,15 +2196,29 @@ unsigned op0Reg, unsigned ConstRHS) { static const unsigned MOVrrTab[] = {X86::MOV8rr, X86::MOV16rr, X86::MOV32rr}; static const unsigned MOVriTab[] = {X86::MOV8ri, X86::MOV16ri, X86::MOV32ri}; + static const unsigned ADDrrTab[] = {X86::ADD8rr, X86::ADD16rr, X86::ADD32rr}; unsigned Class = getClass(DestTy); - if (ConstRHS == 0) { + // Handle special cases here. + switch (ConstRHS) { + case 0: BuildMI(*MBB, IP, MOVriTab[Class], 1, DestReg).addImm(0); return; - } else if (ConstRHS == 1) { + case 1: BuildMI(*MBB, IP, MOVrrTab[Class], 1, DestReg).addReg(op0Reg); return; + case 2: + BuildMI(*MBB, IP, ADDrrTab[Class], 1,DestReg).addReg(op0Reg).addReg(op0Reg); + return; + case 3: + case 5: + case 9: + if (Class == cInt) { + addFullAddress(BuildMI(*MBB, IP, X86::LEA32r, 5, DestReg), + op0Reg, ConstRHS-1, op0Reg, 0); + return; + } } // If the element size is exactly a power of 2, use a shift to get it. From gaeke at cs.uiuc.edu Tue May 4 11:52:02 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue May 4 11:52:02 2004 Subject: [llvm-commits] CVS: llvm/runtime/libprofile/Profiling.h Message-ID: <200405041651.LAA20041@zion.cs.uiuc.edu> Changes in directory llvm/runtime/libprofile: Profiling.h updated: 1.3 -> 1.4 --- Log message: Share the profile info type enum with the C++ analysis libraries. Add a documentation comment for write_profiling_data(). --- Diffs of the changes: (+5 -9) Index: llvm/runtime/libprofile/Profiling.h diff -u llvm/runtime/libprofile/Profiling.h:1.3 llvm/runtime/libprofile/Profiling.h:1.4 --- llvm/runtime/libprofile/Profiling.h:1.3 Mon May 3 18:49:16 2004 +++ llvm/runtime/libprofile/Profiling.h Tue May 4 11:51:48 2004 @@ -15,20 +15,16 @@ #ifndef PROFILING_H #define PROFILING_H +#include "llvm/Analysis/ProfileInfoTypes.h" /* for enum ProfilingType */ + /* save_arguments - Save argc and argv as passed into the program for the file * we output. */ int save_arguments(int argc, const char **argv); -enum ProfilingType { - Arguments = 1, /* The command line argument block */ - Function = 2, /* Function profiling information */ - Block = 3, /* Block profiling information */ - Edge = 4, /* Edge profiling information */ - Path = 5, /* Path profiling information */ - BBTrace = 6 /* Basic block trace information */ -}; - +/* write_profiling_data - Write out a typed packet of profiling data to the + * current output file. + */ void write_profiling_data(enum ProfilingType PT, unsigned *Start, unsigned NumElements); From gaeke at cs.uiuc.edu Tue May 4 11:52:04 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue May 4 11:52:04 2004 Subject: [llvm-commits] CVS: llvm/runtime/libprofile/CommonProfiling.c BasicBlockTracing.c FunctionProfiling.c Message-ID: <200405041651.LAA20034@zion.cs.uiuc.edu> Changes in directory llvm/runtime/libprofile: CommonProfiling.c updated: 1.6 -> 1.7 BasicBlockTracing.c updated: 1.1 -> 1.2 FunctionProfiling.c updated: 1.2 -> 1.3 --- Log message: Constants for profile info type changed names to match the C++ ones. --- Diffs of the changes: (+3 -3) Index: llvm/runtime/libprofile/CommonProfiling.c diff -u llvm/runtime/libprofile/CommonProfiling.c:1.6 llvm/runtime/libprofile/CommonProfiling.c:1.7 --- llvm/runtime/libprofile/CommonProfiling.c:1.6 Tue Feb 10 13:14:44 2004 +++ llvm/runtime/libprofile/CommonProfiling.c Tue May 4 11:51:47 2004 @@ -99,7 +99,7 @@ /* Output the command line arguments to the file. */ { - int PTy = Arguments; + int PTy = ArgumentInfo; int Zeros = 0; write(OutFile, &PTy, sizeof(int)); write(OutFile, &SavedArgsLength, sizeof(unsigned)); Index: llvm/runtime/libprofile/BasicBlockTracing.c diff -u llvm/runtime/libprofile/BasicBlockTracing.c:1.1 llvm/runtime/libprofile/BasicBlockTracing.c:1.2 --- llvm/runtime/libprofile/BasicBlockTracing.c:1.1 Mon May 3 18:51:50 2004 +++ llvm/runtime/libprofile/BasicBlockTracing.c Tue May 4 11:51:47 2004 @@ -23,7 +23,7 @@ * and reset the cursor to point to the beginning of the buffer. */ static void WriteAndFlushBBTraceData () { - write_profiling_data(BBTrace, ArrayStart, (ArrayCursor - ArrayStart)); + write_profiling_data(BBTraceInfo, ArrayStart, (ArrayCursor - ArrayStart)); ArrayCursor = ArrayStart; } Index: llvm/runtime/libprofile/FunctionProfiling.c diff -u llvm/runtime/libprofile/FunctionProfiling.c:1.2 llvm/runtime/libprofile/FunctionProfiling.c:1.3 --- llvm/runtime/libprofile/FunctionProfiling.c:1.2 Tue Feb 10 11:36:25 2004 +++ llvm/runtime/libprofile/FunctionProfiling.c Tue May 4 11:51:47 2004 @@ -25,7 +25,7 @@ static void FuncProfAtExitHandler() { /* Just write out the data we collected. */ - write_profiling_data(Function, ArrayStart, NumElements); + write_profiling_data(FunctionInfo, ArrayStart, NumElements); } From gaeke at cs.uiuc.edu Tue May 4 11:52:06 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue May 4 11:52:06 2004 Subject: [llvm-commits] CVS: llvm/runtime/libprofile/EdgeProfiling.c BlockProfiling.c Message-ID: <200405041651.LAA20023@zion.cs.uiuc.edu> Changes in directory llvm/runtime/libprofile: EdgeProfiling.c updated: 1.1 -> 1.2 BlockProfiling.c updated: 1.2 -> 1.3 --- Log message: Constants for profile info type changed names to match the C++ ones. Edited comments. --- Diffs of the changes: (+12 -11) Index: llvm/runtime/libprofile/EdgeProfiling.c diff -u llvm/runtime/libprofile/EdgeProfiling.c:1.1 llvm/runtime/libprofile/EdgeProfiling.c:1.2 --- llvm/runtime/libprofile/EdgeProfiling.c:1.1 Mon Mar 8 12:04:31 2004 +++ llvm/runtime/libprofile/EdgeProfiling.c Tue May 4 11:51:45 2004 @@ -23,12 +23,12 @@ * data. */ static void EdgeProfAtExitHandler() { - /* Note that if this were doing something more intellegent with the - instrumentation, that we could do some computation here to expand what we - collected into simple edge profiles. Since we directly count each edge, we - just write out all of the counters directly. - */ - write_profiling_data(Edge, ArrayStart, NumElements); + /* Note that if this were doing something more intelligent with the + * instrumentation, we could do some computation here to expand what we + * collected into simple edge profiles. Since we directly count each edge, we + * just write out all of the counters directly. + */ + write_profiling_data(EdgeInfo, ArrayStart, NumElements); } Index: llvm/runtime/libprofile/BlockProfiling.c diff -u llvm/runtime/libprofile/BlockProfiling.c:1.2 llvm/runtime/libprofile/BlockProfiling.c:1.3 --- llvm/runtime/libprofile/BlockProfiling.c:1.2 Tue Feb 10 11:36:25 2004 +++ llvm/runtime/libprofile/BlockProfiling.c Tue May 4 11:51:46 2004 @@ -23,11 +23,12 @@ * data. */ static void BlockProfAtExitHandler() { - /* Note that if this were doing something more intellegent with the - instrumentation, that we could do some computation here to expand what we - collected into simple block profiles. Since we directly count each block, - */ - write_profiling_data(Block, ArrayStart, NumElements); + /* Note that if this were doing something more intelligent with the + * instrumentation, we could do some computation here to expand what we + * collected into simple block profiles. (Or we could do it in llvm-prof.) + * Regardless, we directly count each block, so no expansion is necessary. + */ + write_profiling_data(BlockInfo, ArrayStart, NumElements); } From gaeke at cs.uiuc.edu Tue May 4 11:53:03 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue May 4 11:53:03 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/ProfileInfoLoader.cpp Message-ID: <200405041653.LAA20100@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: ProfileInfoLoader.cpp updated: 1.4 -> 1.5 --- Log message: Share ProfilingType enum with the C profiling runtime libraries. --- Diffs of the changes: (+1 -7) Index: llvm/lib/Analysis/ProfileInfoLoader.cpp diff -u llvm/lib/Analysis/ProfileInfoLoader.cpp:1.4 llvm/lib/Analysis/ProfileInfoLoader.cpp:1.5 --- llvm/lib/Analysis/ProfileInfoLoader.cpp:1.4 Mon Mar 8 14:03:52 2004 +++ llvm/lib/Analysis/ProfileInfoLoader.cpp Tue May 4 11:53:07 2004 @@ -13,18 +13,12 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/ProfileInfoLoader.h" +#include "llvm/Analysis/ProfileInfoTypes.h" #include "llvm/Module.h" #include "llvm/InstrTypes.h" #include #include using namespace llvm; - -enum ProfilingType { - ArgumentInfo = 1, // The command line argument block - FunctionInfo = 2, // Function profiling information - BlockInfo = 3, // Block profiling information - EdgeInfo = 4, // Edge profiling information -}; // ByteSwap - Byteswap 'Var' if 'Really' is true. // From gaeke at cs.uiuc.edu Tue May 4 11:58:04 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue May 4 11:58:04 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/ProfileInfoTypes.h Message-ID: <200405041658.LAA20917@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: ProfileInfoTypes.h added (r1.1) --- Log message: New header file containing profile info enums shared between the C++ analysis libraries and the C runtime support library --- Diffs of the changes: (+28 -0) Index: llvm/include/llvm/Analysis/ProfileInfoTypes.h diff -c /dev/null llvm/include/llvm/Analysis/ProfileInfoTypes.h:1.1 *** /dev/null Tue May 4 11:58:07 2004 --- llvm/include/llvm/Analysis/ProfileInfoTypes.h Tue May 4 11:57:57 2004 *************** *** 0 **** --- 1,28 ---- + /*===-- ProfileInfoTypes.h - Profiling info shared constants ------*- 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 defines constants shared by the various different profiling + |* runtime libraries and the LLVM C++ profile info loader. It must be a + |* C header because, at present, the profiling runtimes are written in C. + |* + \*===----------------------------------------------------------------------===*/ + + #ifndef LLVM_ANALYSIS_PROFILEINFOTYPES_H + #define LLVM_ANALYSIS_PROFILEINFOTYPES_H + + enum ProfilingType { + ArgumentInfo = 1, /* The command line argument block */ + FunctionInfo = 2, /* Function profiling information */ + BlockInfo = 3, /* Block profiling information */ + EdgeInfo = 4, /* Edge profiling information */ + PathInfo = 5, /* Path profiling information */ + BBTraceInfo = 6 /* Basic block trace information */ + }; + + #endif /* LLVM_ANALYSIS_PROFILEINFOTYPES_H */ From lattner at cs.uiuc.edu Tue May 4 12:00:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue May 4 12:00:02 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/ADCE/2004-05-04-UnreachableBlock.llx Message-ID: <200405041700.MAA21420@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/ADCE: 2004-05-04-UnreachableBlock.llx added (r1.1) --- Log message: New testcase for PR332: http://llvm.cs.uiuc.edu/PR332 --- Diffs of the changes: (+16 -0) Index: llvm/test/Regression/Transforms/ADCE/2004-05-04-UnreachableBlock.llx diff -c /dev/null llvm/test/Regression/Transforms/ADCE/2004-05-04-UnreachableBlock.llx:1.1 *** /dev/null Tue May 4 12:00:20 2004 --- llvm/test/Regression/Transforms/ADCE/2004-05-04-UnreachableBlock.llx Tue May 4 12:00:10 2004 *************** *** 0 **** --- 1,16 ---- + ; RUN: llvm-as < %s | opt -adce -disable-output + + void %test() { + entry: + br label %UnifiedReturnBlock + + UnifiedReturnBlock: + ret void + + invoke_catch.0: ; No predecessors! + br bool false, label %UnifiedUnwindBlock, label %UnifiedReturnBlock + + UnifiedUnwindBlock: ; preds = %invoke_catch.0 + unwind + + } From lattner at cs.uiuc.edu Tue May 4 12:01:29 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue May 4 12:01:29 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/ADCE.cpp Message-ID: <200405041700.MAA21436@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: ADCE.cpp updated: 1.76 -> 1.77 --- Log message: Do not mark instructions in unreachable sections of the function as live. This fixes PR332: http://llvm.cs.uiuc.edu/PR332 and ADCE/2004-05-04-UnreachableBlock.llx --- Diffs of the changes: (+5 -2) Index: llvm/lib/Transforms/Scalar/ADCE.cpp diff -u llvm/lib/Transforms/Scalar/ADCE.cpp:1.76 llvm/lib/Transforms/Scalar/ADCE.cpp:1.77 --- llvm/lib/Transforms/Scalar/ADCE.cpp:1.76 Sat Apr 10 13:06:21 2004 +++ llvm/lib/Transforms/Scalar/ADCE.cpp Tue May 4 12:00:46 2004 @@ -215,8 +215,10 @@ // instructions live in basic blocks that are unreachable. These blocks will // be eliminated later, along with the instructions inside. // - for (df_iterator BBI = df_begin(Func), BBE = df_end(Func); - BBI != BBE; ++BBI) { + std::set ReachableBBs; + for (df_ext_iterator + BBI = df_ext_begin(&Func->front(), ReachableBBs), + BBE = df_ext_end(&Func->front(), ReachableBBs); BBI != BBE; ++BBI) { BasicBlock *BB = *BBI; for (BasicBlock::iterator II = BB->begin(), EI = BB->end(); II != EI; ) { Instruction *I = II++; @@ -279,6 +281,7 @@ WorkList.pop_back(); BasicBlock *BB = I->getParent(); + if (!ReachableBBs.count(BB)) continue; if (!AliveBlocks.count(BB)) { // Basic block not alive yet... AliveBlocks.insert(BB); // Block is now ALIVE! markBlockAlive(BB); // Make it so now! From lattner at cs.uiuc.edu Tue May 4 12:06:06 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue May 4 12:06:06 2004 Subject: [llvm-commits] CVS: llvm-www/releases/1.2/docs/ReleaseNotes.html Message-ID: <200405041704.MAA23547@zion.cs.uiuc.edu> Changes in directory llvm-www/releases/1.2/docs: ReleaseNotes.html updated: 1.11 -> 1.12 --- Log message: Bug found --- Diffs of the changes: (+3 -1) Index: llvm-www/releases/1.2/docs/ReleaseNotes.html diff -u llvm-www/releases/1.2/docs/ReleaseNotes.html:1.11 llvm-www/releases/1.2/docs/ReleaseNotes.html:1.12 --- llvm-www/releases/1.2/docs/ReleaseNotes.html:1.11 Fri Apr 30 17:17:37 2004 +++ llvm-www/releases/1.2/docs/ReleaseNotes.html Tue May 4 12:04:19 2004 @@ -352,6 +352,8 @@
  • [loopsimplify] Loop simplify incorrectly updates dominator information
  • [tailduplicate] DemoteRegToStack breaks SSA form
  • + +
  • [adce] Crash handling unreachable code that unwinds
  • @@ -675,7 +677,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/04/30 22:17:37 $ + Last modified: $Date: 2004/05/04 17:04:19 $ From lattner at cs.uiuc.edu Tue May 4 12:06:08 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue May 4 12:06:08 2004 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200405041704.MAA22996@zion.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.170 -> 1.171 --- Log message: Bug fixed --- Diffs of the changes: (+12 -4) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.170 llvm/docs/ReleaseNotes.html:1.171 --- llvm/docs/ReleaseNotes.html:1.170 Sat May 1 23:19:15 2004 +++ llvm/docs/ReleaseNotes.html Tue May 4 12:04:09 2004 @@ -70,7 +70,11 @@

    -This is the fourth public release of the LLVM compiler infrastructure. +This is the fourth public release of the LLVM compiler infrastructure. This +release primarily improves the performance of the +code produced by all aspects of the LLVM compiler and adds some new features, though it does fix a few +bugs as well.

    @@ -167,13 +171,16 @@ memory.

  • The link-time optimizer now runs the -prune-eh pass (to remove unused -exception handlers.
  • +exception handlers).
  • The -simplifycfg pass can now eliminate simple correlated branches (such as "if (A < B && A < B)", and can turn short-circuiting operators into the strict versions when useful (such as "if (A < B || A > C)" into "if (A < B | A > C)"
  • +
  • LLVM now has infrastructure for (simple and sparse conditional) constant +propagation of function calls. It currently supports a few math library +functions like sqrt/sin/cos/etc.
  • @@ -192,6 +199,7 @@ breaks SSA form
  • [X86] JIT miscompiles unsigned short to floating point cast
  • +
  • [adce] Crash handling unreachable code that unwinds
  • @@ -230,7 +238,7 @@
    1. warnings compiling Stacker compiler on Mac OS X
    2. -
    3. getObjectType doesn't understand abbreviated names in headers
    4. +
    5. Archive file reader doesn't understand abbreviated names in headers
    @@ -622,7 +630,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/05/02 04:19:15 $ + Last modified: $Date: 2004/05/04 17:04:09 $ From gaeke at cs.uiuc.edu Tue May 4 12:11:03 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue May 4 12:11:03 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/ProfileInfoLoader.h Message-ID: <200405041711.MAA27994@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: ProfileInfoLoader.h updated: 1.2 -> 1.3 --- Log message: Add BBTrace accessor method and data member. --- Diffs of the changes: (+6 -0) Index: llvm/include/llvm/Analysis/ProfileInfoLoader.h diff -u llvm/include/llvm/Analysis/ProfileInfoLoader.h:1.2 llvm/include/llvm/Analysis/ProfileInfoLoader.h:1.3 --- llvm/include/llvm/Analysis/ProfileInfoLoader.h:1.2 Mon Mar 8 12:19:37 2004 +++ llvm/include/llvm/Analysis/ProfileInfoLoader.h Tue May 4 12:11:13 2004 @@ -32,6 +32,7 @@ std::vector FunctionCounts; std::vector BlockCounts; std::vector EdgeCounts; + std::vector BBTrace; public: // ProfileInfoLoader ctor - Read the specified profiling data file, exiting // the program if the file is invalid or broken. @@ -76,6 +77,11 @@ // typedef std::pair Edge; void getEdgeCounts(std::vector > &Counts); + + // getBBTrace - This method is used by consumers of basic-block trace + // information. + // + void getBBTrace(std::vector &Trace); }; } // End llvm namespace From gaeke at cs.uiuc.edu Tue May 4 12:11:06 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue May 4 12:11:06 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/ProfileInfoLoader.cpp Message-ID: <200405041711.MAA27999@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: ProfileInfoLoader.cpp updated: 1.5 -> 1.6 --- Log message: Add stub support for reading BBTraces. --- Diffs of the changes: (+16 -0) Index: llvm/lib/Analysis/ProfileInfoLoader.cpp diff -u llvm/lib/Analysis/ProfileInfoLoader.cpp:1.5 llvm/lib/Analysis/ProfileInfoLoader.cpp:1.6 --- llvm/lib/Analysis/ProfileInfoLoader.cpp:1.5 Tue May 4 11:53:07 2004 +++ llvm/lib/Analysis/ProfileInfoLoader.cpp Tue May 4 12:11:14 2004 @@ -123,6 +123,10 @@ ReadProfilingBlock(ToolName, F, ShouldByteSwap, EdgeCounts); break; + case BBTraceInfo: + ReadProfilingBlock(ToolName, F, ShouldByteSwap, BBTrace); + break; + default: std::cerr << ToolName << ": Unknown packet type #" << PacketType << "!\n"; exit(1); @@ -257,3 +261,15 @@ return; } } + +// getBBTrace - This method is used by consumers of basic-block trace +// information. +// +void ProfileInfoLoader::getBBTrace(std::vector &Trace) { + if (BBTrace.empty ()) { + std::cerr << "Basic block trace is not available!\n"; + return; + } + std::cerr << "Basic block trace loading is not implemented yet!\n"; +} + From brukman at cs.uiuc.edu Tue May 4 13:31:03 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Tue May 4 13:31:03 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/InstVisitor.h Message-ID: <200405041830.NAA18474@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: InstVisitor.h updated: 1.28 -> 1.29 --- Log message: Provide visit(Module&) and visitModule(Module&) functionality. --- Diffs of the changes: (+5 -0) Index: llvm/include/llvm/Support/InstVisitor.h diff -u llvm/include/llvm/Support/InstVisitor.h:1.28 llvm/include/llvm/Support/InstVisitor.h:1.29 --- llvm/include/llvm/Support/InstVisitor.h:1.28 Thu Mar 11 23:51:22 2004 +++ llvm/include/llvm/Support/InstVisitor.h Tue May 4 13:30:38 2004 @@ -88,6 +88,10 @@ // Define visitors for functions and basic blocks... // + void visit(Module &M) { + ((SubClass*)this)->visitModule(M); + visit(M.begin(), M.end()); + } void visit(Function &F) { ((SubClass*)this)->visitFunction(F); visit(F.begin(), F.end()); @@ -127,6 +131,7 @@ // When visiting a module, function or basic block directly, these methods get // called to indicate when transitioning into a new unit. // + void visitModule (Module &M) {} void visitFunction (Function &F) {} void visitBasicBlock(BasicBlock &BB) {} From lattner at cs.uiuc.edu Tue May 4 14:34:03 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue May 4 14:34:03 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200405041934.OAA26283@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.243 -> 1.244 --- Log message: Improve signed division by power of 2 *dramatically* from this: div: mov %EDX, DWORD PTR [%ESP + 4] mov %ECX, 64 mov %EAX, %EDX sar %EDX, 31 idiv %ECX ret to this: div: mov %EAX, DWORD PTR [%ESP + 4] mov %ECX, %EAX sar %ECX, 5 shr %ECX, 26 mov %EDX, %EAX add %EDX, %ECX sar %EAX, 6 ret Note that the intel compiler is currently making this: div: movl 4(%esp), %edx #3.5 movl %edx, %eax #4.14 sarl $5, %eax #4.14 shrl $26, %eax #4.14 addl %edx, %eax #4.14 sarl $6, %eax #4.14 ret #4.14 Which has one less register->register copy. (hint hint alkis :) --- Diffs of the changes: (+63 -9) Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.243 llvm/lib/Target/X86/InstSelectSimple.cpp:1.244 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.243 Tue May 4 10:47:14 2004 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Tue May 4 14:33:58 2004 @@ -2177,7 +2177,7 @@ // ExactLog2 - This function solves for (Val == 1 << (N-1)) and returns N. It // returns zero when the input is not exactly a power of two. static unsigned ExactLog2(unsigned Val) { - if (Val == 0) return 0; + if (Val == 0 || (Val & (Val-1))) return 0; unsigned Count = 0; while (Val != 1) { if (Val & 1) return 0; @@ -2488,9 +2488,61 @@ default: assert(0 && "Unknown class!"); } - static const unsigned Regs[] ={ X86::AL , X86::AX , X86::EAX }; static const unsigned MovOpcode[]={ X86::MOV8rr, X86::MOV16rr, X86::MOV32rr }; - static const unsigned SarOpcode[]={ X86::SAR8ri, X86::SAR16ri, X86::SAR32ri }; + static const unsigned NEGOpcode[] = { X86::NEG8r, X86::NEG16r, X86::NEG32r }; + static const unsigned SAROpcode[]={ X86::SAR8ri, X86::SAR16ri, X86::SAR32ri }; + static const unsigned SHROpcode[]={ X86::SHR8ri, X86::SHR16ri, X86::SHR32ri }; + static const unsigned ADDOpcode[]={ X86::ADD8rr, X86::ADD16rr, X86::ADD32rr }; + + // Special case signed division by power of 2. + if (isDiv) + if (ConstantSInt *CI = dyn_cast(Op1)) { + assert(Class != cLong && "This doesn't handle 64-bit divides!"); + int V = CI->getValue(); + + if (V == 1) { // X /s 1 => X + unsigned Op0Reg = getReg(Op0, BB, IP); + BuildMI(*BB, IP, MovOpcode[Class], 1, ResultReg).addReg(Op0Reg); + return; + } + + if (V == -1) { // X /s -1 => -X + unsigned Op0Reg = getReg(Op0, BB, IP); + BuildMI(*BB, IP, NEGOpcode[Class], 1, ResultReg).addReg(Op0Reg); + return; + } + + bool isNeg = false; + if (V < 0) { // Not a positive power of 2? + V = -V; + isNeg = true; // Maybe it's a negative power of 2. + } + if (unsigned Log = ExactLog2(V)) { + --Log; + unsigned Op0Reg = getReg(Op0, BB, IP); + unsigned TmpReg = makeAnotherReg(Op0->getType()); + if (Log != 1) + BuildMI(*BB, IP, SAROpcode[Class], 2, TmpReg) + .addReg(Op0Reg).addImm(Log-1); + else + BuildMI(*BB, IP, MovOpcode[Class], 1, TmpReg).addReg(Op0Reg); + unsigned TmpReg2 = makeAnotherReg(Op0->getType()); + BuildMI(*BB, IP, SHROpcode[Class], 2, TmpReg2) + .addReg(TmpReg).addImm(32-Log); + unsigned TmpReg3 = makeAnotherReg(Op0->getType()); + BuildMI(*BB, IP, ADDOpcode[Class], 2, TmpReg3) + .addReg(Op0Reg).addReg(TmpReg2); + + unsigned TmpReg4 = isNeg ? makeAnotherReg(Op0->getType()) : ResultReg; + BuildMI(*BB, IP, SAROpcode[Class], 2, TmpReg4) + .addReg(Op0Reg).addImm(Log); + if (isNeg) + BuildMI(*BB, IP, NEGOpcode[Class], 1, ResultReg).addReg(TmpReg4); + return; + } + } + + static const unsigned Regs[] ={ X86::AL , X86::AX , X86::EAX }; static const unsigned ClrOpcode[]={ X86::MOV8ri, X86::MOV16ri, X86::MOV32ri }; static const unsigned ExtRegs[] ={ X86::AH , X86::DX , X86::EDX }; @@ -2499,7 +2551,6 @@ { X86::IDIV8r, X86::IDIV16r, X86::IDIV32r, 0 }, // Signed division }; - bool isSigned = Ty->isSigned(); unsigned Reg = Regs[Class]; unsigned ExtReg = ExtRegs[Class]; @@ -2508,18 +2559,21 @@ unsigned Op1Reg = getReg(Op1, BB, IP); BuildMI(*BB, IP, MovOpcode[Class], 1, Reg).addReg(Op0Reg); - if (isSigned) { + if (Ty->isSigned()) { // Emit a sign extension instruction... unsigned ShiftResult = makeAnotherReg(Op0->getType()); - BuildMI(*BB, IP, SarOpcode[Class], 2,ShiftResult).addReg(Op0Reg).addImm(31); + BuildMI(*BB, IP, SAROpcode[Class], 2,ShiftResult).addReg(Op0Reg).addImm(31); BuildMI(*BB, IP, MovOpcode[Class], 1, ExtReg).addReg(ShiftResult); + + // Emit the appropriate divide or remainder instruction... + BuildMI(*BB, IP, DivOpcode[1][Class], 1).addReg(Op1Reg); } else { // If unsigned, emit a zeroing instruction... (reg = 0) BuildMI(*BB, IP, ClrOpcode[Class], 2, ExtReg).addImm(0); - } - // Emit the appropriate divide or remainder instruction... - BuildMI(*BB, IP, DivOpcode[isSigned][Class], 1).addReg(Op1Reg); + // Emit the appropriate divide or remainder instruction... + BuildMI(*BB, IP, DivOpcode[0][Class], 1).addReg(Op1Reg); + } // Figure out which register we want to pick the result out of... unsigned DestReg = isDiv ? Reg : ExtReg; From lattner at cs.uiuc.edu Tue May 4 14:35:03 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue May 4 14:35:03 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200405041935.OAA26295@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.244 -> 1.245 --- Log message: Remove unneeded check --- Diffs of the changes: (+0 -1) Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.244 llvm/lib/Target/X86/InstSelectSimple.cpp:1.245 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.244 Tue May 4 14:33:58 2004 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Tue May 4 14:35:11 2004 @@ -2180,7 +2180,6 @@ if (Val == 0 || (Val & (Val-1))) return 0; unsigned Count = 0; while (Val != 1) { - if (Val & 1) return 0; Val >>= 1; ++Count; } From gaeke at cs.uiuc.edu Tue May 4 16:09:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue May 4 16:09:01 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/ToolRunner.h Message-ID: <200405042109.QAA29504@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: ToolRunner.h updated: 1.11 -> 1.12 --- Log message: Add "Args" optional argument to AbstractInterpreter factory methods, which fills in a ToolArgs vector in the AbstractInterpreter if it is set. This ToolArgs vector is used to pass additional arguments to LLI and/or LLC. This is intended to address Bug 40: http://llvm.cs.uiuc.edu/PR40 . Also, make -debug-only=toolrunner work for the LLC and CBE AbstractInterpreters. --- Diffs of the changes: (+20 -8) Index: llvm/include/llvm/Support/ToolRunner.h diff -u llvm/include/llvm/Support/ToolRunner.h:1.11 llvm/include/llvm/Support/ToolRunner.h:1.12 --- llvm/include/llvm/Support/ToolRunner.h:1.11 Thu Feb 19 01:39:26 2004 +++ llvm/include/llvm/Support/ToolRunner.h Tue May 4 16:09:01 2004 @@ -80,14 +80,18 @@ /// complexity behind a simple interface. /// struct AbstractInterpreter { - static CBE* createCBE(const std::string &ProgramPath, std::string &Message); - static LLC *createLLC(const std::string &ProgramPath, std::string &Message); + static CBE *createCBE(const std::string &ProgramPath, std::string &Message, + const std::vector *Args = 0); + static LLC *createLLC(const std::string &ProgramPath, std::string &Message, + const std::vector *Args = 0); static AbstractInterpreter* createLLI(const std::string &ProgramPath, - std::string &Message); + std::string &Message, + const std::vector *Args=0); static AbstractInterpreter* createJIT(const std::string &ProgramPath, - std::string &Message); + std::string &Message, + const std::vector *Args=0); virtual ~AbstractInterpreter() {} @@ -114,9 +118,14 @@ // class CBE : public AbstractInterpreter { std::string LLCPath; // The path to the `llc' executable + std::vector ToolArgs; // Extra args to pass to LLC GCC *gcc; public: - CBE(const std::string &llcPath, GCC *Gcc) : LLCPath(llcPath), gcc(Gcc) { } + CBE(const std::string &llcPath, GCC *Gcc, + const std::vector *Args) : LLCPath(llcPath), gcc(Gcc) { + ToolArgs.clear (); + if (Args) { ToolArgs.assign (Args->begin (), Args->end ()); } + } ~CBE() { delete gcc; } /// compileProgram - Compile the specified program from bytecode to executable @@ -145,12 +154,15 @@ // class LLC : public AbstractInterpreter { std::string LLCPath; // The path to the LLC executable + std::vector ToolArgs; // Extra args to pass to LLC GCC *gcc; public: - LLC(const std::string &llcPath, GCC *Gcc) - : LLCPath(llcPath), gcc(Gcc) { } + LLC(const std::string &llcPath, GCC *Gcc, + const std::vector *Args) : LLCPath(llcPath), gcc(Gcc) { + ToolArgs.clear (); + if (Args) { ToolArgs.assign (Args->begin (), Args->end ()); } + } ~LLC() { delete gcc; } - /// compileProgram - Compile the specified program from bytecode to executable /// code. This does not produce any output, it is only used when debugging From gaeke at cs.uiuc.edu Tue May 4 16:09:07 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue May 4 16:09:07 2004 Subject: [llvm-commits] CVS: llvm/lib/Support/ToolRunner.cpp Message-ID: <200405042109.QAA29511@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: ToolRunner.cpp updated: 1.22 -> 1.23 --- Log message: Add "Args" optional argument to AbstractInterpreter factory methods, which fills in a ToolArgs vector in the AbstractInterpreter if it is set. This ToolArgs vector is used to pass additional arguments to LLI and/or LLC. This is intended to address Bug 40: http://llvm.cs.uiuc.edu/PR40 . Also, make -debug-only=toolrunner work for the LLC and CBE AbstractInterpreters. --- Diffs of the changes: (+71 -31) Index: llvm/lib/Support/ToolRunner.cpp diff -u llvm/lib/Support/ToolRunner.cpp:1.22 llvm/lib/Support/ToolRunner.cpp:1.23 --- llvm/lib/Support/ToolRunner.cpp:1.22 Mon Apr 5 15:28:41 2004 +++ llvm/lib/Support/ToolRunner.cpp Tue May 4 16:09:01 2004 @@ -54,9 +54,13 @@ namespace { class LLI : public AbstractInterpreter { std::string LLIPath; // The path to the LLI executable + std::vector ToolArgs; // Args to pass to LLI public: - LLI(const std::string &Path) : LLIPath(Path) { } - + LLI(const std::string &Path, const std::vector *Args) + : LLIPath(Path) { + ToolArgs.clear (); + if (Args) { ToolArgs.assign (Args->begin (), Args->end ()); } + } virtual int ExecuteProgram(const std::string &Bytecode, const std::vector &Args, @@ -79,6 +83,11 @@ std::vector LLIArgs; LLIArgs.push_back(LLIPath.c_str()); LLIArgs.push_back("-force-interpreter=true"); + + // Add any extra LLI args. + for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i) + LLIArgs.push_back(ToolArgs[i].c_str()); + LLIArgs.push_back(Bytecode.c_str()); // Add optional parameters to the running program from Argv for (unsigned i=0, e = Args.size(); i != e; ++i) @@ -97,11 +106,12 @@ // LLI create method - Try to find the LLI executable AbstractInterpreter *AbstractInterpreter::createLLI(const std::string &ProgPath, - std::string &Message) { + std::string &Message, + const std::vector *ToolArgs) { std::string LLIPath = FindExecutable("lli", ProgPath); if (!LLIPath.empty()) { Message = "Found lli: " + LLIPath + "\n"; - return new LLI(LLIPath); + return new LLI(LLIPath, ToolArgs); } Message = "Cannot find `lli' in executable directory or PATH!\n"; @@ -113,18 +123,28 @@ // void LLC::OutputAsm(const std::string &Bytecode, std::string &OutputAsmFile) { OutputAsmFile = getUniqueFilename(Bytecode+".llc.s"); - const char *LLCArgs[] = { - LLCPath.c_str(), - "-o", OutputAsmFile.c_str(), // Output to the Asm file - "-f", // Overwrite as necessary... - Bytecode.c_str(), // This is the input bytecode - 0 - }; + std::vector LLCArgs; + LLCArgs.push_back (LLCPath.c_str()); + + // Add any extra LLC args. + for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i) + LLCArgs.push_back(ToolArgs[i].c_str()); + + LLCArgs.push_back ("-o"); + LLCArgs.push_back (OutputAsmFile.c_str()); // Output to the Asm file + LLCArgs.push_back ("-f"); // Overwrite as necessary... + LLCArgs.push_back (Bytecode.c_str()); // This is the input bytecode + LLCArgs.push_back (0); std::cout << "" << std::flush; - if (RunProgramWithTimeout(LLCPath, LLCArgs, "/dev/null", "/dev/null", + DEBUG(std::cerr << "\nAbout to run:\t"; + for (unsigned i=0, e = LLCArgs.size()-1; i != e; ++i) + std::cerr << " " << LLCArgs[i]; + std::cerr << "\n"; + ); + if (RunProgramWithTimeout(LLCPath, &LLCArgs[0], "/dev/null", "/dev/null", "/dev/null")) - ProcessFailure(LLCPath, LLCArgs); + ProcessFailure(LLCPath, &LLCArgs[0]); } void LLC::compileProgram(const std::string &Bytecode) { @@ -151,7 +171,8 @@ /// createLLC - Try to find the LLC executable /// LLC *AbstractInterpreter::createLLC(const std::string &ProgramPath, - std::string &Message) { + std::string &Message, + const std::vector *Args) { std::string LLCPath = FindExecutable("llc", ProgramPath); if (LLCPath.empty()) { Message = "Cannot find `llc' in executable directory or PATH!\n"; @@ -164,7 +185,7 @@ std::cerr << Message << "\n"; exit(1); } - return new LLC(LLCPath, gcc); + return new LLC(LLCPath, gcc, Args); } //===---------------------------------------------------------------------===// @@ -173,9 +194,13 @@ namespace { class JIT : public AbstractInterpreter { std::string LLIPath; // The path to the LLI executable + std::vector ToolArgs; // Args to pass to LLI public: - JIT(const std::string &Path) : LLIPath(Path) { } - + JIT(const std::string &Path, const std::vector *Args) + : LLIPath(Path) { + ToolArgs.clear (); + if (Args) { ToolArgs.assign (Args->begin (), Args->end ()); } + } virtual int ExecuteProgram(const std::string &Bytecode, const std::vector &Args, @@ -196,6 +221,10 @@ JITArgs.push_back(LLIPath.c_str()); JITArgs.push_back("-force-interpreter=false"); + // Add any extra LLI args. + for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i) + JITArgs.push_back(ToolArgs[i].c_str()); + for (unsigned i = 0, e = SharedLibs.size(); i != e; ++i) { JITArgs.push_back("-load"); JITArgs.push_back(SharedLibs[i].c_str()); @@ -220,11 +249,11 @@ /// createJIT - Try to find the LLI executable /// AbstractInterpreter *AbstractInterpreter::createJIT(const std::string &ProgPath, - std::string &Message) { + std::string &Message, const std::vector *Args) { std::string LLIPath = FindExecutable("lli", ProgPath); if (!LLIPath.empty()) { Message = "Found lli: " + LLIPath + "\n"; - return new JIT(LLIPath); + return new JIT(LLIPath, Args); } Message = "Cannot find `lli' in executable directory or PATH!\n"; @@ -234,19 +263,29 @@ void CBE::OutputC(const std::string &Bytecode, std::string &OutputCFile) { OutputCFile = getUniqueFilename(Bytecode+".cbe.c"); - const char *LLCArgs[] = { - LLCPath.c_str(), - "-o", OutputCFile.c_str(), // Output to the C file - "-march=c", // Output to C - "-f", // Overwrite as necessary... - Bytecode.c_str(), // This is the input bytecode - 0 - }; + std::vector LLCArgs; + LLCArgs.push_back (LLCPath.c_str()); + + // Add any extra LLC args. + for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i) + LLCArgs.push_back(ToolArgs[i].c_str()); + + LLCArgs.push_back ("-o"); + LLCArgs.push_back (OutputCFile.c_str()); // Output to the C file + LLCArgs.push_back ("-march=c"); // Output C language + LLCArgs.push_back ("-f"); // Overwrite as necessary... + LLCArgs.push_back (Bytecode.c_str()); // This is the input bytecode + LLCArgs.push_back (0); std::cout << "" << std::flush; - if (RunProgramWithTimeout(LLCPath, LLCArgs, "/dev/null", "/dev/null", + DEBUG(std::cerr << "\nAbout to run:\t"; + for (unsigned i=0, e = LLCArgs.size()-1; i != e; ++i) + std::cerr << " " << LLCArgs[i]; + std::cerr << "\n"; + ); + if (RunProgramWithTimeout(LLCPath, &LLCArgs[0], "/dev/null", "/dev/null", "/dev/null")) - ProcessFailure(LLCPath, LLCArgs); + ProcessFailure(LLCPath, &LLCArgs[0]); } void CBE::compileProgram(const std::string &Bytecode) { @@ -272,7 +311,8 @@ /// createCBE - Try to find the 'llc' executable /// CBE *AbstractInterpreter::createCBE(const std::string &ProgramPath, - std::string &Message) { + std::string &Message, + const std::vector *Args) { std::string LLCPath = FindExecutable("llc", ProgramPath); if (LLCPath.empty()) { Message = @@ -286,7 +326,7 @@ std::cerr << Message << "\n"; exit(1); } - return new CBE(LLCPath, gcc); + return new CBE(LLCPath, gcc, Args); } //===---------------------------------------------------------------------===// From gaeke at cs.uiuc.edu Tue May 4 16:09:11 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue May 4 16:09:11 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/SparcV9AsmPrinter.cpp Message-ID: <200405042109.QAA29518@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9AsmPrinter.cpp updated: 1.110 -> 1.111 --- Log message: Correctly mangle function names when they are used as part of a constant pool member's name. This is intended to address Bug 333: http://llvm.cs.uiuc.edu/PR333 . Also, fix an anachronistic usage of "M" as a parameter of type Function *. --- Diffs of the changes: (+3 -3) Index: llvm/lib/Target/SparcV9/SparcV9AsmPrinter.cpp diff -u llvm/lib/Target/SparcV9/SparcV9AsmPrinter.cpp:1.110 llvm/lib/Target/SparcV9/SparcV9AsmPrinter.cpp:1.111 --- llvm/lib/Target/SparcV9/SparcV9AsmPrinter.cpp:1.110 Sun Apr 25 02:04:49 2004 +++ llvm/lib/Target/SparcV9/SparcV9AsmPrinter.cpp Tue May 4 16:09:02 2004 @@ -651,7 +651,7 @@ case MachineOperand::MO_ConstantPoolIndex: { - toAsm << ".CPI_" << currFunction->getName() + toAsm << ".CPI_" << getID(currFunction) << "_" << mop.getConstantPoolIndex(); break; } @@ -663,8 +663,8 @@ if (const BasicBlock *BB = dyn_cast(Val)) toAsm << getID(BB); - else if (const Function *M = dyn_cast(Val)) - toAsm << getID(M); + else if (const Function *F = dyn_cast(Val)) + toAsm << getID(F); else if (const GlobalVariable *GV = dyn_cast(Val)) toAsm << getID(GV); else if (const Constant *CV = dyn_cast(Val)) From gaeke at cs.uiuc.edu Tue May 4 16:09:13 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue May 4 16:09:13 2004 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/ExecutionDriver.cpp Message-ID: <200405042109.QAA29789@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: ExecutionDriver.cpp updated: 1.40 -> 1.41 --- Log message: Add --tool-args flag which lets you pass arguments to llc or lli. This is intended to address Bug 40: http://llvm.cs.uiuc.edu/PR40 . --- Diffs of the changes: (+22 -9) Index: llvm/tools/bugpoint/ExecutionDriver.cpp diff -u llvm/tools/bugpoint/ExecutionDriver.cpp:1.40 llvm/tools/bugpoint/ExecutionDriver.cpp:1.41 --- llvm/tools/bugpoint/ExecutionDriver.cpp:1.40 Sun Apr 18 22:12:35 2004 +++ llvm/tools/bugpoint/ExecutionDriver.cpp Tue May 4 16:09:16 2004 @@ -71,6 +71,10 @@ cl::list InputArgv("args", cl::Positional, cl::desc("..."), cl::ZeroOrMore); + + cl::list + ToolArgv("tool-args", cl::Positional, cl::desc("..."), + cl::ZeroOrMore); } //===----------------------------------------------------------------------===// @@ -87,21 +91,26 @@ // the command line cbe = 0; std::string Message; + switch (InterpreterSel) { case AutoPick: InterpreterSel = RunCBE; - Interpreter = cbe = AbstractInterpreter::createCBE(getToolName(), Message); + Interpreter = cbe = AbstractInterpreter::createCBE(getToolName(), Message, + &ToolArgv); if (!Interpreter) { InterpreterSel = RunJIT; - Interpreter = AbstractInterpreter::createJIT(getToolName(), Message); + Interpreter = AbstractInterpreter::createJIT(getToolName(), Message, + &ToolArgv); } if (!Interpreter) { InterpreterSel = RunLLC; - Interpreter = AbstractInterpreter::createLLC(getToolName(), Message); + Interpreter = AbstractInterpreter::createLLC(getToolName(), Message, + &ToolArgv); } if (!Interpreter) { InterpreterSel = RunLLI; - Interpreter = AbstractInterpreter::createLLI(getToolName(), Message); + Interpreter = AbstractInterpreter::createLLI(getToolName(), Message, + &ToolArgv); } if (!Interpreter) { InterpreterSel = AutoPick; @@ -109,16 +118,20 @@ } break; case RunLLI: - Interpreter = AbstractInterpreter::createLLI(getToolName(), Message); + Interpreter = AbstractInterpreter::createLLI(getToolName(), Message, + &ToolArgv); break; case RunLLC: - Interpreter = AbstractInterpreter::createLLC(getToolName(), Message); + Interpreter = AbstractInterpreter::createLLC(getToolName(), Message, + &ToolArgv); break; case RunJIT: - Interpreter = AbstractInterpreter::createJIT(getToolName(), Message); + Interpreter = AbstractInterpreter::createJIT(getToolName(), Message, + &ToolArgv); break; case RunCBE: - Interpreter = cbe = AbstractInterpreter::createCBE(getToolName(), Message); + Interpreter = cbe = AbstractInterpreter::createCBE(getToolName(), Message, + &ToolArgv); break; default: Message = "Sorry, this back-end is not supported by bugpoint right now!\n"; @@ -128,7 +141,7 @@ // Initialize auxiliary tools for debugging if (!cbe) { - cbe = AbstractInterpreter::createCBE(getToolName(), Message); + cbe = AbstractInterpreter::createCBE(getToolName(), Message, &ToolArgv); if (!cbe) { std::cout << Message << "\nExiting.\n"; exit(1); } } gcc = GCC::create(getToolName(), Message); From gaeke at cs.uiuc.edu Tue May 4 16:13:00 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue May 4 16:13:00 2004 Subject: [llvm-commits] CVS: llvm/docs/CommandGuide/bugpoint.html Message-ID: <200405042113.QAA30127@zion.cs.uiuc.edu> Changes in directory llvm/docs/CommandGuide: bugpoint.html updated: 1.28 -> 1.29 --- Log message: update command guide to have --tool-args --- Diffs of the changes: (+12 -0) Index: llvm/docs/CommandGuide/bugpoint.html diff -u llvm/docs/CommandGuide/bugpoint.html:1.28 llvm/docs/CommandGuide/bugpoint.html:1.29 --- llvm/docs/CommandGuide/bugpoint.html:1.28 Sun Apr 18 22:28:39 2004 +++ llvm/docs/CommandGuide/bugpoint.html Tue May 4 16:13:35 2004 @@ -177,6 +177,18 @@ part of the -args option, not as options to bugpoint itself.

    +

  • -tool-args <tool args>
    + Pass all arguments specified after -tool-args to the + LLVM tool under test (llc, lli, etc.) whenever it runs. + You should use this option in the following way: +

    + bugpoint <bugpoint args> -tool-args -- <tool args> +

    + The "--" right after the -tool-args option tells + bugpoint to consider any options starting with - to be + part of the -tool-args option, not as options to + bugpoint itself. (See -args, above.)

    +

  • -check-exit-code={true,false}
    Assume a non-zero exit code or core dump from the test program is a failure. Defaults to true.

    From gaeke at cs.uiuc.edu Tue May 4 16:23:02 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue May 4 16:23:02 2004 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200405042123.QAA30979@zion.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.171 -> 1.172 --- Log message: Bugs fixed --- Diffs of the changes: (+6 -3) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.171 llvm/docs/ReleaseNotes.html:1.172 --- llvm/docs/ReleaseNotes.html:1.171 Tue May 4 12:04:09 2004 +++ llvm/docs/ReleaseNotes.html Tue May 4 16:22:57 2004 @@ -96,6 +96,9 @@ generators, and the interpreter.

  • Bugpoint can now narrow down code-generation bugs to a loop nest, where before it could only narrow them down to a function being miscompiled.
  • +
  • Bugpoint can now debug arbitrary +modes of llc and lli, by passing them command line flags (e.g., +-regalloc=linearscan, -enable-correct-eh-support, etc.)
  • The Control Flow Graph in the native code generators is no longer constrained to be the same as the CFG for the LLVM input code.
  • The LLVM induction variable analysis routines have been rewritten.
  • @@ -200,10 +203,10 @@
  • [X86] JIT miscompiles unsigned short to floating point cast
  • [adce] Crash handling unreachable code that unwinds
  • +
  • [sparc] LLC can't emit 2 functions of +the same name, both having constant pools
  • - -

    Bugs in the C/C++ front-end:

      @@ -630,7 +633,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
      - Last modified: $Date: 2004/05/04 17:04:09 $ + Last modified: $Date: 2004/05/04 21:22:57 $ From gaeke at cs.uiuc.edu Tue May 4 16:24:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue May 4 16:24:01 2004 Subject: [llvm-commits] CVS: llvm-www/releases/1.2/docs/ReleaseNotes.html Message-ID: <200405042124.QAA31179@zion.cs.uiuc.edu> Changes in directory llvm-www/releases/1.2/docs: ReleaseNotes.html updated: 1.12 -> 1.13 --- Log message: Bug found --- Diffs of the changes: (+3 -1) Index: llvm-www/releases/1.2/docs/ReleaseNotes.html diff -u llvm-www/releases/1.2/docs/ReleaseNotes.html:1.12 llvm-www/releases/1.2/docs/ReleaseNotes.html:1.13 --- llvm-www/releases/1.2/docs/ReleaseNotes.html:1.12 Tue May 4 12:04:19 2004 +++ llvm-www/releases/1.2/docs/ReleaseNotes.html Tue May 4 16:24:32 2004 @@ -603,6 +603,8 @@
    @@ -677,7 +679,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/05/04 17:04:19 $ + Last modified: $Date: 2004/05/04 21:24:32 $ From lattner at cs.uiuc.edu Tue May 4 16:39:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue May 4 16:39:01 2004 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/Makefile.multisrc Message-ID: <200405042139.QAA13823@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource: Makefile.multisrc updated: 1.41 -> 1.42 --- Log message: Add a bugpoint-llc-ls target for the day when we support Output/*.bugpoint-llc-ls targets --- Diffs of the changes: (+1 -0) Index: llvm/test/Programs/MultiSource/Makefile.multisrc diff -u llvm/test/Programs/MultiSource/Makefile.multisrc:1.41 llvm/test/Programs/MultiSource/Makefile.multisrc:1.42 --- llvm/test/Programs/MultiSource/Makefile.multisrc:1.41 Sun Feb 22 14:18:18 2004 +++ llvm/test/Programs/MultiSource/Makefile.multisrc Tue May 4 16:39:22 2004 @@ -41,6 +41,7 @@ bugpoint-gccld: Output/$(PROG).bugpoint-gccld bugpoint-jit: Output/$(PROG).bugpoint-jit bugpoint-llc: Output/$(PROG).bugpoint-llc +bugpoint-llc-ls: Output/$(PROG).bugpoint-llc-ls # Raw bytecode files are files created by simply assembling the output of the # GCC frontend, without running any optimizations. From gaeke at cs.uiuc.edu Tue May 4 16:42:04 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue May 4 16:42:04 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/SparcV9AsmPrinter.cpp Message-ID: <200405042141.QAA14194@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9AsmPrinter.cpp updated: 1.111 -> 1.112 --- Log message: Missing piece of fix for Bug 333: http://llvm.cs.uiuc.edu/PR333 --- Diffs of the changes: (+1 -1) Index: llvm/lib/Target/SparcV9/SparcV9AsmPrinter.cpp diff -u llvm/lib/Target/SparcV9/SparcV9AsmPrinter.cpp:1.111 llvm/lib/Target/SparcV9/SparcV9AsmPrinter.cpp:1.112 --- llvm/lib/Target/SparcV9/SparcV9AsmPrinter.cpp:1.111 Tue May 4 16:09:02 2004 +++ llvm/lib/Target/SparcV9/SparcV9AsmPrinter.cpp Tue May 4 16:41:45 2004 @@ -736,7 +736,7 @@ enterSection(AsmPrinter::ReadOnlyData); for (unsigned i = 0, e = CP.size(); i != e; ++i) { - std::string cpiName = ".CPI_" + F.getName() + "_" + utostr(i); + std::string cpiName = ".CPI_" + methName + "_" + utostr(i); printConstant(CP[i], cpiName); } From criswell at cs.uiuc.edu Tue May 4 16:47:05 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Tue May 4 16:47:05 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Verifier.cpp Message-ID: <200405042146.QAA21169@choi.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Verifier.cpp updated: 1.96 -> 1.97 --- Log message: Fixed inconsistent indentation. --- Diffs of the changes: (+16 -16) Index: llvm/lib/VMCore/Verifier.cpp diff -u llvm/lib/VMCore/Verifier.cpp:1.96 llvm/lib/VMCore/Verifier.cpp:1.97 --- llvm/lib/VMCore/Verifier.cpp:1.96 Fri Apr 16 00:51:47 2004 +++ llvm/lib/VMCore/Verifier.cpp Tue May 4 16:46:05 2004 @@ -136,22 +136,22 @@ if (Broken) { msgs << "Broken module found, "; - switch (action) - { - case AbortProcessAction: - msgs << "compilation aborted!\n"; - std::cerr << msgs.str(); - abort(); - case ThrowExceptionAction: - msgs << "verification terminated.\n"; - throw msgs.str(); - case PrintMessageAction: - msgs << "verification continues.\n"; - std::cerr << msgs.str(); - break; - case ReturnStatusAction: - break; - } + switch (action) + { + case AbortProcessAction: + msgs << "compilation aborted!\n"; + std::cerr << msgs.str(); + abort(); + case ThrowExceptionAction: + msgs << "verification terminated.\n"; + throw msgs.str(); + case PrintMessageAction: + msgs << "verification continues.\n"; + std::cerr << msgs.str(); + break; + case ReturnStatusAction: + break; + } } } From gaeke at cs.uiuc.edu Tue May 4 17:03:02 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue May 4 17:03:02 2004 Subject: [llvm-commits] CVS: llvm/lib/Support/ToolRunner.cpp Message-ID: <200405042202.RAA22396@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: ToolRunner.cpp updated: 1.23 -> 1.24 --- Log message: Apply simplification suggested by Chris: why assign() when operator = will do? --- Diffs of the changes: (+2 -2) Index: llvm/lib/Support/ToolRunner.cpp diff -u llvm/lib/Support/ToolRunner.cpp:1.23 llvm/lib/Support/ToolRunner.cpp:1.24 --- llvm/lib/Support/ToolRunner.cpp:1.23 Tue May 4 16:09:01 2004 +++ llvm/lib/Support/ToolRunner.cpp Tue May 4 17:02:41 2004 @@ -59,7 +59,7 @@ LLI(const std::string &Path, const std::vector *Args) : LLIPath(Path) { ToolArgs.clear (); - if (Args) { ToolArgs.assign (Args->begin (), Args->end ()); } + if (Args) { ToolArgs = *Args; } } virtual int ExecuteProgram(const std::string &Bytecode, @@ -199,7 +199,7 @@ JIT(const std::string &Path, const std::vector *Args) : LLIPath(Path) { ToolArgs.clear (); - if (Args) { ToolArgs.assign (Args->begin (), Args->end ()); } + if (Args) { ToolArgs = *Args; } } virtual int ExecuteProgram(const std::string &Bytecode, From gaeke at cs.uiuc.edu Tue May 4 17:03:06 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue May 4 17:03:06 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/ToolRunner.h Message-ID: <200405042202.RAA22395@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: ToolRunner.h updated: 1.12 -> 1.13 --- Log message: Apply simplification suggested by Chris: why assign() when operator = will do? --- Diffs of the changes: (+2 -2) Index: llvm/include/llvm/Support/ToolRunner.h diff -u llvm/include/llvm/Support/ToolRunner.h:1.12 llvm/include/llvm/Support/ToolRunner.h:1.13 --- llvm/include/llvm/Support/ToolRunner.h:1.12 Tue May 4 16:09:01 2004 +++ llvm/include/llvm/Support/ToolRunner.h Tue May 4 17:02:41 2004 @@ -124,7 +124,7 @@ CBE(const std::string &llcPath, GCC *Gcc, const std::vector *Args) : LLCPath(llcPath), gcc(Gcc) { ToolArgs.clear (); - if (Args) { ToolArgs.assign (Args->begin (), Args->end ()); } + if (Args) { ToolArgs = *Args; } } ~CBE() { delete gcc; } @@ -160,7 +160,7 @@ LLC(const std::string &llcPath, GCC *Gcc, const std::vector *Args) : LLCPath(llcPath), gcc(Gcc) { ToolArgs.clear (); - if (Args) { ToolArgs.assign (Args->begin (), Args->end ()); } + if (Args) { ToolArgs = *Args; } } ~LLC() { delete gcc; } From gaeke at cs.uiuc.edu Wed May 5 01:10:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed May 5 01:10:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/CFGPrinter.cpp Message-ID: <200405050610.BAA30564@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: CFGPrinter.cpp updated: 1.7 -> 1.8 --- Log message: Move the stuff that fixes the size, orientation & fonts of graphs to the debugging functions that call "dot". These fixed settings have various problems: for example, the fixed size that is set in the graph traits classes is not appropriate for turning the dot file into a PNG, and if TrueType font rendering is being used, the 'Courier' TrueType font may not be installed. It seems easy enough to specify these things on the command line, anyhow. --- Diffs of the changes: (+2 -5) Index: llvm/lib/Analysis/CFGPrinter.cpp diff -u llvm/lib/Analysis/CFGPrinter.cpp:1.7 llvm/lib/Analysis/CFGPrinter.cpp:1.8 --- llvm/lib/Analysis/CFGPrinter.cpp:1.7 Wed Apr 28 23:04:47 2004 +++ llvm/lib/Analysis/CFGPrinter.cpp Wed May 5 01:10:06 2004 @@ -75,10 +75,6 @@ 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" @@ -155,7 +151,8 @@ std::cerr << "\n"; std::cerr << "Running 'dot' program... " << std::flush; - if (system(("dot -Tps " + Filename + " > /tmp/cfg.tempgraph.ps").c_str())) { + if (system(("dot -Tps -Nfontname=Courier -Gsize=7.5,10 " + Filename + + " > /tmp/cfg.tempgraph.ps").c_str())) { std::cerr << "Error running dot: 'dot' not in path?\n"; } else { std::cerr << "\n"; From gaeke at cs.uiuc.edu Wed May 5 01:10:04 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed May 5 01:10:04 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Printer.cpp Message-ID: <200405050610.BAA30569@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Printer.cpp updated: 1.67 -> 1.68 --- Log message: Move the stuff that fixes the size, orientation & fonts of graphs to the debugging functions that call "dot". These fixed settings have various problems: for example, the fixed size that is set in the graph traits classes is not appropriate for turning the dot file into a PNG, and if TrueType font rendering is being used, the 'Courier' TrueType font may not be installed. It seems easy enough to specify these things on the command line, anyhow. --- Diffs of the changes: (+2 -7) Index: llvm/lib/Analysis/DataStructure/Printer.cpp diff -u llvm/lib/Analysis/DataStructure/Printer.cpp:1.67 llvm/lib/Analysis/DataStructure/Printer.cpp:1.68 --- llvm/lib/Analysis/DataStructure/Printer.cpp:1.67 Tue Mar 2 15:39:43 2004 +++ llvm/lib/Analysis/DataStructure/Printer.cpp Wed May 5 01:10:06 2004 @@ -93,17 +93,12 @@ } } - static const char *getGraphProperties(const DSGraph *G) { - return "\tsize=\"10,7.5\";\n" - "\trotate=\"90\";\n"; - } - static std::string getNodeLabel(const DSNode *Node, const DSGraph *Graph) { return getCaption(Node, Graph); } static std::string getNodeAttributes(const DSNode *N) { - return "shape=Mrecord";//fontname=Courier"; + return "shape=Mrecord"; } /// addCustomGraphFeatures - Use this graph writing hook to emit call nodes @@ -234,7 +229,7 @@ } print(F); F.close(); - if (system("dot -Tps /tmp/tempgraph.dot > /tmp/tempgraph.ps")) + if (system("dot -Tps -Gsize=10,7.5 -Grotate=90 /tmp/tempgraph.dot > /tmp/tempgraph.ps")) std::cerr << "Error running dot: 'dot' not in path?\n"; system("gv /tmp/tempgraph.ps"); system("rm /tmp/tempgraph.dot /tmp/tempgraph.ps"); From gaeke at cs.uiuc.edu Wed May 5 01:10:06 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed May 5 01:10:06 2004 Subject: [llvm-commits] CVS: llvm/include/Support/DOTGraphTraits.h Message-ID: <200405050610.BAA30559@zion.cs.uiuc.edu> Changes in directory llvm/include/Support: DOTGraphTraits.h updated: 1.8 -> 1.9 --- Log message: Move the stuff that fixes the size, orientation & fonts of graphs to the debugging functions that call "dot". These fixed settings have various problems: for example, the fixed size that is set in the graph traits classes is not appropriate for turning the dot file into a PNG, and if TrueType font rendering is being used, the 'Courier' TrueType font may not be installed. It seems easy enough to specify these things on the command line, anyhow. --- Diffs of the changes: (+2 -3) Index: llvm/include/Support/DOTGraphTraits.h diff -u llvm/include/Support/DOTGraphTraits.h:1.8 llvm/include/Support/DOTGraphTraits.h:1.9 --- llvm/include/Support/DOTGraphTraits.h:1.8 Tue Nov 11 16:41:29 2003 +++ llvm/include/Support/DOTGraphTraits.h Wed May 5 01:10:06 2004 @@ -33,11 +33,10 @@ static std::string getGraphName(const void *Graph) { return ""; } /// getGraphProperties - Return any custom properties that should be included - /// in the top level graph structure for dot. By default, we resize the graph - /// to fit on a letter size page. + /// in the top level graph structure for dot. /// static std::string getGraphProperties(const void *Graph) { - return "\tsize=\"7.5,10\";\n"; // Size to fit on a page + return ""; } /// getNodeLabel - Given a node and a pointer to the top level graph, return From gaeke at cs.uiuc.edu Wed May 5 14:13:07 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed May 5 14:13:07 2004 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp Message-ID: <200405051912.OAA21794@seraph.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: RuntimeOptimizations.cpp updated: 1.30 -> 1.31 --- Log message: Add another handy-dandy debug message --- Diffs of the changes: (+3 -0) Index: reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp diff -u reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp:1.30 reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp:1.31 --- reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp:1.30 Tue Apr 27 13:34:44 2004 +++ reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp Wed May 5 14:12:32 2004 @@ -121,6 +121,9 @@ // will proceed from the optimized version of the code. uint64_t traceStartAddr = getPointerToGlobalIfAvailable (TF->TraceFn); assert (traceStartAddr && "Address of code for TraceFn was NULL after JIT?!"); + + DEBUG(std::cerr << "Writing branch at 0x" << std::hex << a + << " to point to 0x" << traceStartAddr << std::dec << "\n"); vm->writeBranchInstruction(a, traceStartAddr); doFlush (a, a + 4); } From alkis at cs.uiuc.edu Wed May 5 21:08:02 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed May 5 21:08:02 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/InstVisitor.h Message-ID: <200405060207.VAA22455@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: InstVisitor.h updated: 1.29 -> 1.30 --- Log message: Fix for gcc3.4: invalid use of forward delacred class on line 93 --- Diffs of the changes: (+1 -2) Index: llvm/include/llvm/Support/InstVisitor.h diff -u llvm/include/llvm/Support/InstVisitor.h:1.29 llvm/include/llvm/Support/InstVisitor.h:1.30 --- llvm/include/llvm/Support/InstVisitor.h:1.29 Tue May 4 13:30:38 2004 +++ llvm/include/llvm/Support/InstVisitor.h Wed May 5 21:07:42 2004 @@ -51,10 +51,9 @@ #define LLVM_SUPPORT_INSTVISITOR_H #include "llvm/Function.h" +#include "llvm/Module.h" namespace llvm { - -class Module; // We operate on opaque instruction classes, so forward declare all instruction // types now... From lattner at cs.uiuc.edu Thu May 6 11:26:03 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu May 6 11:26:03 2004 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveIntervals.cpp RegAllocLinearScan.cpp Message-ID: <200405061626.LAA09211@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveIntervals.cpp updated: 1.71 -> 1.72 RegAllocLinearScan.cpp updated: 1.70 -> 1.71 --- Log message: numeric_limits::infinity() apparently does not work on all systems. As a workaround, use the C HUGE_VAL macro instead. --- Diffs of the changes: (+5 -7) Index: llvm/lib/CodeGen/LiveIntervals.cpp diff -u llvm/lib/CodeGen/LiveIntervals.cpp:1.71 llvm/lib/CodeGen/LiveIntervals.cpp:1.72 --- llvm/lib/CodeGen/LiveIntervals.cpp:1.71 Sat May 1 16:24:39 2004 +++ llvm/lib/CodeGen/LiveIntervals.cpp Thu May 6 11:25:59 2004 @@ -196,7 +196,7 @@ VirtRegMap& vrm, int slot) { - assert(li.weight != std::numeric_limits::infinity() && + assert(li.weight != HUGE_VAL && "attempt to spill already spilled interval!"); Interval::Ranges oldRanges; swap(oldRanges, li.ranges); @@ -253,7 +253,7 @@ } } // the new spill weight is now infinity as it cannot be spilled again - li.weight = std::numeric_limits::infinity(); + li.weight = HUGE_VAL; DEBUG(std::cerr << '\n'); DEBUG(std::cerr << "\t\t\t\tupdated interval: " << li << '\n'); } @@ -556,15 +556,13 @@ LiveIntervals::Interval::Interval(unsigned r) : reg(r), - weight((MRegisterInfo::isPhysicalRegister(r) ? - std::numeric_limits::infinity() : 0.0F)) + weight((MRegisterInfo::isPhysicalRegister(r) ? HUGE_VAL : 0.0F)) { - } bool LiveIntervals::Interval::spilled() const { - return (weight == std::numeric_limits::infinity() && + return (weight == HUGE_VAL && MRegisterInfo::isVirtualRegister(reg)); } Index: llvm/lib/CodeGen/RegAllocLinearScan.cpp diff -u llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.70 llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.71 --- llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.70 Tue Mar 16 18:48:59 2004 +++ llvm/lib/CodeGen/RegAllocLinearScan.cpp Thu May 6 11:25:59 2004 @@ -351,7 +351,7 @@ DEBUG(std::cerr << "\tassigning stack slot at interval "<< *cur << ":\n"); - float minWeight = std::numeric_limits::infinity(); + float minWeight = HUGE_VAL; unsigned minReg = 0; const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg); for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_); From brukman at cs.uiuc.edu Thu May 6 11:31:02 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu May 6 11:31:02 2004 Subject: [llvm-commits] [parallel] CVS: llvm/include/llvm/Analysis/ParallelInfo.h Message-ID: <200405061631.LAA10322@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: ParallelInfo.h updated: 1.1.2.3 -> 1.1.2.4 --- Log message: Add some iterators for the contained members. --- Diffs of the changes: (+22 -11) Index: llvm/include/llvm/Analysis/ParallelInfo.h diff -u llvm/include/llvm/Analysis/ParallelInfo.h:1.1.2.3 llvm/include/llvm/Analysis/ParallelInfo.h:1.1.2.4 --- llvm/include/llvm/Analysis/ParallelInfo.h:1.1.2.3 Fri Apr 16 11:35:12 2004 +++ llvm/include/llvm/Analysis/ParallelInfo.h Thu May 6 11:31:14 2004 @@ -30,10 +30,18 @@ /// class ParallelRegion { ParallelSeq *parent; - std::vector children; + std::vector Children; std::vector Blocks; public: + ParallelRegion(ParallelSeq *PS) : parent(PS) {} + ParallelRegion(BasicBlock *BB) : parent(0) { Blocks.push_back(BB); } + ParallelRegion() : parent(0) {} + ~ParallelRegion(); + + static ParallelRegion* discoverRegion(BasicBlock *pbrBlock, + BasicBlock *begin); + typedef std::vector::iterator iterator; typedef std::vector::const_iterator const_iterator; iterator begin() { return Blocks.begin(); } @@ -41,23 +49,23 @@ const_iterator const_begin() const { return Blocks.begin(); } const_iterator const_end() const { return Blocks.end(); } - ParallelRegion(ParallelSeq *PS) : parent(PS) {} - ParallelRegion(BasicBlock *BB) : parent(0) { Blocks.push_back(BB); } - ParallelRegion() : parent(0) {} - ~ParallelRegion(); + typedef std::vector::iterator seqiterator; + typedef std::vector::const_iterator const_seqiterator; + seqiterator seqbegin() { return Children.begin(); } + seqiterator seqend() { return Children.end(); } + const_seqiterator const_seqbegin() const { return Children.begin(); } + const_seqiterator const_seqend() const { return Children.end(); } - static ParallelRegion* discoverRegion(BasicBlock *pbrBlock, - BasicBlock *begin, BasicBlock *end); void addBasicBlock(BasicBlock *BB) { Blocks.push_back(BB); } void removeBasicBlock(BasicBlock *BB); bool contains(const BasicBlock *BB); void addChildSeq(ParallelSeq *PS); + std::vector &getBlocks() { return Blocks; } ParallelSeq *getParent() { return parent; } void print(std::ostream &os); void dump() { print(std::cerr); } - }; @@ -88,9 +96,12 @@ /// region_iterator/region_begin/region_end - Return the regions contained /// within this parallel sequence. /// - typedef std::vector::const_iterator region_iterator; - region_iterator region_begin() const { return Regions.begin(); } - region_iterator region_end() const { return Regions.end(); } + typedef std::vector::iterator riterator; + typedef std::vector::const_iterator const_riterator; + riterator rbegin() { return Regions.begin(); } + riterator rend() { return Regions.end(); } + const_riterator const_rbegin() const { return Regions.begin(); } + const_riterator const_rend() const { return Regions.end(); } /// getJoinBlocks - Return all of the join/synchronization blocks where the /// threads of this sequence become one again. From brukman at cs.uiuc.edu Thu May 6 11:32:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu May 6 11:32:01 2004 Subject: [llvm-commits] [parallel] CVS: llvm/test/Regression/Transforms/Parallel/20040429-ImplicitMultiplePbr.c Message-ID: <200405061632.LAA10372@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/Parallel: 20040429-ImplicitMultiplePbr.c added (r1.1.2.1) --- Log message: Test case for multiple parallel regions, which end up sharing code (thanks to tail duplication). --- Diffs of the changes: (+25 -0) Index: llvm/test/Regression/Transforms/Parallel/20040429-ImplicitMultiplePbr.c diff -c /dev/null llvm/test/Regression/Transforms/Parallel/20040429-ImplicitMultiplePbr.c:1.1.2.1 *** /dev/null Thu May 6 11:32:46 2004 --- llvm/test/Regression/Transforms/Parallel/20040429-ImplicitMultiplePbr.c Thu May 6 11:32:36 2004 *************** *** 0 **** --- 1,25 ---- + void* __llvm_pbr(void); + void __llvm_join(void*); + + void bar(void); + void baz(void); + void quux(void); + void quux2(void); + + void foo() { + void* p = __llvm_pbr(); + if (p) + bar(); + else + baz(); + __llvm_join(p); + + void *q = __llvm_pbr(); + if (q) + quux(); + else + quuux(); + + __llvm_join(q); + + } From brukman at cs.uiuc.edu Thu May 6 11:32:04 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu May 6 11:32:04 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/Analysis/ParallelInfo.cpp Message-ID: <200405061632.LAA10339@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: ParallelInfo.cpp updated: 1.1.2.2 -> 1.1.2.3 --- Log message: Pbr and join no longer need a static 1-to-1 mapping; we only require a 1-to-1 dynamic execution. --- Diffs of the changes: (+45 -35) Index: llvm/lib/Analysis/ParallelInfo.cpp diff -u llvm/lib/Analysis/ParallelInfo.cpp:1.1.2.2 llvm/lib/Analysis/ParallelInfo.cpp:1.1.2.3 --- llvm/lib/Analysis/ParallelInfo.cpp:1.1.2.2 Fri Apr 16 11:36:01 2004 +++ llvm/lib/Analysis/ParallelInfo.cpp Thu May 6 11:31:53 2004 @@ -14,6 +14,7 @@ //===----------------------------------------------------------------------===// #include "llvm/iOther.h" +#include "llvm/iPHINode.h" #include "llvm/iTerminators.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/ParallelInfo.h" @@ -34,13 +35,15 @@ // ParallelRegion::~ParallelRegion() { - for (std::vector::iterator i = children.begin(), - e = children.end(); i != e; ++i) + for (std::vector::iterator i = Children.begin(), + e = Children.end(); i != e; ++i) (*i)->setParent(0); + + // recursively destroy contained parallel sequences? } void ParallelRegion::addChildSeq(ParallelSeq *PS) { - children.push_back(PS); + Children.push_back(PS); PS->setParent(this); } @@ -56,14 +59,25 @@ } void ParallelRegion::print(std::ostream &os) { - for (const_iterator i = const_begin(), e = const_end(); i != e; ++i) { + for (const_iterator i = const_begin(), e = const_end(); i != e; ++i) os << (*i)->getName() << " "; - } +} + +static bool findPbr(Value *V, ParaBrInst *pbr) { + if (V == pbr) + return true; + else if (PHINode *phi = dyn_cast(V)) { + bool Found = false; + for (unsigned i = 0, e = phi->getNumIncomingValues(); i != e; ++i) + if (findPbr(phi->getIncomingValue(i), pbr)) + return true; + return false; + } else + return false; } ParallelRegion* ParallelRegion::discoverRegion(BasicBlock *pbrBlock, - BasicBlock *begin, - BasicBlock *end) { + BasicBlock *begin) { ParallelRegion *PR = new ParallelRegion(); // accumulate all the basic blocks in the subtree following to the first @@ -72,20 +86,33 @@ std::vector Worklist; DEBUG(std::cerr << "begin: " << begin->getName() << "\n"); Worklist.push_back(begin); + ParaBrInst *pbr = dyn_cast(pbrBlock->getTerminator()); while (!Worklist.empty()) { BasicBlock *BB = Worklist.back(); DEBUG(std::cerr << "processing: " << BB->getName() << "\n"); Worklist.pop_back(); - PR->addBasicBlock(BB); + // if this block contains a join to the pbr which we've begun from, then + // stop processing this block + bool done = false; + for (BasicBlock::iterator i = BB->begin(), e = BB->end(); i != e; ++i) + if (CallInst *CI = dyn_cast(i)) + if (CI->getCalledFunction()->getName() == "llvm.join" && + findPbr(CI->getOperand(1), pbr)) { + done = true; + break; + } + if (done) continue; + + PR->addBasicBlock(BB); TerminatorInst *TI = BB->getTerminator(); // Add all successors to the worklist if (BranchInst *BI = dyn_cast(TI)) { for (unsigned i = 0, e = BI->getNumSuccessors(); i != e; ++i) { BasicBlock *succ = BI->getSuccessor(i); DEBUG(std::cerr << "successor: " << succ->getName() << "\n"); - if (succ != pbrBlock && succ != end && !PR->contains(succ) && + if (succ != pbrBlock && !PR->contains(succ) && std::find(Worklist.begin(), Worklist.end(), succ) == Worklist.end()) Worklist.push_back(succ); } @@ -93,23 +120,17 @@ for (unsigned i = 0, e = SI->getNumCases(); i != e; ++i) { BasicBlock *succ = SI->getSuccessor(i); DEBUG(std::cerr << "successor: " << succ->getName() << "\n"); - if (succ != pbrBlock && succ != end && !PR->contains(succ) && + if (succ != pbrBlock && !PR->contains(succ) && std::find(Worklist.begin(), Worklist.end(), succ) == Worklist.end()) Worklist.push_back(succ); } } else if (ReturnInst *RI = dyn_cast(TI)) { assert(0 && "return not handled within parallel region"); } else if (ParaBrInst *PB = dyn_cast(TI)) { - Value::use_iterator pbrUser = PB->use_begin(); - assert(pbrUser != PB->use_end() && "pbr not closed by join()?"); - CallInst *CI = dyn_cast(*pbrUser); - assert(CI && "result of pbr used in a non-call instr"); - assert(CI->getCalledFunction()->getName() == "llvm.join" && - "result of pbr used in a call to something besides `llvm.join'"); - BasicBlock *pbrBB = PB->getParent(), *joinBB = CI->getParent(); + BasicBlock *pbrBB = PB->getParent(); ParallelSeq *PS = - new ParallelSeq(discoverRegion(pbrBB, PB->getSuccessor(0), joinBB), - discoverRegion(pbrBB, PB->getSuccessor(1), joinBB), + new ParallelSeq(discoverRegion(pbrBB, PB->getSuccessor(0)), + discoverRegion(pbrBB, PB->getSuccessor(1)), pbrBB); PR->addChildSeq(PS); } else { @@ -128,7 +149,7 @@ /// contains - Return true of the specified basic block is in this loop /// bool ParallelSeq::contains(const BasicBlock *BB) const { - for (region_iterator i = region_begin(), e = region_end(); i != e; ++i) + for (const_riterator i = const_rbegin(), e = const_rend(); i != e; ++i) if ((*i)->contains(BB)) return true; return false; @@ -138,9 +159,8 @@ unsigned region = 0; if (SeqHeader) os << "header: " << SeqHeader->getName() << "\n"; - for (region_iterator i = region_begin(), e = region_end(); i != e; - ++i, ++region) - { + for (const_riterator i = const_rbegin(), e = const_rend(); i != e; + ++i, ++region) { os << utostr(region) << " "; (*i)->print(os); os << "\n"; @@ -177,21 +197,11 @@ // process each successor tree separately into regions, and combine them // into a parallel sequence - - // The last instruction of the pbr BasicBlock is the pbr that spawned the - // regionStart, so find the join instruction correlated to it and hence the - // end basic block for the region. - Value::use_iterator join = PBr->use_begin(); - CallInst *call = dyn_cast(*join); - // FIXME: make sure the call is to "llvm.join" intrinsic - assert(call && "Value returned by pbr used in something not a call to join!"); - BasicBlock *end = call->getParent(); - ParallelRegion *PR0 = - ParallelRegion::discoverRegion(PBr->getParent(), PBr->getSuccessor(0), end); + ParallelRegion::discoverRegion(PBr->getParent(), PBr->getSuccessor(0)); DEBUG(std::cerr << "PR0: "; PR0->print(std::cerr); std::cerr << "\n";); ParallelRegion *PR1 = - ParallelRegion::discoverRegion(PBr->getParent(), PBr->getSuccessor(1), end); + ParallelRegion::discoverRegion(PBr->getParent(), PBr->getSuccessor(1)); DEBUG(std::cerr << "PR1: "; PR1->print(std::cerr); std::cerr << "\n";); // construct a parallel sequence From brukman at cs.uiuc.edu Thu May 6 11:34:03 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu May 6 11:34:03 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/Transforms/Parallel/PbrInjector.cpp Message-ID: <200405061634.LAA10404@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Parallel: PbrInjector.cpp updated: 1.1.2.1 -> 1.1.2.2 --- Log message: Convert all uses of __llvm_join to the llvm.join intrinsic, whether or not they immediately use the result of a pbr -- some uses may first go through a phi node... perhaps we may need a new phi-like node for merging parallel control flow. --- Diffs of the changes: (+29 -19) Index: llvm/lib/Transforms/Parallel/PbrInjector.cpp diff -u llvm/lib/Transforms/Parallel/PbrInjector.cpp:1.1.2.1 llvm/lib/Transforms/Parallel/PbrInjector.cpp:1.1.2.2 --- llvm/lib/Transforms/Parallel/PbrInjector.cpp:1.1.2.1 Fri Apr 23 11:55:13 2004 +++ llvm/lib/Transforms/Parallel/PbrInjector.cpp Thu May 6 11:34:00 2004 @@ -9,6 +9,14 @@ // // This pass converts hand-annotated parallel code regions to use `pbr' // +// Due to optimizations that run before this pass, at the end of it, there may +// be multiple calls to %llvm.join() for a given result of pbr. This is invalid +// LLVM pbr code, and a pass should run after it to `canonicalize' the usage of +// %llvm.join to push them down to a commonly-dominated block (creating it if +// necessary). +// +// This will be done by a subsequent pass, PbrCanonicalize. +// //===----------------------------------------------------------------------===// #include "llvm/DerivedTypes.h" @@ -47,7 +55,7 @@ for (std::vector::iterator u = Users.begin(), e = Users.end(); u != e; ++u) { // Check for the pattern as follows: - // %a = call int %__llvm_parallel() + // %a = call sbyte* %__llvm_pbr() // %b = seteq int %a, 0 // br %b, %label_1, %label_2 // @@ -62,38 +70,40 @@ new ParaBrInst(BI->getSuccessor(0), BI->getSuccessor(1), BB); // Before we erase the call, add a join instruction to match the `pbr' + CI->replaceAllUsesWith(pbr); // Delete condition and branch instructions BB->getInstList().erase(BI); BB->getInstList().erase(SCI); - - // Convert calls to __llvm_join(%x = __llvm_pbr()) to - // uses of the %llvm.join intrinsic - std::vector PbrCallUsers(CI->use_begin(), CI->use_end()); - for (std::vector::iterator cu = PbrCallUsers.begin(), - cue = PbrCallUsers.end(); cu != cue; ++cu) { - if (CallInst *CJ = dyn_cast(*cu)) { - if (CJ->getCalledFunction()->getName() == "__llvm_join") { - Function *Join = getJoinIntrinsic(F.getParent()); - new CallInst(Join, pbr, "", CJ); - CJ->getParent()->getInstList().erase(CJ); - } - } - } - BB->getInstList().erase(CI); - Changed = true; } } } } + Function *JoinFn = getJoinFunc(F.getParent()); + if (JoinFn->use_begin() == JoinFn->use_end()) + return Changed; + + std::vector JoinCalls(JoinFn->use_begin(), JoinFn->use_end()); + Function *Join = getJoinIntrinsic(F.getParent()); + for (std::vector::iterator u = JoinCalls.begin(), e = JoinCalls.end(); + u != e; ++u) { + // Convert calls to __llvm_join(%x = __llvm_pbr()) to + // uses of the %llvm.join intrinsic + if (CallInst *CJ = dyn_cast(*u)) { + if (CJ->getCalledFunction() == JoinFn) { + new CallInst(Join, CJ->getOperand(1), "", CJ); + CJ->getParent()->getInstList().erase(CJ); + } + } + } + return Changed; } -/// getParallelizer - find the function in the Module that marks parallel -/// regions +/// getPbrFunc - find the function in the Module that marks parallel regions /// Function* Parallelize::getPbrFunc(Module *M) { return M->getOrInsertFunction("__llvm_pbr", PointerType::get(Type::SByteTy), From brukman at cs.uiuc.edu Thu May 6 11:35:03 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu May 6 11:35:03 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/Transforms/Parallel/BreakJoinBlocks.cpp Message-ID: <200405061635.LAA10449@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Parallel: BreakJoinBlocks.cpp added (r1.1.2.1) --- Log message: Break basic blocks at the calls to llvm.join so that they are not extract with the parallel regions -- we need the join to be on the outside! --- Diffs of the changes: (+65 -0) Index: llvm/lib/Transforms/Parallel/BreakJoinBlocks.cpp diff -c /dev/null llvm/lib/Transforms/Parallel/BreakJoinBlocks.cpp:1.1.2.1 *** /dev/null Thu May 6 11:35:08 2004 --- llvm/lib/Transforms/Parallel/BreakJoinBlocks.cpp Thu May 6 11:34:58 2004 *************** *** 0 **** --- 1,65 ---- + //===- BreakJoinBlocks.cpp - Break blocks at calls to join ----------===// + // + // 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. + // + //===----------------------------------------------------------------------===// + // + // + // + //===----------------------------------------------------------------------===// + + #include "llvm/iOther.h" + #include "llvm/Function.h" + #include "llvm/BasicBlock.h" + #include "llvm/Pass.h" + #include "llvm/Transforms/Utils/FunctionUtils.h" + using namespace llvm; + + namespace { + + /// BreakJoin - + /// + struct BreakJoin : public FunctionPass { + public: + BreakJoin() {} + bool runOnFunction(Function &F); + private: + CallInst *findJoin(BasicBlock *BB); + }; + + RegisterOpt X("break-joins", "Break BasicBlocks at joins"); + + } // End anonymous namespace + + bool BreakJoin::runOnFunction(Function &F) { + bool Changed = false; + std::vector Worklist; + for (Function::iterator i = F.begin(), e = F.end(); i != e; ++i) + Worklist.push_back(i); + + while (!Worklist.empty()) { + BasicBlock *BB = Worklist.back(); + Worklist.pop_back(); + if (CallInst *CI = findJoin(BB)) { + BasicBlock::iterator II(CI); + if (II != BB->begin()) { + BasicBlock *newBB = BB->splitBasicBlock(II, BB->getName() + "_split"); + if (newBB) Worklist.push_back(newBB); + } + } + } + + return Changed; + } + + CallInst* BreakJoin::findJoin(BasicBlock *BB) { + for (BasicBlock::iterator i = BB->begin(), e = BB->end(); i != e; ++i) + if (CallInst *CI = dyn_cast(i)) + if (CI->getCalledFunction()->getName() == "llvm.join") + return CI; + + return 0; + } From brukman at cs.uiuc.edu Thu May 6 11:53:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu May 6 11:53:01 2004 Subject: [llvm-commits] CVS: llvm/CREDITS.TXT Message-ID: <200405061653.LAA10541@zion.cs.uiuc.edu> Changes in directory llvm: CREDITS.TXT updated: 1.8 -> 1.9 --- Log message: Give props to Vladimir Prus for the inst_iterator patch. --- Diffs of the changes: (+4 -0) Index: llvm/CREDITS.TXT diff -u llvm/CREDITS.TXT:1.8 llvm/CREDITS.TXT:1.9 --- llvm/CREDITS.TXT:1.8 Wed Dec 17 12:15:04 2003 +++ llvm/CREDITS.TXT Thu May 6 11:53:18 2004 @@ -45,6 +45,10 @@ W: http://nondot.org/~sabre/ D: Primary architect of LLVM +N: Vladimir Prus +E: ghost at cs.msu.su +D: Made inst_iterator behave like a proper iterator + N: Ruchira Sasanka E: sasanka at uiuc.edu D: Graph coloring register allocator for the Sparc64 backend From lattner at cs.uiuc.edu Thu May 6 12:27:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu May 6 12:27:02 2004 Subject: [llvm-commits] CVS: llvm-www/header.incl Message-ID: <200405061726.MAA11243@zion.cs.uiuc.edu> Changes in directory llvm-www: header.incl updated: 1.15 -> 1.16 --- Log message: Add new status update --- Diffs of the changes: (+1 -0) Index: llvm-www/header.incl diff -u llvm-www/header.incl:1.15 llvm-www/header.incl:1.16 --- llvm-www/header.incl:1.15 Fri Mar 19 22:58:34 2004 +++ llvm-www/header.incl Thu May 6 12:26:07 2004 @@ -49,6 +49,7 @@ Status Updates
    + May 6, 2004
    March 19, 2004
    February 6, 2004
    December 17, 2003
    From llvm at cs.uiuc.edu Thu May 6 13:10:07 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Thu May 6 13:10:07 2004 Subject: [llvm-commits] CVS: llvm/CREDITS.TXT Message-ID: <200405061806.NAA13640@zion.cs.uiuc.edu> Changes in directory llvm: CREDITS.TXT updated: 1.9 -> 1.10 --- Log message: Just testing the "Reid has CVS commit access" system --- Diffs of the changes: (+1 -1) Index: llvm/CREDITS.TXT diff -u llvm/CREDITS.TXT:1.9 llvm/CREDITS.TXT:1.10 --- llvm/CREDITS.TXT:1.9 Thu May 6 11:53:18 2004 +++ llvm/CREDITS.TXT Thu May 6 13:06:18 2004 @@ -60,7 +60,7 @@ N: Reid Spencer E: rspencer at x10sys.com W: http://extprosys.sourceforge.net/ -D: Complete 'llvm' namespacification, Stacker, bug fixes, and improvements +D: Complete 'llvm' namespacification, Stacker, bug fixes, and other improvements N: Bill Wendling E: wendling at isanbard.org From lattner at cs.uiuc.edu Thu May 6 14:30:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu May 6 14:30:01 2004 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/ExecutionDriver.cpp Message-ID: <200405061930.OAA15559@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: ExecutionDriver.cpp updated: 1.41 -> 1.42 --- Log message: Remove a really old comment --- Diffs of the changes: (+0 -9) Index: llvm/tools/bugpoint/ExecutionDriver.cpp diff -u llvm/tools/bugpoint/ExecutionDriver.cpp:1.41 llvm/tools/bugpoint/ExecutionDriver.cpp:1.42 --- llvm/tools/bugpoint/ExecutionDriver.cpp:1.41 Tue May 4 16:09:16 2004 +++ llvm/tools/bugpoint/ExecutionDriver.cpp Thu May 6 14:29:58 2004 @@ -12,15 +12,6 @@ // //===----------------------------------------------------------------------===// -/* -BUGPOINT NOTES: - -1. Bugpoint should not leave any files behind if the program works properly -2. There should be an option to specify the program name, which specifies a - unique string to put into output files. This allows operation in the - SingleSource directory, e.g. default to the first input filename. -*/ - #include "BugDriver.h" #include "llvm/Support/ToolRunner.h" #include "Support/CommandLine.h" From criswell at cs.uiuc.edu Thu May 6 16:19:02 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu May 6 16:19:02 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/iMemory.cpp Message-ID: <200405062118.QAA16769@choi.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: iMemory.cpp updated: 1.36 -> 1.37 --- Log message: Fix for PR#330. When looking at getelementptr instructions, make sure to use a forwarded type. We want to do this because a DerivedType may drop its uses and then refine its users, who may then use another user who hasn't been refined yet. By getting the forwarded type, we always ensure that we're looking at a Type that isn't in a halfway refined state. Now, I should be able to put this stuff in PATypeHandle, but it doesn't work for some reason. This should do for now. --- Diffs of the changes: (+8 -0) Index: llvm/lib/VMCore/iMemory.cpp diff -u llvm/lib/VMCore/iMemory.cpp:1.36 llvm/lib/VMCore/iMemory.cpp:1.37 --- llvm/lib/VMCore/iMemory.cpp:1.36 Sun Apr 4 20:30:19 2004 +++ llvm/lib/VMCore/iMemory.cpp Thu May 6 16:18:08 2004 @@ -156,6 +156,14 @@ return 0; // Can only index into pointer types at the first index! if (!CT->indexValid(Index)) return 0; Ptr = CT->getTypeAtIndex(Index); + + // If the new type forwards to another type, then it is in the middle + // of being refined to another type (and hence, may have dropped all + // references to what it was using before). So, use the new forwarded + // type. + if (Ptr->getForwardedType()) { + Ptr = Ptr->getForwardedType(); + } } return CurIdx == Idx.size() ? Ptr : 0; } From gaeke at cs.uiuc.edu Thu May 6 16:48:03 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu May 6 16:48:03 2004 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/Makefile TraceToFunction.h Message-ID: <200405062148.QAA30406@zion.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: Makefile updated: 1.5 -> 1.6 TraceToFunction.h updated: 1.9 -> 1.10 --- Log message: Make this directory compile on PPC. --- Diffs of the changes: (+2 -2) Index: reopt/lib/LightWtProfiling/Makefile diff -u reopt/lib/LightWtProfiling/Makefile:1.5 reopt/lib/LightWtProfiling/Makefile:1.6 --- reopt/lib/LightWtProfiling/Makefile:1.5 Wed Apr 28 12:27:36 2004 +++ reopt/lib/LightWtProfiling/Makefile Thu May 6 16:47:49 2004 @@ -5,7 +5,7 @@ include $(LEVEL)/Makefile.config ifneq ($(ARCH),Sparc) -Source := Initialization.cpp RuntimeOptimizations.cpp SLI.cpp Trace.cpp TraceOptEmitter.cpp TraceToFunction.cpp UnpackTraceFunction.cpp scheduler.cpp +Source := Initialization.cpp RuntimeOptimizations.cpp SLI.cpp Trace.cpp TraceOptEmitter.cpp TraceToFunction.cpp UnpackTraceFunction.cpp all :: @echo "This code assumes an LP64 machine- please ignore ptr cast warnings!" endif Index: reopt/lib/LightWtProfiling/TraceToFunction.h diff -u reopt/lib/LightWtProfiling/TraceToFunction.h:1.9 reopt/lib/LightWtProfiling/TraceToFunction.h:1.10 --- reopt/lib/LightWtProfiling/TraceToFunction.h:1.9 Fri Apr 9 13:03:23 2004 +++ reopt/lib/LightWtProfiling/TraceToFunction.h Thu May 6 16:47:49 2004 @@ -57,7 +57,7 @@ /// live variable sets. If you want those, use TraceFunction::get () /// instead, which performs all the expensive transformations. /// - TraceFunction (Trace &_T) : MatrixFn (_T.getFunction ()), T (_T) { } + TraceFunction (Trace &T_) : MatrixFn (T_.getFunction ()), T (T_) { } /// Returns a filled-in TraceFunction object with a TraceFn for T, /// along with its Live-In and Live-Out variable sets. From lattner at cs.uiuc.edu Thu May 6 17:04:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu May 6 17:04:02 2004 Subject: [llvm-commits] CVS: llvm/lib/Support/CommandLine.cpp Message-ID: <200405062204.RAA00588@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: CommandLine.cpp updated: 1.43 -> 1.44 --- Log message: Implement the new cl::PositionalEatsArgs flag, refactor code a bit --- Diffs of the changes: (+66 -53) Index: llvm/lib/Support/CommandLine.cpp diff -u llvm/lib/Support/CommandLine.cpp:1.43 llvm/lib/Support/CommandLine.cpp:1.44 --- llvm/lib/Support/CommandLine.cpp:1.43 Thu Mar 4 11:50:44 2004 +++ llvm/lib/Support/CommandLine.cpp Thu May 6 17:04:31 2004 @@ -213,11 +213,11 @@ /// from the caller (as PROGNAME) and its command-line arguments from /// an environment variable (whose name is given in ENVVAR). /// -void cl::ParseEnvironmentOptions (const char *progName, const char *envVar, - const char *Overview) { +void cl::ParseEnvironmentOptions(const char *progName, const char *envVar, + const char *Overview) { // Check args. - assert (progName && "Program name not specified"); - assert (envVar && "Environment variable name missing"); + assert(progName && "Program name not specified"); + assert(envVar && "Environment variable name missing"); // Get the environment variable they want us to parse options out of. const char *envValue = getenv (envVar); @@ -242,6 +242,29 @@ } } +/// LookupOption - Lookup the option specified by the specified option on the +/// command line. If there is a value specified (after an equal sign) return +/// that as well. +static Option *LookupOption(const char *&Arg, const char *&Value) { + while (*Arg == '-') ++Arg; // Eat leading dashes + + const char *ArgEnd = Arg; + while (*ArgEnd && *ArgEnd != '=') + ++ArgEnd; // Scan till end of argument name... + + Value = ArgEnd; + if (*Value) // If we have an equals sign... + ++Value; // Advance to value... + + if (*Arg == 0) return 0; + + // Look up the option. + std::map &Opts = getOpts(); + std::map::iterator I = + Opts.find(std::string(Arg, ArgEnd)); + return (I != Opts.end()) ? I->second : 0; +} + void cl::ParseCommandLineOptions(int &argc, char **argv, const char *Overview) { assert((!getOpts().empty() || !getPositionalOpts().empty()) && @@ -335,78 +358,68 @@ // Delay processing positional arguments until the end... continue; } - } else { // We start with a '-', must be an argument... + } else if (argv[i][0] == '-' && argv[i][1] == '-' && argv[i][2] == 0 && + !DashDashFound) { + DashDashFound = true; // This is the mythical "--"? + continue; // Don't try to process it as an argument itself. + } else if (ActivePositionalArg && + (ActivePositionalArg->getMiscFlags() & PositionalEatsArgs)) { + // If there is a positional argument eating options, check to see if this + // option is another positional argument. If so, treat it as an argument, + // otherwise feed it to the eating positional. ArgName = argv[i]+1; - while (*ArgName == '-') ++ArgName; // Eat leading dashes - - if (*ArgName == 0 && !DashDashFound) { // Is this the mythical "--"? - DashDashFound = true; // Yup, take note of that fact... - continue; // Don't try to process it as an argument itself. + Handler = LookupOption(ArgName, Value); + if (!Handler || Handler->getFormattingFlag() != cl::Positional) { + ProvidePositionalOption(ActivePositionalArg, argv[i]); + continue; // We are done! } - const char *ArgNameEnd = ArgName; - while (*ArgNameEnd && *ArgNameEnd != '=') - ++ArgNameEnd; // Scan till end of argument name... - - Value = ArgNameEnd; - if (*Value) // If we have an equals sign... - ++Value; // Advance to value... - - if (*ArgName != 0) { - std::string RealName(ArgName, ArgNameEnd); - // Extract arg name part - std::map::iterator I = Opts.find(RealName); - - if (I == Opts.end() && !*Value && RealName.size() > 1) { - // Check to see if this "option" is really a prefixed or grouped - // argument... - // + } else { // We start with a '-', must be an argument... + ArgName = argv[i]+1; + Handler = LookupOption(ArgName, Value); + + // Check to see if this "option" is really a prefixed or grouped argument. + if (Handler == 0 && *Value == 0) { + std::string RealName(ArgName); + if (RealName.size() > 1) { unsigned Length = 0; Option *PGOpt = getOptionPred(RealName, Length, isPrefixedOrGrouping); - + // If the option is a prefixed option, then the value is simply the // rest of the name... so fall through to later processing, by // setting up the argument name flags and value fields. // if (PGOpt && PGOpt->getFormattingFlag() == cl::Prefix) { - ArgNameEnd = ArgName+Length; - Value = ArgNameEnd; - I = Opts.find(std::string(ArgName, ArgNameEnd)); - assert(I->second == PGOpt); + Value = ArgName+Length; + assert(Opts.find(std::string(ArgName, Value)) != Opts.end() && + Opts.find(std::string(ArgName, Value))->second == PGOpt); + Handler = PGOpt; } else if (PGOpt) { - // This must be a grouped option... handle all of them now... + // This must be a grouped option... handle them now. assert(isGrouping(PGOpt) && "Broken getOptionPred!"); - + do { // Move current arg name out of RealName into RealArgName... - std::string RealArgName(RealName.begin(),RealName.begin()+Length); - RealName.erase(RealName.begin(), RealName.begin()+Length); - + std::string RealArgName(RealName.begin(), + RealName.begin() + Length); + RealName.erase(RealName.begin(), RealName.begin() + Length); + // Because ValueRequired is an invalid flag for grouped arguments, // we don't need to pass argc/argv in... // assert(PGOpt->getValueExpectedFlag() != cl::ValueRequired && "Option can not be cl::Grouping AND cl::ValueRequired!"); int Dummy; - ErrorParsing |= ProvideOption(PGOpt, RealArgName.c_str(), "", - 0, 0, Dummy); - + ErrorParsing |= ProvideOption(PGOpt, RealArgName.c_str(), + "", 0, 0, Dummy); + // Get the next grouping option... - if (!RealName.empty()) - PGOpt = getOptionPred(RealName, Length, isGrouping); - } while (!RealName.empty() && PGOpt); - - if (RealName.empty()) // Processed all of the options, move on - continue; // to the next argv[] value... - - // If RealName is not empty, that means we did not match one of the - // options! This is an error. - // - I = Opts.end(); + PGOpt = getOptionPred(RealName, Length, isGrouping); + } while (PGOpt && Length != RealName.size()); + + Handler = PGOpt; // Ate all of the options. } } - - Handler = I != Opts.end() ? I->second : 0; } } From lattner at cs.uiuc.edu Thu May 6 17:04:08 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu May 6 17:04:08 2004 Subject: [llvm-commits] CVS: llvm/docs/CommandLine.html Message-ID: <200405062204.RAA00571@zion.cs.uiuc.edu> Changes in directory llvm/docs: CommandLine.html updated: 1.19 -> 1.20 --- Log message: Add a new cl::PositionalEatsArgs flag --- Diffs of the changes: (+15 -5) Index: llvm/docs/CommandLine.html diff -u llvm/docs/CommandLine.html:1.19 llvm/docs/CommandLine.html:1.20 --- llvm/docs/CommandLine.html:1.19 Fri Nov 7 13:42:44 2003 +++ llvm/docs/CommandLine.html Thu May 6 17:03:59 2004 @@ -870,13 +870,14 @@

    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 specified, there must not be any cl::list +positional arguments, and the cl::ConsumeAfter option should be a cl::list option.

    -
    + @@ -1283,10 +1284,19 @@ makes sense to be used in a case where the option is allowed to accept one or more values (i.e. it is a cl::list option). +
  • The +cl::PositionalEatsArgs modifier (which only applies to +positional arguments, and only makes sense for lists) indicates that positional +argument should consume any strings after it (including strings that start with +a "-") up until another recognized positional argument. For example, if you +have two "eating" positional arguments "pos1" and "pos2" the +string "-pos1 -foo -bar baz -pos2 -bork" would cause the "-foo -bar +-baz" strings to be applied to the "-pos1" option and the +"-bork" string to be applied to the "-pos2" option.
  • + -

    So far, the only miscellaneous option modifier is the -cl::CommaSeparated modifier.

    +

    So far, these are the only two miscellaneous option modifiers.

    @@ -1692,7 +1702,7 @@
    Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2003/11/07 19:42:44 $ + Last modified: $Date: 2004/05/06 22:03:59 $ From lattner at cs.uiuc.edu Thu May 6 17:05:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu May 6 17:05:01 2004 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/ExecutionDriver.cpp Message-ID: <200405062205.RAA00598@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: ExecutionDriver.cpp updated: 1.42 -> 1.43 --- Log message: Use the new commandline flag to allow us to call bugpoint like this: bugpoint ... --tool-args -enable-correct-eh-support -regalloc=linearscan --args -- -foo So that tool-args option gets the -enable-correct-eh-support -regalloc=linearscan flags instead of bugpoint. --- Diffs of the changes: (+2 -2) Index: llvm/tools/bugpoint/ExecutionDriver.cpp diff -u llvm/tools/bugpoint/ExecutionDriver.cpp:1.42 llvm/tools/bugpoint/ExecutionDriver.cpp:1.43 --- llvm/tools/bugpoint/ExecutionDriver.cpp:1.42 Thu May 6 14:29:58 2004 +++ llvm/tools/bugpoint/ExecutionDriver.cpp Thu May 6 17:05:35 2004 @@ -61,11 +61,11 @@ // program being debugged. cl::list InputArgv("args", cl::Positional, cl::desc("..."), - cl::ZeroOrMore); + cl::ZeroOrMore, cl::PositionalEatsArgs); cl::list ToolArgv("tool-args", cl::Positional, cl::desc("..."), - cl::ZeroOrMore); + cl::ZeroOrMore, cl::PositionalEatsArgs); } //===----------------------------------------------------------------------===// From lattner at cs.uiuc.edu Thu May 6 17:07:07 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu May 6 17:07:07 2004 Subject: [llvm-commits] CVS: llvm/test/Programs/Makefile.programs Message-ID: <200405062206.RAA00669@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs: Makefile.programs updated: 1.129 -> 1.130 --- Log message: Pass the -enable-correct-eh-support flag into bugpoint, and implement a new bugpoint-llc-ls target. Thanks to Brian for adding the bugpoint features required to do this :) --- Diffs of the changes: (+10 -5) Index: llvm/test/Programs/Makefile.programs diff -u llvm/test/Programs/Makefile.programs:1.129 llvm/test/Programs/Makefile.programs:1.130 --- llvm/test/Programs/Makefile.programs:1.129 Fri Apr 23 14:22:21 2004 +++ llvm/test/Programs/Makefile.programs Thu May 6 17:06:43 2004 @@ -373,26 +373,31 @@ # Specify stdin, reference output, and command line options for the program... BUGPOINT_OPTIONS += -input=$(STDIN_FILENAME) -output=Output/$*.out-nat -BUGPOINT_OPTIONS += --args -- $(RUN_OPTIONS) +BUGPOINT_OPTIONS += --tool-args $(LLCFLAGS) +BUGPOINT_ARGS += --args -- $(RUN_OPTIONS) # Rules to bugpoint the GCCAS, GCCLD, LLC, or LLI commands... $(PROGRAMS_TO_TEST:%=Output/%.bugpoint-gccas): \ Output/%.bugpoint-gccas: Output/%.noopt-llvm.bc $(LBUGPOINT) \ Output/gccas-pass-args Output/%.out-nat - $(LBUGPOINT) $< `cat Output/gccas-pass-args` $(BUGPOINT_OPTIONS) + $(LBUGPOINT) $< `cat Output/gccas-pass-args` $(BUGPOINT_OPTIONS) $(BUGPOINT_ARGS) $(PROGRAMS_TO_TEST:%=Output/%.bugpoint-gccld): \ Output/%.bugpoint-gccld: Output/%.nogccldopt-llvm.bc $(LBUGPOINT) \ Output/gccld-pass-args Output/%.out-nat - $(LBUGPOINT) $< `cat Output/gccld-pass-args` $(OPTPASSES) $(BUGPOINT_OPTIONS) + $(LBUGPOINT) $< `cat Output/gccld-pass-args` $(OPTPASSES) $(BUGPOINT_OPTIONS) $(BUGPOINT_ARGS) $(PROGRAMS_TO_TEST:%=Output/%.bugpoint-llc): \ Output/%.bugpoint-llc: Output/%.llvm.bc $(LBUGPOINT) Output/%.out-nat - $(LBUGPOINT) $< -run-llc $(BUGPOINT_OPTIONS) + $(LBUGPOINT) $< -run-llc $(BUGPOINT_OPTIONS) $(BUGPOINT_ARGS) + +$(PROGRAMS_TO_TEST:%=Output/%.bugpoint-llc-ls): \ +Output/%.bugpoint-llc-ls: Output/%.llvm.bc $(LBUGPOINT) Output/%.out-nat + $(LBUGPOINT) $< -run-llc $(BUGPOINT_OPTIONS) -regalloc=linearscan $(BUGPOINT_ARGS) $(PROGRAMS_TO_TEST:%=Output/%.bugpoint-jit): \ Output/%.bugpoint-jit: Output/%.llvm.bc $(LBUGPOINT) Output/%.out-nat - $(LBUGPOINT) $< -run-jit $(BUGPOINT_OPTIONS) + $(LBUGPOINT) $< -run-jit $(BUGPOINT_OPTIONS) $(BUGPOINT_ARGS) LIBPROFILESO = $(LEVEL)/lib/Debug/libprofile_rt.so From criswell at cs.uiuc.edu Thu May 6 17:17:04 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu May 6 17:17:04 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/iMemory.cpp Message-ID: <200405062215.RAA19569@choi.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: iMemory.cpp updated: 1.37 -> 1.38 --- Log message: Don't call getForwardedType() twice, as recommended by Chris. --- Diffs of the changes: (+2 -2) Index: llvm/lib/VMCore/iMemory.cpp diff -u llvm/lib/VMCore/iMemory.cpp:1.37 llvm/lib/VMCore/iMemory.cpp:1.38 --- llvm/lib/VMCore/iMemory.cpp:1.37 Thu May 6 16:18:08 2004 +++ llvm/lib/VMCore/iMemory.cpp Thu May 6 17:15:47 2004 @@ -161,8 +161,8 @@ // of being refined to another type (and hence, may have dropped all // references to what it was using before). So, use the new forwarded // type. - if (Ptr->getForwardedType()) { - Ptr = Ptr->getForwardedType(); + if (const Type * Ty = Ptr->getForwardedType()) { + Ptr = Ty; } } return CurIdx == Idx.size() ? Ptr : 0; From criswell at cs.uiuc.edu Thu May 6 17:24:02 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu May 6 17:24:02 2004 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200405062223.RAA19768@choi.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.172 -> 1.173 --- Log message: Bug fixed. --- Diffs of the changes: (+3 -1) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.172 llvm/docs/ReleaseNotes.html:1.173 --- llvm/docs/ReleaseNotes.html:1.172 Tue May 4 16:22:57 2004 +++ llvm/docs/ReleaseNotes.html Thu May 6 17:23:24 2004 @@ -196,6 +196,8 @@

    Bugs in the LLVM Core:

      +
    1. [vmcore] Linker causes erroneous +asssertion
    2. [loopsimplify] Loop simplify incorrectly updates dominator information
    3. [tailduplicate] DemoteRegToStack @@ -633,7 +635,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
      - Last modified: $Date: 2004/05/04 21:22:57 $ + Last modified: $Date: 2004/05/06 22:23:24 $ From lattner at cs.uiuc.edu Thu May 6 21:27:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu May 6 21:27:01 2004 Subject: [llvm-commits] CVS: llvm/include/Support/CommandLine.h Message-ID: <200405070227.VAA07869@zion.cs.uiuc.edu> Changes in directory llvm/include/Support: CommandLine.h updated: 1.30 -> 1.31 --- Log message: Add the enum corresponding to the source change I made earlier --- Diffs of the changes: (+3 -2) Index: llvm/include/Support/CommandLine.h diff -u llvm/include/Support/CommandLine.h:1.30 llvm/include/Support/CommandLine.h:1.31 --- llvm/include/Support/CommandLine.h:1.30 Mon Feb 23 21:50:05 2004 +++ llvm/include/Support/CommandLine.h Thu May 6 21:27:32 2004 @@ -107,8 +107,9 @@ }; enum MiscFlags { // Miscellaneous flags to adjust argument - CommaSeparated = 0x200, // Should this cl::list split between commas? - MiscMask = 0x200, + CommaSeparated = 0x200, // Should this cl::list split between commas? + PositionalEatsArgs = 0x400, // Should this positional cl::list eat -args? + MiscMask = 0x600, }; From criswell at cs.uiuc.edu Fri May 7 08:37:01 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri May 7 08:37:01 2004 Subject: [llvm-commits] CVS: llvm-www/releases/1.2/docs/ReleaseNotes.html Message-ID: <200405071336.IAA10660@choi.cs.uiuc.edu> Changes in directory llvm-www/releases/1.2/docs: ReleaseNotes.html updated: 1.13 -> 1.14 --- Log message: Bug found (although the symptoms differ from that found in the original CVS trunk bug). --- Diffs of the changes: (+3 -1) Index: llvm-www/releases/1.2/docs/ReleaseNotes.html diff -u llvm-www/releases/1.2/docs/ReleaseNotes.html:1.13 llvm-www/releases/1.2/docs/ReleaseNotes.html:1.14 --- llvm-www/releases/1.2/docs/ReleaseNotes.html:1.13 Tue May 4 16:24:32 2004 +++ llvm-www/releases/1.2/docs/ReleaseNotes.html Fri May 7 08:36:12 2004 @@ -354,6 +354,8 @@
    4. [tailduplicate] DemoteRegToStack breaks SSA form
    5. [adce] Crash handling unreachable code that unwinds
    6. + +
    7. [vmcore] Linker causes erroneous asssertion
    8. @@ -679,7 +681,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
      - Last modified: $Date: 2004/05/04 21:24:32 $ + Last modified: $Date: 2004/05/07 13:36:12 $ From criswell at cs.uiuc.edu Fri May 7 08:58:01 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri May 7 08:58:01 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/Linker/2004-05-07-TypeResolution1.ll 2004-05-07-TypeResolution2.ll Message-ID: <200405071357.IAA12388@choi.cs.uiuc.edu> Changes in directory llvm/test/Regression/Linker: 2004-05-07-TypeResolution1.ll added (r1.1) 2004-05-07-TypeResolution2.ll added (r1.1) --- Log message: Regression test for PR#330. --- Diffs of the changes: (+69 -0) Index: llvm/test/Regression/Linker/2004-05-07-TypeResolution1.ll diff -c /dev/null llvm/test/Regression/Linker/2004-05-07-TypeResolution1.ll:1.1 *** /dev/null Fri May 7 08:57:29 2004 --- llvm/test/Regression/Linker/2004-05-07-TypeResolution1.ll Fri May 7 08:57:19 2004 *************** *** 0 **** --- 1,44 ---- + ; RUN: llvm-as -f < %s > %t1.bc + ; RUN: llvm-as -f < `dirname %s`/2004-05-07-TypeResolution2.ll > %t2.bc + ; RUN: llvm-link -f -o %t3.bc %t1.bc %t2.bc + + target endian = little + target pointersize = 32 + + %myint = type opaque + %struct2 = type { %struct1 } + + %struct1 = type { int, void (%struct2*)*, %myint *, int (uint *)* } + + + %driver1 = global %struct1 zeroinitializer ; <%struct1*> [#uses=1] + + %m1 = external global [1 x sbyte] * ; <%struct.task_struct**> [#uses=0] + ;%m1 = external global uint ; <%struct.task_struct**> [#uses=0] + %str1 = constant [1 x ubyte] zeroinitializer + %str2 = constant [2 x ubyte] zeroinitializer + %str3 = constant [3 x ubyte] zeroinitializer + %str4 = constant [4 x ubyte] zeroinitializer + %str5 = constant [5 x ubyte] zeroinitializer + %str6 = constant [6 x ubyte] zeroinitializer + %str7 = constant [7 x ubyte] zeroinitializer + %str8 = constant [8 x ubyte] zeroinitializer + %str9 = constant [9 x ubyte] zeroinitializer + %stra = constant [10 x ubyte] zeroinitializer + %strb = constant [11 x ubyte] zeroinitializer + %strc = constant [12 x ubyte] zeroinitializer + %strd = constant [13 x ubyte] zeroinitializer + %stre = constant [14 x ubyte] zeroinitializer + %strf = constant [15 x ubyte] zeroinitializer + %strg = constant [16 x ubyte] zeroinitializer + %strh = constant [17 x ubyte] zeroinitializer + + implementation ; Functions: + + declare void %func(%struct2*) + + void %tty_init() { + entry: + volatile store void (%struct2*)* %func, void (%struct2 *)** getelementptr (%struct1* %driver1, uint 0, uint 1) + ret void + } Index: llvm/test/Regression/Linker/2004-05-07-TypeResolution2.ll diff -c /dev/null llvm/test/Regression/Linker/2004-05-07-TypeResolution2.ll:1.1 *** /dev/null Fri May 7 08:57:29 2004 --- llvm/test/Regression/Linker/2004-05-07-TypeResolution2.ll Fri May 7 08:57:19 2004 *************** *** 0 **** --- 1,25 ---- + ; This file is used by testlink1.ll, so it doesn't actually do anything itself + ; + ; RUN: echo + + target endian = little + target pointersize = 32 + + %myint = type ushort + %struct2 = type { %struct1 } + %struct1 = type { int, void (%struct2*)*, %myint *, int (uint *)* } + + implementation ; Functions: + + internal void %f1 (%struct1* %tty) { + loopentry.preheader: + + ; [#uses=1] + ; [#uses=0] + + %tmp.2.i.i = getelementptr %struct1* %tty, uint 0, uint 1 + %tmp.3.i.i = volatile load void (%struct2*)** %tmp.2.i.i + + ret void + } + From lattner at cs.uiuc.edu Fri May 7 10:36:04 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri May 7 10:36:04 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200405071536.KAA07311@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.198 -> 1.199 --- Log message: Fix PR336: http://llvm.cs.uiuc.edu/PR336 : The instcombine pass asserts when visiting load instruction --- Diffs of the changes: (+3 -2) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.198 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.199 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.198 Tue May 4 10:19:33 2004 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Fri May 7 10:35:56 2004 @@ -887,7 +887,7 @@ // if so, convert to a bitwise and. if (ConstantUInt *C = dyn_cast(RHS)) if (uint64_t Val = C->getValue()) // Don't break X % 0 (divide by zero) - if (!(Val & Val-1)) // Power of 2 + if (!(Val & (Val-1))) // Power of 2 return BinaryOperator::create(Instruction::And, I.getOperand(0), ConstantUInt::get(I.getType(), Val-1)); } @@ -2869,7 +2869,8 @@ if (const PointerType *SrcTy = dyn_cast(CI->getOperand(0)->getType())) { const Type *SrcPTy = SrcTy->getElementType(); - if (TD->getTypeSize(SrcPTy) == TD->getTypeSize(DestPTy) && + if (SrcPTy->isSized() && DestPTy->isSized() && + TD->getTypeSize(SrcPTy) == TD->getTypeSize(DestPTy) && (SrcPTy->isInteger() || isa(SrcPTy)) && (DestPTy->isInteger() || isa(DestPTy))) { // Okay, we are casting from one integer or pointer type to another of From lattner at cs.uiuc.edu Fri May 7 10:39:05 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri May 7 10:39:05 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/2004-05-07-UnsizedCastLoad.ll Message-ID: <200405071539.KAA07353@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: 2004-05-07-UnsizedCastLoad.ll added (r1.1) --- Log message: New testcase for PR336: http://llvm.cs.uiuc.edu/PR336 --- Diffs of the changes: (+9 -0) Index: llvm/test/Regression/Transforms/InstCombine/2004-05-07-UnsizedCastLoad.ll diff -c /dev/null llvm/test/Regression/Transforms/InstCombine/2004-05-07-UnsizedCastLoad.ll:1.1 *** /dev/null Fri May 7 10:39:00 2004 --- llvm/test/Regression/Transforms/InstCombine/2004-05-07-UnsizedCastLoad.ll Fri May 7 10:38:50 2004 *************** *** 0 **** --- 1,9 ---- + ; RUN: llvm-as < %s | opt -instcombine -disable-output + + %Ty = type opaque + + int %test(%Ty *%X) { + %Y = cast %Ty* %X to int* + %Z = load int* %Y + ret int %Z + } From lattner at cs.uiuc.edu Fri May 7 11:23:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri May 7 11:23:01 2004 Subject: [llvm-commits] CVS: llvm-gcc/gcc/llvm-expand.c Message-ID: <200405071623.LAA16066@zion.cs.uiuc.edu> Changes in directory llvm-gcc/gcc: llvm-expand.c updated: 1.34 -> 1.35 --- Log message: Right... remove the fixme too --- Diffs of the changes: (+0 -1) Index: llvm-gcc/gcc/llvm-expand.c diff -u llvm-gcc/gcc/llvm-expand.c:1.34 llvm-gcc/gcc/llvm-expand.c:1.35 --- llvm-gcc/gcc/llvm-expand.c:1.34 Fri May 7 11:23:19 2004 +++ llvm-gcc/gcc/llvm-expand.c Fri May 7 11:23:37 2004 @@ -4095,7 +4095,6 @@ default: abort(); } - /* FIXME: This could use a conditional move instead of branches! */ Compare = append_inst(Fn, create_binary_inst("comp", Opcode, op0, op1)); if (TREE_CODE(exp) == ABS_EXPR) From lattner at cs.uiuc.edu Fri May 7 11:23:05 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri May 7 11:23:05 2004 Subject: [llvm-commits] CVS: llvm-gcc/gcc/llvm-expand.c Message-ID: <200405071623.LAA16055@zion.cs.uiuc.edu> Changes in directory llvm-gcc/gcc: llvm-expand.c updated: 1.33 -> 1.34 --- Log message: Expand min/max/abs in terms of select instead of explicit branching --- Diffs of the changes: (+12 -16) Index: llvm-gcc/gcc/llvm-expand.c diff -u llvm-gcc/gcc/llvm-expand.c:1.33 llvm-gcc/gcc/llvm-expand.c:1.34 --- llvm-gcc/gcc/llvm-expand.c:1.33 Wed Apr 21 13:57:57 2004 +++ llvm-gcc/gcc/llvm-expand.c Fri May 7 11:23:19 2004 @@ -4082,34 +4082,30 @@ llvm_basicblock *FromBlock =llvm_ilist_back(llvm_basicblock, Fn->BasicBlocks); enum InstOpcode Opcode; llvm_value *Compare; - llvm_instruction *PHI; + llvm_instruction *Select; + const char *Name; assert(op0->Ty == op1->Ty && "Operands must have same type!"); assert(llvm_type_is_scalar(op0->Ty) && "Min/Max/Abs require scalar type!"); switch (TREE_CODE(exp)) { - case ABS_EXPR: Opcode = O_SetGE; break; - case MAX_EXPR: Opcode = O_SetGE; break; - case MIN_EXPR: Opcode = O_SetLE; break; + case ABS_EXPR: Opcode = O_SetGE; Name = "abs"; break; + case MAX_EXPR: Opcode = O_SetGE; Name = "max"; break; + case MIN_EXPR: Opcode = O_SetLE; Name = "min"; break; default: abort(); } /* FIXME: This could use a conditional move instead of branches! */ Compare = append_inst(Fn, create_binary_inst("comp", Opcode, op0, op1)); - append_inst(Fn, create_cond_branch(Compare, Cont, Stub)); - llvm_emit_label(Fn, Stub); if (TREE_CODE(exp) == ABS_EXPR) - op1 = append_inst(Fn, create_binary_inst("abs", O_Sub, op1, op0)); - - append_inst(Fn, create_uncond_branch(Cont)); - llvm_emit_label(Fn, Cont); - PHI = llvm_instruction_new(op0->Ty, "minmax", O_PHINode, 4); - PHI->Operands[0] = op0; - PHI->Operands[1] = D2V(FromBlock); - PHI->Operands[2] = op1; - PHI->Operands[3] = D2V(Stub); - return append_inst(Fn, PHI); + op1 = append_inst(Fn, create_binary_inst("abs.pos", O_Sub, op1, op0)); + + Select = llvm_instruction_new(op0->Ty, Name, O_Select, 3); + Select->Operands[0] = Compare; + Select->Operands[1] = op0; + Select->Operands[2] = op1; + return append_inst(Fn, Select); } static llvm_function *CreateIntrinsicFnWithType(const char *Name, From lattner at cs.uiuc.edu Fri May 7 11:23:09 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri May 7 11:23:09 2004 Subject: [llvm-commits] CVS: llvm-gcc/gcc/llvm-representation.c llvm-representation.h Message-ID: <200405071623.LAA15794@zion.cs.uiuc.edu> Changes in directory llvm-gcc/gcc: llvm-representation.c updated: 1.5 -> 1.6 llvm-representation.h updated: 1.4 -> 1.5 --- Log message: Add support for the select instruction --- Diffs of the changes: (+4 -2) Index: llvm-gcc/gcc/llvm-representation.c diff -u llvm-gcc/gcc/llvm-representation.c:1.5 llvm-gcc/gcc/llvm-representation.c:1.6 --- llvm-gcc/gcc/llvm-representation.c:1.5 Tue Mar 9 20:50:57 2004 +++ llvm-gcc/gcc/llvm-representation.c Fri May 7 11:22:57 2004 @@ -390,6 +390,7 @@ case O_Call: fprintf(F, "call"); break; case O_Shl: fprintf(F, "shl"); break; case O_Shr: fprintf(F, "shr"); break; + case O_Select: fprintf(F, "select"); break; case O_VAArg: fprintf(F, "vaarg"); break; case O_VANext: fprintf(F, "vanext"); break; default: fprintf(F, ""); break; @@ -712,7 +713,8 @@ * the type from all but the first operand. If the instruction has * different type operands (for example br), then they are all printed. */ - int PrintAllTypes = I->Opcode == O_Shr || I->Opcode == O_Shl || !Operand; + int PrintAllTypes = + I->Opcode == O_Shr || I->Opcode == O_Shl || I->Opcode == O_Select || !Operand; llvm_type *TheType = Operand ? Operand->Ty : VoidTy; if (!PrintAllTypes) Index: llvm-gcc/gcc/llvm-representation.h diff -u llvm-gcc/gcc/llvm-representation.h:1.4 llvm-gcc/gcc/llvm-representation.h:1.5 --- llvm-gcc/gcc/llvm-representation.h:1.4 Tue Mar 16 01:06:12 2004 +++ llvm-gcc/gcc/llvm-representation.h Fri May 7 11:22:58 2004 @@ -161,7 +161,7 @@ O_And, O_Or, O_Xor, O_SetEQ, O_SetNE, O_SetLE, O_SetGE, O_SetLT, O_SetGT, O_Alloca, O_Malloc, O_Load, O_Store, O_GetElementPtr, - O_PHINode, O_Cast, O_Call, O_Shl, O_Shr, O_VAArg, O_VANext + O_PHINode, O_Cast, O_Call, O_Shl, O_Shr, O_Select, O_VAArg, O_VANext } Opcode; union { From lattner at cs.uiuc.edu Fri May 7 11:55:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri May 7 11:55:02 2004 Subject: [llvm-commits] CVS: llvm-gcc/gcc/llvm-expand.c Message-ID: <200405071655.LAA19237@zion.cs.uiuc.edu> Changes in directory llvm-gcc/gcc: llvm-expand.c updated: 1.35 -> 1.36 --- Log message: Implement constant folding of integer constant casts to bool. This should speed up the front-end a bit and expose further opportunities. create_cond_branch is about to get spiffier, so bracer ourselves. Remove some dead variables. --- Diffs of the changes: (+26 -7) Index: llvm-gcc/gcc/llvm-expand.c diff -u llvm-gcc/gcc/llvm-expand.c:1.35 llvm-gcc/gcc/llvm-expand.c:1.36 --- llvm-gcc/gcc/llvm-expand.c:1.35 Fri May 7 11:23:37 2004 +++ llvm-gcc/gcc/llvm-expand.c Fri May 7 11:55:09 2004 @@ -193,11 +193,18 @@ /* Constant fold some simple, but common, constants */ if (V->VTy == Constant) { - if (V2C(V)->Repr[0] == '0' && V2C(V)->Repr[1] == 0) { + llvm_constant *C = V2C(V); + if (C->Repr[0] == '0' && C->Repr[1] == 0) { return llvm_constant_get_null(Ty); /* At least handle the 0 case now */ } else if (Ty == LongTy) { /* Common array idx cases */ if (V->Ty == UIntTy || V->Ty == IntTy) - return llvm_constant_new(Ty, V2C(V)->Repr); + return llvm_constant_new(Ty, C->Repr); + } else if (Ty == BoolTy) { + if (C->Repr[0] >= '0' && C->Repr[0] <= '9') { + assert(llvm_constant_get_integer_val(C) != 0 && + "Null should have been handled already!"); + return llvm_constant_bool_true; + } } } @@ -3163,10 +3170,13 @@ llvm_basicblock *TestBlock = llvm_basicblock_new("shortcirc_next"); llvm_basicblock *DoneBlock = llvm_basicblock_new("shortcirc_done"); llvm_instruction *PHI; + llvm_instruction *CondBr; FirstOp = cast_if_type_not_equal(Fn, FirstOp, BoolTy); - append_inst(Fn, create_cond_branch(FirstOp, isAndExpr ? TestBlock : DoneBlock, - isAndExpr ? DoneBlock : TestBlock)); + CondBr = create_cond_branch(FirstOp, isAndExpr ? TestBlock : DoneBlock, + isAndExpr ? DoneBlock : TestBlock); + append_inst(Fn, CondBr); + llvm_emit_label(Fn, TestBlock); SecondOp = llvm_expand_expr(Fn, TREE_OPERAND(exp, 1), 0); @@ -3175,6 +3185,18 @@ llvm_emit_label(Fn, DoneBlock); + /* If the conditional branch was folded into an unconditional branch (because + * the condition was known true or false, don't insert a PHI node, just use + * the known value instead. + */ + if (CondBr->NumOperands == 1) { + llvm_type *Ty = llvm_type_get_from_tree(TREE_TYPE(exp)); + if (CondBr->Operands[0] == D2V(FromBlock)) + return cast_if_type_not_equal(Fn, isAndExpr ? llvm_constant_bool_false : + llvm_constant_bool_true, Ty); + return cast_if_type_not_equal(Fn, SecondOp, Ty); + } + /* Add a PHI node to merge together the two computed values */ PHI = llvm_instruction_new(BoolTy, "shortcirc_val", O_PHINode, 4); PHI->Operands[0] = isAndExpr ? llvm_constant_bool_false : @@ -4077,9 +4099,6 @@ static llvm_value *llvm_expand_minmaxabs_expr(llvm_function *Fn, tree exp, llvm_value *op0, llvm_value *op1){ - llvm_basicblock *Stub = llvm_basicblock_new("minmaxabs"); - llvm_basicblock *Cont = llvm_basicblock_new("cont"); - llvm_basicblock *FromBlock =llvm_ilist_back(llvm_basicblock, Fn->BasicBlocks); enum InstOpcode Opcode; llvm_value *Compare; llvm_instruction *Select; From lattner at cs.uiuc.edu Fri May 7 11:56:03 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri May 7 11:56:03 2004 Subject: [llvm-commits] CVS: llvm-gcc/gcc/llvm-representation.h llvm-representation.c Message-ID: <200405071655.LAA19251@zion.cs.uiuc.edu> Changes in directory llvm-gcc/gcc: llvm-representation.h updated: 1.5 -> 1.6 llvm-representation.c updated: 1.6 -> 1.7 --- Log message: Improve compile times with llvm-gcc by folding conditional branches into unconditional branches when the condition is obviously a constant. --- Diffs of the changes: (+12 -1) Index: llvm-gcc/gcc/llvm-representation.h diff -u llvm-gcc/gcc/llvm-representation.h:1.5 llvm-gcc/gcc/llvm-representation.h:1.6 --- llvm-gcc/gcc/llvm-representation.h:1.5 Fri May 7 11:22:58 2004 +++ llvm-gcc/gcc/llvm-representation.h Fri May 7 11:55:49 2004 @@ -200,6 +200,11 @@ llvm_instruction *create_binary_inst(const char *Name, enum InstOpcode Opc, llvm_value *Op1, llvm_value *Op2); llvm_instruction *create_uncond_branch(struct llvm_basicblock *Dest); + +/* create_cond_branch - Create a conditional branch on Val to the two blocks. + * Be aware that if Val is a constant, this will actually return an + * unconditional branch. + */ llvm_instruction *create_cond_branch(llvm_value *Val, struct llvm_basicblock *TrueBlock, struct llvm_basicblock *FalseBlock); Index: llvm-gcc/gcc/llvm-representation.c diff -u llvm-gcc/gcc/llvm-representation.c:1.6 llvm-gcc/gcc/llvm-representation.c:1.7 --- llvm-gcc/gcc/llvm-representation.c:1.6 Fri May 7 11:22:57 2004 +++ llvm-gcc/gcc/llvm-representation.c Fri May 7 11:55:49 2004 @@ -572,7 +572,13 @@ llvm_instruction *create_cond_branch(llvm_value *Cond, llvm_basicblock *TrueBlock, llvm_basicblock *FalseBlock) { - llvm_instruction *New = llvm_instruction_new(VoidTy, "", O_Br, 3); + llvm_instruction *New; + if (Cond == llvm_constant_bool_true) + return create_uncond_branch(TrueBlock); + else if (Cond == llvm_constant_bool_false) + return create_uncond_branch(FalseBlock); + + New = llvm_instruction_new(VoidTy, "", O_Br, 3); New->Operands[0] = Cond; New->Operands[1] = D2V(TrueBlock); New->Operands[2] = D2V(FalseBlock); From lattner at cs.uiuc.edu Fri May 7 11:59:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri May 7 11:59:02 2004 Subject: [llvm-commits] CVS: llvm-gcc/gcc/llvm-expand.c Message-ID: <200405071659.LAA19267@zion.cs.uiuc.edu> Changes in directory llvm-gcc/gcc: llvm-expand.c updated: 1.36 -> 1.37 --- Log message: Minor code cleanups --- Diffs of the changes: (+4 -4) Index: llvm-gcc/gcc/llvm-expand.c diff -u llvm-gcc/gcc/llvm-expand.c:1.36 llvm-gcc/gcc/llvm-expand.c:1.37 --- llvm-gcc/gcc/llvm-expand.c:1.36 Fri May 7 11:55:09 2004 +++ llvm-gcc/gcc/llvm-expand.c Fri May 7 11:59:33 2004 @@ -3186,15 +3186,15 @@ llvm_emit_label(Fn, DoneBlock); /* If the conditional branch was folded into an unconditional branch (because - * the condition was known true or false, don't insert a PHI node, just use + * the condition was known true or false) don't insert a PHI node, just use * the known value instead. */ if (CondBr->NumOperands == 1) { llvm_type *Ty = llvm_type_get_from_tree(TREE_TYPE(exp)); + llvm_value *Val = SecondOp; if (CondBr->Operands[0] == D2V(FromBlock)) - return cast_if_type_not_equal(Fn, isAndExpr ? llvm_constant_bool_false : - llvm_constant_bool_true, Ty); - return cast_if_type_not_equal(Fn, SecondOp, Ty); + Val = isAndExpr ? llvm_constant_bool_false : llvm_constant_bool_true; + return cast_if_type_not_equal(Fn, Val, Ty); } /* Add a PHI node to merge together the two computed values */ From lattner at cs.uiuc.edu Fri May 7 12:29:05 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri May 7 12:29:05 2004 Subject: [llvm-commits] CVS: llvm-gcc/gcc/llvm-expand.c Message-ID: <200405071728.MAA19380@zion.cs.uiuc.edu> Changes in directory llvm-gcc/gcc: llvm-expand.c updated: 1.37 -> 1.38 --- Log message: Minor cleanups, do not unconditionally force array indexes to long anymore --- Diffs of the changes: (+6 -6) Index: llvm-gcc/gcc/llvm-expand.c diff -u llvm-gcc/gcc/llvm-expand.c:1.37 llvm-gcc/gcc/llvm-expand.c:1.38 --- llvm-gcc/gcc/llvm-expand.c:1.37 Fri May 7 11:59:33 2004 +++ llvm-gcc/gcc/llvm-expand.c Fri May 7 12:28:45 2004 @@ -5221,11 +5221,12 @@ break; case ARRAY_REF: { - llvm_type *Op0Ty = llvm_type_get_from_tree(TREE_TYPE(TREE_OPERAND(exp, 0))); + tree tOp0 = TREE_OPERAND(exp, 0), tOp1 = TREE_OPERAND(exp, 1); + llvm_type *Op0Ty = llvm_type_get_from_tree(TREE_TYPE(tOp0)); if (llvm_type_is_composite(Op0Ty)) { - llvm_value *Op0 = llvm_expand_lvalue_expr(Fn, TREE_OPERAND(exp, 0), 0, 0); - llvm_value *Op1 = llvm_expand_expr(Fn, TREE_OPERAND(exp, 1), 0); + llvm_value *Op0 = llvm_expand_lvalue_expr(Fn, tOp0, 0, 0); + llvm_value *Op1 = llvm_expand_expr(Fn, tOp1, 0); Op1 = cast_if_type_not_equal(Fn, Op1, LongTy); Result = append_inst(Fn, create_gep3(Op0, llvm_constant_long_0, Op1)); } else { @@ -5234,12 +5235,11 @@ * take a pointer as the first operand. In this case, we generate a two * operand GEP. */ - llvm_value *Op0 = llvm_expand_expr(Fn, TREE_OPERAND(exp, 0), 0); - llvm_value *Op1 = llvm_expand_expr(Fn, TREE_OPERAND(exp, 1), 0); + llvm_value *Op0 = llvm_expand_expr(Fn, tOp0, 0); + llvm_value *Op1 = llvm_expand_expr(Fn, tOp1, 0); llvm_type *IntPtrTy = llvm_type_get_integer(llvm_type_get_size(VoidPtrTy)*8, 0); Op1 = cast_if_type_not_equal(Fn, Op1, IntPtrTy); - Op1 = cast_if_type_not_equal(Fn, Op1, LongTy); /* FIXME: What do we do about bitfields here??? */ assert(Op0->Ty->ID == PointerTyID && From lattner at cs.uiuc.edu Fri May 7 13:33:03 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri May 7 13:33:03 2004 Subject: [llvm-commits] CVS: llvm-gcc/gcc/llvm-representation.c Message-ID: <200405071833.NAA21612@zion.cs.uiuc.edu> Changes in directory llvm-gcc/gcc: llvm-representation.c updated: 1.7 -> 1.8 --- Log message: Relax restrictions on gep operand types --- Diffs of the changes: (+5 -2) Index: llvm-gcc/gcc/llvm-representation.c diff -u llvm-gcc/gcc/llvm-representation.c:1.7 llvm-gcc/gcc/llvm-representation.c:1.8 --- llvm-gcc/gcc/llvm-representation.c:1.7 Fri May 7 11:55:49 2004 +++ llvm-gcc/gcc/llvm-representation.c Fri May 7 13:32:35 2004 @@ -590,8 +590,11 @@ llvm_type *ResultTy = GET_POINTER_TYPE_ELEMENT(Op0->Ty); assert(Op1->Ty == LongTy && "First GEP index must be long type!"); assert(llvm_type_is_composite(ResultTy) && "Cannot index into noncomposite!"); - assert(((ResultTy->ID == ArrayTyID && Op2->Ty == LongTy) || - (ResultTy->ID == StructTyID && Op2->Ty == UByteTy)) && + assert(((ResultTy->ID == ArrayTyID && + (Op2->Ty == LongTy || Op2->Ty == ULongTy || + Op2->Ty == IntTy || Op2->Ty == UIntTy)) || + (ResultTy->ID == StructTyID && + (Op2->Ty == UByteTy || Op2->Ty == UIntTy))) && "Invalid getelementptr indices!"); if (ResultTy->ID == StructTyID) { unsigned Idx = llvm_constant_get_integer_val(V2C(Op2)); From lattner at cs.uiuc.edu Fri May 7 13:34:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri May 7 13:34:02 2004 Subject: [llvm-commits] CVS: llvm-gcc/gcc/llvm-types.c llvm-expand.c Message-ID: <200405071834.NAA21640@zion.cs.uiuc.edu> Changes in directory llvm-gcc/gcc: llvm-types.c updated: 1.4 -> 1.5 llvm-expand.c updated: 1.38 -> 1.39 --- Log message: Fix the first part of PR298: http://llvm.cs.uiuc.edu/PR298 : [llvmgcc] Variable length array indexing miscompiled --- Diffs of the changes: (+44 -16) Index: llvm-gcc/gcc/llvm-types.c diff -u llvm-gcc/gcc/llvm-types.c:1.4 llvm-gcc/gcc/llvm-types.c:1.5 --- llvm-gcc/gcc/llvm-types.c:1.4 Wed Apr 21 13:57:43 2004 +++ llvm-gcc/gcc/llvm-types.c Fri May 7 13:34:32 2004 @@ -987,19 +987,25 @@ case ARRAY_TYPE: { unsigned NumElements; - if (TYPE_DOMAIN(type) && TYPE_MAX_VALUE(TYPE_DOMAIN(type)) && - TREE_CODE(TYPE_MAX_VALUE(TYPE_DOMAIN(type))) == INTEGER_CST) { - NumElements = TREE_INT_CST_LOW(TYPE_MAX_VALUE(TYPE_DOMAIN(type)))+1; + tree Domain = TYPE_DOMAIN(type); + if (Domain && TYPE_MAX_VALUE(Domain)) { + if (TREE_CODE(TYPE_MAX_VALUE(Domain)) == INTEGER_CST) { + /* Normal array */ + NumElements = TREE_INT_CST_LOW(TYPE_MAX_VALUE(Domain))+1; + } else { + /* This handles cases like "int A[n]" which have a runtime constant + * number of elements, but is a compile-time variable. Since these are + * variable sized, we just represent them as the element themself. + */ + return llvm_type_get_from_tree(TREE_TYPE(type)); + } } else { - /* Otherwise the reasons we could get here is if they have something that - * is globally declared as an array with no dimension, this becomes just a - * zero size array of the element type so that: int X[] becomes *'%X = - * external global [0 x int]' + /* We get here is if they have something that is globally declared as an + * array with no dimension, this becomes just a zero size array of the + * element type so that: int X[] becomes *'%X = external global [0 x int]' * * Note that this also affects new expressions, which return a pointer to - * an unsized array of elements. This also effects things like "int A[n]" - * which has an runtime constant number of elements, but is a compile-time - * variable. + * an unsized array of elements. */ NumElements = 0; } Index: llvm-gcc/gcc/llvm-expand.c diff -u llvm-gcc/gcc/llvm-expand.c:1.38 llvm-gcc/gcc/llvm-expand.c:1.39 --- llvm-gcc/gcc/llvm-expand.c:1.38 Fri May 7 12:28:45 2004 +++ llvm-gcc/gcc/llvm-expand.c Fri May 7 13:34:32 2004 @@ -5223,11 +5223,13 @@ case ARRAY_REF: { tree tOp0 = TREE_OPERAND(exp, 0), tOp1 = TREE_OPERAND(exp, 1); llvm_type *Op0Ty = llvm_type_get_from_tree(TREE_TYPE(tOp0)); + llvm_type *IntPtrTy = + llvm_type_get_integer(llvm_type_get_size(VoidPtrTy)*8, 0); if (llvm_type_is_composite(Op0Ty)) { llvm_value *Op0 = llvm_expand_lvalue_expr(Fn, tOp0, 0, 0); llvm_value *Op1 = llvm_expand_expr(Fn, tOp1, 0); - Op1 = cast_if_type_not_equal(Fn, Op1, LongTy); + Op1 = cast_if_type_not_equal(Fn, Op1, IntPtrTy); Result = append_inst(Fn, create_gep3(Op0, llvm_constant_long_0, Op1)); } else { llvm_instruction *I; @@ -5235,12 +5237,32 @@ * take a pointer as the first operand. In this case, we generate a two * operand GEP. */ - llvm_value *Op0 = llvm_expand_expr(Fn, tOp0, 0); - llvm_value *Op1 = llvm_expand_expr(Fn, tOp1, 0); - llvm_type *IntPtrTy = - llvm_type_get_integer(llvm_type_get_size(VoidPtrTy)*8, 0); + llvm_value *Op0, *Op1; + unsigned LLVMSize; + + if (TREE_CODE(TREE_TYPE(tOp0)) == ARRAY_TYPE) + Op0 = llvm_expand_lvalue_expr(Fn, tOp0, 0, 0); + else + Op0 = llvm_expand_expr(Fn, tOp0, 0); + Op1 = llvm_expand_expr(Fn, tOp1, 0); + LLVMSize = llvm_type_get_size(GET_POINTER_TYPE_ELEMENT(Op0->Ty)); Op1 = cast_if_type_not_equal(Fn, Op1, IntPtrTy); - /* FIXME: What do we do about bitfields here??? */ + + /* If we are stepping over a variable sized array, then the element size + * of the array will not match the size of the pointer, and we need to + * scale the index. + */ + if (TREE_CODE(TREE_TYPE(tOp0)) == POINTER_TYPE) { + tree PointeeSize = TYPE_SIZE_UNIT(TREE_TYPE(TREE_TYPE(tOp0))); + if (TREE_CODE(PointeeSize) == INTEGER_CST) { + unsigned GCCSize = TREE_INT_CST_LOW(PointeeSize); + assert(GCCSize == LLVMSize &&"Unknown pointer subscript expression!"); + } else { + llvm_value *Size = llvm_expand_expr(Fn, PointeeSize, 0); + Size = cast_if_type_not_equal(Fn, Size, Op1->Ty); + Op1 = append_inst(Fn, create_binary_inst("tmp", O_Mul, Op1, Size)); + } + } assert(Op0->Ty->ID == PointerTyID && "Cannot subscript non-pointer, non-array type!"); From lattner at cs.uiuc.edu Fri May 7 13:39:06 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri May 7 13:39:06 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/CFrontend/2004-05-07-VarArrays.c Message-ID: <200405071839.NAA21803@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CFrontend: 2004-05-07-VarArrays.c added (r1.1) --- Log message: New testcase --- Diffs of the changes: (+3 -0) Index: llvm/test/Regression/CFrontend/2004-05-07-VarArrays.c diff -c /dev/null llvm/test/Regression/CFrontend/2004-05-07-VarArrays.c:1.1 *** /dev/null Fri May 7 13:39:09 2004 --- llvm/test/Regression/CFrontend/2004-05-07-VarArrays.c Fri May 7 13:38:59 2004 *************** *** 0 **** --- 1,3 ---- + int foo(int len, char arr[][len], int X) { + return arr[X][0]; + } From lattner at cs.uiuc.edu Fri May 7 13:42:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri May 7 13:42:01 2004 Subject: [llvm-commits] CVS: llvm-www/releases/1.2/docs/ReleaseNotes.html Message-ID: <200405071841.NAA30354@apoc.cs.uiuc.edu> Changes in directory llvm-www/releases/1.2/docs: ReleaseNotes.html updated: 1.14 -> 1.15 --- Log message: Bug found --- Diffs of the changes: (+2 -1) Index: llvm-www/releases/1.2/docs/ReleaseNotes.html diff -u llvm-www/releases/1.2/docs/ReleaseNotes.html:1.14 llvm-www/releases/1.2/docs/ReleaseNotes.html:1.15 --- llvm-www/releases/1.2/docs/ReleaseNotes.html:1.14 Fri May 7 08:36:12 2004 +++ llvm-www/releases/1.2/docs/ReleaseNotes.html Fri May 7 13:40:52 2004 @@ -389,6 +389,7 @@ Bugs in 1.2 fixed in 1.3: @@ -681,7 +682,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
      - Last modified: $Date: 2004/05/07 13:36:12 $ + Last modified: $Date: 2004/05/07 18:40:52 $ From lattner at cs.uiuc.edu Fri May 7 13:42:05 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri May 7 13:42:05 2004 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200405071840.NAA29704@apoc.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.173 -> 1.174 --- Log message: Bug fixed --- Diffs of the changes: (+3 -2) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.173 llvm/docs/ReleaseNotes.html:1.174 --- llvm/docs/ReleaseNotes.html:1.173 Thu May 6 17:23:24 2004 +++ llvm/docs/ReleaseNotes.html Fri May 7 13:40:38 2004 @@ -212,7 +212,8 @@

      Bugs in the C/C++ front-end:

        -
      1. [llvmgcc] Crash on use of undeclared enum type
      2. +
      3. [llvmgcc] Crash on use of undeclared enum type
      4. +
      5. [llvmgcc] Variable length array indexing miscompiled
      @@ -635,7 +636,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
      - Last modified: $Date: 2004/05/06 22:23:24 $ + Last modified: $Date: 2004/05/07 18:40:38 $ From lattner at cs.uiuc.edu Fri May 7 14:20:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri May 7 14:20:02 2004 Subject: [llvm-commits] CVS: llvm-gcc/gcc/llvm-out.h llvm-types.c toplev.c Message-ID: <200405071920.OAA06906@zion.cs.uiuc.edu> Changes in directory llvm-gcc/gcc: llvm-out.h updated: 1.3 -> 1.4 llvm-types.c updated: 1.5 -> 1.6 toplev.c updated: 1.4 -> 1.5 --- Log message: Fix PR329: http://llvm.cs.uiuc.edu/PR329 : [llvmgcc] type names are not emitted for structure typedefs --- Diffs of the changes: (+24 -1) Index: llvm-gcc/gcc/llvm-out.h diff -u llvm-gcc/gcc/llvm-out.h:1.3 llvm-gcc/gcc/llvm-out.h:1.4 --- llvm-gcc/gcc/llvm-out.h:1.3 Thu Feb 5 10:05:45 2004 +++ llvm-gcc/gcc/llvm-out.h Fri May 7 14:20:26 2004 @@ -48,6 +48,11 @@ */ void llvm_assemble_external(union tree_node *decl); +/* llvm_emit_type_decl - This is called to emit type declarations for type-defs + * that are not already named. + */ +void llvm_emit_type_decl(union tree_node *decl); + /* llvm_c_expand_body - Expand the specified function into LLVM code and emit it. */ void llvm_c_expand_body(union tree_node *); Index: llvm-gcc/gcc/llvm-types.c diff -u llvm-gcc/gcc/llvm-types.c:1.5 llvm-gcc/gcc/llvm-types.c:1.6 --- llvm-gcc/gcc/llvm-types.c:1.5 Fri May 7 13:34:32 2004 +++ llvm-gcc/gcc/llvm-types.c Fri May 7 14:20:26 2004 @@ -1409,3 +1409,19 @@ } abort(); } + + +/* llvm_emit_type_decl - This is called to emit type declarations for type-defs + * that are not already named. + */ +void llvm_emit_type_decl(tree decl) { + llvm_type *Ty = llvm_type_get_from_tree(TREE_TYPE(decl)); + + /* If this typedef provides a name for a structure type that does not have a + * tag, apply it now. + */ + if (DECL_NAME(decl) && Ty->ID == StructTyID && Ty->x.Struct.TypeName == 0) { + const char *N = IDENTIFIER_POINTER(DECL_NAME(decl)); + Ty->x.Struct.TypeName = get_type_name(N, "struct.", DECL_CONTEXT(decl)); + } +} Index: llvm-gcc/gcc/toplev.c diff -u llvm-gcc/gcc/toplev.c:1.4 llvm-gcc/gcc/toplev.c:1.5 --- llvm-gcc/gcc/toplev.c:1.4 Thu Feb 5 10:05:45 2004 +++ llvm-gcc/gcc/toplev.c Fri May 7 14:20:26 2004 @@ -1951,7 +1951,9 @@ } } else if (EMIT_LLVM) { - /* Do not send to debugging */ + /* Do not send to debug info. */ + if (TREE_CODE(decl) == TYPE_DECL) + llvm_emit_type_decl(decl); } #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) else if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) From lattner at cs.uiuc.edu Fri May 7 14:23:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri May 7 14:23:02 2004 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200405071923.OAA07545@zion.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.174 -> 1.175 --- Log message: PR implemented --- Diffs of the changes: (+2 -1) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.174 llvm/docs/ReleaseNotes.html:1.175 --- llvm/docs/ReleaseNotes.html:1.174 Fri May 7 13:40:38 2004 +++ llvm/docs/ReleaseNotes.html Fri May 7 14:23:05 2004 @@ -132,6 +132,7 @@
      1. LLVM tools will happily spew bytecode onto your terminal
      2. +
      3. [llvmgcc] type names are not emitted for structure typedefs
      @@ -636,7 +637,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
      - Last modified: $Date: 2004/05/07 18:40:38 $ + Last modified: $Date: 2004/05/07 19:23:05 $ From lattner at cs.uiuc.edu Fri May 7 14:25:03 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri May 7 14:25:03 2004 Subject: [llvm-commits] CVS: llvm-gcc/gcc/llvm-types.c Message-ID: <200405071925.OAA08146@zion.cs.uiuc.edu> Changes in directory llvm-gcc/gcc: llvm-types.c updated: 1.6 -> 1.7 --- Log message: We really should identify the name as a typedef tag, not a struct tag --- Diffs of the changes: (+1 -1) Index: llvm-gcc/gcc/llvm-types.c diff -u llvm-gcc/gcc/llvm-types.c:1.6 llvm-gcc/gcc/llvm-types.c:1.7 --- llvm-gcc/gcc/llvm-types.c:1.6 Fri May 7 14:20:26 2004 +++ llvm-gcc/gcc/llvm-types.c Fri May 7 14:24:53 2004 @@ -1422,6 +1422,6 @@ */ if (DECL_NAME(decl) && Ty->ID == StructTyID && Ty->x.Struct.TypeName == 0) { const char *N = IDENTIFIER_POINTER(DECL_NAME(decl)); - Ty->x.Struct.TypeName = get_type_name(N, "struct.", DECL_CONTEXT(decl)); + Ty->x.Struct.TypeName = get_type_name(N, "typedef.", DECL_CONTEXT(decl)); } } From lattner at cs.uiuc.edu Fri May 7 14:56:06 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri May 7 14:56:06 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200405071956.OAA13201@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.245 -> 1.246 --- Log message: Make comparisons against the null pointer as efficient as integer comparisons against zero. In particular, don't emit: mov %ESI, 0 cmp %ECX, %ESI instead, emit: test %ECX, %ECX --- Diffs of the changes: (+8 -1) Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.245 llvm/lib/Target/X86/InstSelectSimple.cpp:1.246 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.245 Tue May 4 14:35:11 2004 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Fri May 7 14:55:55 2004 @@ -829,7 +829,14 @@ unsigned Op0r = getReg(Op0, MBB, IP); // Special case handling of: cmp R, i - if (ConstantInt *CI = dyn_cast(Op1)) { + if (isa(Op1)) { + if (OpNum < 2) // seteq/setne -> test + BuildMI(*MBB, IP, X86::TEST32rr, 2).addReg(Op0r).addReg(Op0r); + else + BuildMI(*MBB, IP, X86::CMP32ri, 2).addReg(Op0r).addImm(0); + return OpNum; + + } else if (ConstantInt *CI = dyn_cast(Op1)) { if (Class == cByte || Class == cShort || Class == cInt) { unsigned Op1v = CI->getRawValue(); From gaeke at cs.uiuc.edu Fri May 7 16:10:03 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Fri May 7 16:10:03 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/ExecutionEngine/test-cast.ll Message-ID: <200405072110.QAA18826@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/ExecutionEngine: test-cast.ll updated: 1.6 -> 1.7 --- Log message: Add more casts. You can never have enough casts. --- Diffs of the changes: (+49 -1) Index: llvm/test/Regression/ExecutionEngine/test-cast.ll diff -u llvm/test/Regression/ExecutionEngine/test-cast.ll:1.6 llvm/test/Regression/ExecutionEngine/test-cast.ll:1.7 --- llvm/test/Regression/ExecutionEngine/test-cast.ll:1.6 Sat May 31 22:37:25 2003 +++ llvm/test/Regression/ExecutionEngine/test-cast.ll Fri May 7 16:10:28 2004 @@ -7,35 +7,67 @@ int %main() { ; cast bool to ... cast bool true to bool + cast bool true to ubyte + cast bool true to sbyte + cast bool true to short + cast bool true to ushort cast bool true to int + cast bool true to uint cast bool true to long cast bool true to ulong cast bool true to float cast bool true to double ; cast sbyte to ... + cast sbyte 0 to bool + cast sbyte 1 to bool cast sbyte 0 to sbyte + cast sbyte -1 to ubyte cast sbyte 4 to short + cast sbyte 4 to ushort cast sbyte 4 to long cast sbyte 4 to ulong + cast sbyte 4 to float cast sbyte 4 to double ; cast ubyte to ... + cast ubyte 0 to bool + cast ubyte 1 to bool + cast ubyte 0 to sbyte + cast ubyte 1 to ubyte + cast ubyte 4 to short + cast ubyte 4 to ushort + cast ubyte 4 to long + cast ubyte 4 to ulong cast ubyte 0 to float cast ubyte 0 to double ; cast short to ... + cast short 1 to bool + cast short -1 to sbyte + cast short 255 to ubyte cast short 0 to short + cast short 0 to ushort cast short 0 to long cast short 0 to ulong + cast short 0 to float cast short 0 to double ; cast ushort to ... + cast ushort 1 to bool + cast ushort 1 to sbyte + cast ushort 255 to ubyte + cast ushort 0 to short + cast ushort 0 to ushort + cast ushort 0 to long + cast ushort 0 to ulong cast ushort 0 to float cast ushort 0 to double ; cast int to ... cast int 6 to bool + cast int -6 to sbyte + cast int 6 to ubyte cast int 6 to short cast int 0 to int cast int 0 to long @@ -44,6 +76,11 @@ cast int 0 to double ; cast uint to ... + cast uint 6 to bool + cast uint 7 to sbyte + cast uint 8 to ubyte + cast uint 9 to short + cast uint 10 to int cast uint 0 to long cast uint 0 to ulong cast uint 0 to float @@ -62,7 +99,18 @@ cast long 0 to float cast long 0 to double - cast ulong 0 to bool + ; cast ulong to ... + cast ulong 1 to bool + cast ulong 1 to sbyte + cast ulong 1 to ubyte + cast ulong 1 to short + cast ulong 1 to ushort + cast ulong 1 to int + cast ulong 1 to uint + cast ulong 1 to long + cast ulong 1 to ulong + cast ulong 1 to float + cast ulong 0 to double ; cast float to ... ;cast float 0.0 to bool From lattner at cs.uiuc.edu Fri May 7 16:18:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri May 7 16:18:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200405072118.QAA19298@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.246 -> 1.247 --- Log message: Codegen floating point stores of constants into integer instructions. This allows us to compile: store float 10.0, float* %P into: mov DWORD PTR [%EAX], 1092616192 instead of: .CPItest_0: # float 0x4024000000000000 .long 1092616192 # float 10 ... fld DWORD PTR [.CPItest_0] fstp DWORD PTR [%EAX] --- Diffs of the changes: (+37 -15) Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.246 llvm/lib/Target/X86/InstSelectSimple.cpp:1.247 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.246 Fri May 7 14:55:55 2004 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Fri May 7 16:18:15 2004 @@ -2879,23 +2879,45 @@ } else if (ConstantBool *CB = dyn_cast(I.getOperand(0))) { addFullAddress(BuildMI(BB, X86::MOV8mi, 5), BaseReg, Scale, IndexReg, Disp).addImm(CB->getValue()); - } else { - if (Class == cLong) { - unsigned ValReg = getReg(I.getOperand(0)); - addFullAddress(BuildMI(BB, X86::MOV32mr, 5), - BaseReg, Scale, IndexReg, Disp).addReg(ValReg); - addFullAddress(BuildMI(BB, X86::MOV32mr, 5), - BaseReg, Scale, IndexReg, Disp+4).addReg(ValReg+1); + } else if (ConstantFP *CFP = dyn_cast(I.getOperand(0))) { + // Store constant FP values with integer instructions to avoid having to + // load the constants from the constant pool then do a store. + if (CFP->getType() == Type::FloatTy) { + union { + unsigned I; + float F; + } V; + V.F = CFP->getValue(); + addFullAddress(BuildMI(BB, X86::MOV32mi, 5), + BaseReg, Scale, IndexReg, Disp).addImm(V.I); } else { - unsigned ValReg = getReg(I.getOperand(0)); - static const unsigned Opcodes[] = { - X86::MOV8mr, X86::MOV16mr, X86::MOV32mr, X86::FST32m - }; - unsigned Opcode = Opcodes[Class]; - if (ValTy == Type::DoubleTy) Opcode = X86::FST64m; - addFullAddress(BuildMI(BB, Opcode, 1+4), - BaseReg, Scale, IndexReg, Disp).addReg(ValReg); + union { + uint64_t I; + double F; + } V; + V.F = CFP->getValue(); + addFullAddress(BuildMI(BB, X86::MOV32mi, 5), + BaseReg, Scale, IndexReg, Disp).addImm((unsigned)V.I); + addFullAddress(BuildMI(BB, X86::MOV32mi, 5), + BaseReg, Scale, IndexReg, Disp+4).addImm( + unsigned(V.I >> 32)); } + + } else if (Class == cLong) { + unsigned ValReg = getReg(I.getOperand(0)); + addFullAddress(BuildMI(BB, X86::MOV32mr, 5), + BaseReg, Scale, IndexReg, Disp).addReg(ValReg); + addFullAddress(BuildMI(BB, X86::MOV32mr, 5), + BaseReg, Scale, IndexReg, Disp+4).addReg(ValReg+1); + } else { + unsigned ValReg = getReg(I.getOperand(0)); + static const unsigned Opcodes[] = { + X86::MOV8mr, X86::MOV16mr, X86::MOV32mr, X86::FST32m + }; + unsigned Opcode = Opcodes[Class]; + if (ValTy == Type::DoubleTy) Opcode = X86::FST64m; + addFullAddress(BuildMI(BB, Opcode, 1+4), + BaseReg, Scale, IndexReg, Disp).addReg(ValReg); } } From brukman at cs.uiuc.edu Fri May 7 16:37:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri May 7 16:37:01 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/Transforms/Parallel/LowerParaBr.cpp Message-ID: <200405072137.QAA21329@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Parallel: LowerParaBr.cpp updated: 1.1.2.1 -> 1.1.2.2 --- Log message: llvm.join no longer necessarily uses pbr directly, plus there could be >1 join for every pbr, so we need to remove them all in a given parallel region. --- Diffs of the changes: (+38 -15) Index: llvm/lib/Transforms/Parallel/LowerParaBr.cpp diff -u llvm/lib/Transforms/Parallel/LowerParaBr.cpp:1.1.2.1 llvm/lib/Transforms/Parallel/LowerParaBr.cpp:1.1.2.2 --- llvm/lib/Transforms/Parallel/LowerParaBr.cpp:1.1.2.1 Sat Apr 17 19:45:51 2004 +++ llvm/lib/Transforms/Parallel/LowerParaBr.cpp Fri May 7 16:37:09 2004 @@ -43,6 +43,7 @@ private: void straightenSequence(ParallelSeq *PS); + Function* getJoinIntrinsic(Module *M); }; RegisterOpt X("lowerpbr", "Lower pbr to sequential code"); @@ -66,6 +67,10 @@ return Changed; } +static bool contains(std::vector haystack, BasicBlock *needle) { + return std::find(haystack.begin(), haystack.end(), needle) != haystack.end(); +} + /// straightenSequence - Recursively process parallel sequences /// void LowerParaBr::straightenSequence(ParallelSeq *PS) { @@ -79,27 +84,45 @@ ci != ce; ++ci) straightenSequence(*ci); - // Stitch previous region to the current one by rewriting the last branch + // Stitch previous region to the current one by all branches to the join + // block instead branch to the first block of the second region if (PrevPR) { - std::vector &PrevBlocks = PrevPR->getBlocks(), + std::vector &PrevJoinBlocks = PrevPR->getJoinBlocks(), &PRBlocks = PR->getBlocks(); - BasicBlock *PrevLastBB = PrevBlocks.back(), *PRFirstBB = PRBlocks[0]; - TerminatorInst *TI = PrevLastBB->getTerminator(); - new BranchInst(PRFirstBB, TI); - PrevLastBB->getInstList().erase(TI); + BasicBlock *PRFirstBB = PRBlocks[0]; + for (std::vector::iterator j = PrevJoinBlocks.begin(), + je = PrevJoinBlocks.end(); j != je; ++j) { + std::vector JUsers((*j)->use_begin(), (*j)->use_end()); + for (std::vector::iterator u = JUsers.begin(), ue = JUsers.end(); + u != ue; ++u) + if (Instruction *I = dyn_cast(*u)) + if (contains(PR->getBlocks(), I->getParent())) + I->replaceUsesOfWith(*j, PRFirstBB); + } } } - // Remove the call to llvm.join() - ParaBrInst *pbr = dyn_cast(PS->getHeader()->getTerminator()); - assert(pbr && "pbr not a terminator of ParallelSeq header!"); - std::vector Users(pbr->use_begin(), pbr->use_end()); + Module *M = PS->getHeader()->getParent()->getParent(); + Function *JoinIntr = getJoinIntrinsic(M); + std::vector Users(JoinIntr->use_begin(), JoinIntr->use_end()); + // Remove the calls to llvm.join() for (std::vector::iterator use = Users.begin(), ue = Users.end(); use != ue; ++use) - if (Instruction *Inst = dyn_cast(*use)) - Inst->getParent()->getInstList().erase(Inst); + if (CallInst *CI = dyn_cast(*use)) + if (contains(PR->getJoinBlocks(), CI->getParent()) || + contains(PrevPR->getJoinBlocks(), CI->getParent())) + CI->getParent()->getInstList().erase(CI); + + // Remove pbr + ParaBrInst *pbr = dyn_cast(PS->getHeader()->getTerminator()); + //assert(pbr && "Terminator of ParaSeq header is not a pbr"); + if (pbr) { + new BranchInst(pbr->getSuccessor(0), pbr); + pbr->getParent()->getInstList().erase(pbr); + } +} - // Rewrite pbr as a regular branch - new BranchInst(pbr->getSuccessor(0), pbr); - pbr->getParent()->getInstList().erase(pbr); +Function* LowerParaBr::getJoinIntrinsic(Module *M) { + return M->getOrInsertFunction("llvm.join", Type::VoidTy, + PointerType::get(Type::SByteTy), 0); } From brukman at cs.uiuc.edu Fri May 7 16:38:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri May 7 16:38:01 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/Transforms/Parallel/ParallelCallsToThreads.cpp Message-ID: <200405072138.QAA21442@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Parallel: ParallelCallsToThreads.cpp updated: 1.1.2.2 -> 1.1.2.3 --- Log message: Convert calls to threads for _each_ parallel region, as the values we join() on depend on the region we spawned off. --- Diffs of the changes: (+47 -25) Index: llvm/lib/Transforms/Parallel/ParallelCallsToThreads.cpp diff -u llvm/lib/Transforms/Parallel/ParallelCallsToThreads.cpp:1.1.2.2 llvm/lib/Transforms/Parallel/ParallelCallsToThreads.cpp:1.1.2.3 --- llvm/lib/Transforms/Parallel/ParallelCallsToThreads.cpp:1.1.2.2 Sat Apr 17 20:10:58 2004 +++ llvm/lib/Transforms/Parallel/ParallelCallsToThreads.cpp Fri May 7 16:37:56 2004 @@ -11,10 +11,10 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Constant.h" #include "llvm/DerivedTypes.h" #include "llvm/Module.h" -#include "llvm/iOther.h" -#include "llvm/iTerminators.h" +#include "llvm/Instructions.h" #include "llvm/Pass.h" #include "llvm/Type.h" #include "llvm/Analysis/ParallelInfo.h" @@ -30,6 +30,7 @@ /// struct PCallToThreads : public FunctionPass { Type *startTy; + typedef std::vector BBVec; public: PCallToThreads() { @@ -57,6 +58,19 @@ } // End anonymous namespace +static bool findPbr(Value *V, ParaBrInst *pbr) { + if (V == pbr) + return true; + else if (PHINode *phi = dyn_cast(V)) { + bool Found = false; + for (unsigned i = 0, e = phi->getNumIncomingValues(); i != e; ++i) + if (findPbr(phi->getIncomingValue(i), pbr)) + return true; + return false; + } else + return false; +} + /// runOnFunction - /// bool PCallToThreads::runOnFunction(Function &F) { @@ -66,11 +80,12 @@ // Convert parallel calls to pthread_create() invocations for (ParallelInfo::iterator i = PI.begin(), e = PI.end(); i != e; ++i) { ParallelSeq *PS = *i; - std::vector JoinValues; - for (ParallelSeq::riterator r = PS->rbegin(), - re = PS->rend(); r != re; ++r) { + for (ParallelSeq::riterator r = PS->rbegin(), re = PS->rend(); + r != re; ++r) { + std::vector JoinValues; ParallelRegion *PR = *r; std::vector RegionBlocks(PR->begin(), PR->end()); + if (RegionBlocks.empty()) continue; // Ensure that there is only one block in this region assert(RegionBlocks.size() == 1 && "Parallel region has > 1 BB"); @@ -84,15 +99,17 @@ // Replace call with __llvm_thread_create Function *ThCreate = getFuncThreadStart(*F.getParent()); - assert(OldCall->getNumOperands() == 2 && - "Can only threadify calls with one argument!"); + assert(OldCall->getNumOperands() <= 2 && + "Can only threadify calls with at most one argument!"); TerminatorInst *TI = BB->getTerminator(); CastInst *funcPtr = new CastInst(OldCall->getOperand(0), startTy, "cast_ptr", TI); - CastInst *funcVal = new CastInst(OldCall->getOperand(1), - PointerType::get(Type::SByteTy), - "cast_val", TI); + Value *funcVal = Constant::getNullValue(PointerType::get(Type::SByteTy)); + if (OldCall->getNumOperands() == 2) + funcVal = new CastInst(OldCall->getOperand(1), + PointerType::get(Type::SByteTy), + "cast_val", TI); std::vector Args; Args.push_back(funcPtr); Args.push_back(funcVal); @@ -101,24 +118,29 @@ OldCall->getParent()->getInstList().erase(OldCall); + for (std::vector::iterator BBr = RegionBlocks.begin(), + BBre = RegionBlocks.end(); BBr != BBre; ++BBr) + PR->removeBasicBlock(*BBr); + + // Convert llvm.join() intrinsic to __llvm_thread_join() calls + // Get join function call position/bb + ParaBrInst *Pbr = dyn_cast(PS->getHeader()->getTerminator()); + Function *ThJoin = getFuncThreadJoin(*F.getParent()); + assert(Pbr && "Terminator of parallel sequence header is not a Pbr!"); + BBVec &JoinBlocks = PR->getJoinBlocks(); + for (BBVec::iterator j = JoinBlocks.begin(), je = JoinBlocks.end(); + j != je; ++j) + for (BasicBlock::iterator i = (*j)->begin(), e=(*j)->end(); i!=e; ++i) + if (CallInst *CI = dyn_cast(i)) + if (CI->getCalledFunction()->getName() == "llvm.join" && + findPbr(CI->getOperand(1), Pbr)) + for (std::vector::iterator val = JoinValues.begin(), + ve = JoinValues.end(); val != ve; ++val) + CallInst *Join = new CallInst(ThJoin, *val, "", CI); + Changed = true; } - // Convert llvm.join() intrinsic to __llvm_thread_join() calls - // Get join function call position/bb - ParaBrInst *Pbr = dyn_cast(PS->getHeader()->getTerminator()); - assert(Pbr && "Terminator of parallel sequence header is not a Pbr!"); - - std::vector Users(Pbr->use_begin(), Pbr->use_end()); - assert(Users.size() == 1 && "Must have unique user of Pbr"); - CallInst *JoinCall = cast(Users[0]); - assert(JoinCall && "Pbr result used in something other than call!"); - - Function *ThJoin = getFuncThreadJoin(*F.getParent()); - TerminatorInst *JoinBBTerm = JoinCall->getParent()->getTerminator(); - for (std::vector::iterator val = JoinValues.begin(), - ve = JoinValues.end(); val != ve; ++val) - CallInst *Join = new CallInst(ThJoin, *val, "", JoinBBTerm); } return Changed; From brukman at cs.uiuc.edu Fri May 7 16:39:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri May 7 16:39:01 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/Transforms/Parallel/ParallelSeqExtractor.cpp Message-ID: <200405072139.QAA21479@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Parallel: ParallelSeqExtractor.cpp added (r1.1.2.1) --- Log message: Extract parallel sequences into separate functions (aggregating arguments) so that we can spawn off those functions as threads. Note: this does not properly take care of cases where code is shared among parallel regions/sequences. --- Diffs of the changes: (+148 -0) Index: llvm/lib/Transforms/Parallel/ParallelSeqExtractor.cpp diff -c /dev/null llvm/lib/Transforms/Parallel/ParallelSeqExtractor.cpp:1.1.2.1 *** /dev/null Fri May 7 16:39:13 2004 --- llvm/lib/Transforms/Parallel/ParallelSeqExtractor.cpp Fri May 7 16:39:02 2004 *************** *** 0 **** --- 1,148 ---- + //===- PSeqExtractor.cpp - Pull parallel seqs into new functions ----------===// + // + // 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 interface to tear out parallel seqs into a new + // function, replacing it with a call to the new function. + // + //===----------------------------------------------------------------------===// + + #include "llvm/Instructions.h" + #include "llvm/Module.h" + #include "llvm/BasicBlock.h" + #include "llvm/Analysis/Dominators.h" + #include "llvm/Analysis/ParallelInfo.h" + #include "llvm/Transforms/Utils/FunctionUtils.h" + #include "llvm/Support/CFG.h" + #include "Support/Debug.h" + #include + using namespace llvm; + + namespace { + + /// PSeqExtractor - + /// + /// FIXME: This should be a Pass, but Passes currently cannot require + /// FunctionPasses. + /// + struct PSeqExtractor : public FunctionPass { + public: + PSeqExtractor() {} + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + AU.addRequired(); + } + + bool runOnFunction(Function &F); + private: + bool containsThreadCall(BasicBlock *BB); + }; + + // FIXME: need to specify threshold level.. ie, up to 2 nested pseqs become + // new functions, then everything else sequential + RegisterOpt + X("pseq-extract", "Extract parallel seqs into new functions"); + + } // End anonymous namespace + + static bool contains(std::vector &haystack, + BasicBlock *needle) { + return std::find(haystack.begin(), haystack.end(), needle) != haystack.end(); + } + + static void intersect(std::vector &a, + std::vector &b, + std::vector &intersection) { + for (unsigned i = 0, e = a.size(); i != e; ++i) + for (unsigned j = 0, f = b.size(); j != f; ++j) + if (a[i] == b[j]) + intersection.push_back(a[i]); + } + + static BasicBlock* clone(BasicBlock *BB) { + BasicBlock *newBB = new BasicBlock(BB->getName(), BB->getParent()); + for (BasicBlock::iterator i = BB->begin(), e = BB->end(); i != e; ++i) + newBB->getInstList().push_back(i->clone()); + return newBB; + } + + /// runOnFunction - + /// + bool PSeqExtractor::runOnFunction(Function &F) { + bool Changed = false; + DEBUG(std::cerr << "Running on: " << F.getName() << "\n"); + ParallelInfo &PI = getAnalysis(); + DominatorSet &DS = getAnalysis(); + + #if 0 + // If there is shared code in the ParallelRegions, make copies + // 1. find intersecting code region + for (ParallelInfo::iterator i = PI.begin(), e = PI.end(); i != e; ++i) { + ParallelSeq *PS = *i; + ParallelRegion* PR[2]; + unsigned i=0, e=0; + for (ParallelSeq::riterator r = PS->rbegin(), re = PS->rend(); + r!=re; ++r, ++i) PR[i] = *r; + std::vector Blocks0(PR[0]->begin(), PR[0]->end()); + std::vector Blocks1(PR[1]->begin(), PR[1]->end()); + std::vector Intersection; + intersect(Blocks0, Blocks1, Intersection); + + // 2. for each basic block in shared code: + // clone block + // all incoming/outgoing edges to/from region0 stay, + // all incoming/outgoing edges to/from region1 redirected to/from clone + for (i = 0, e = Intersection.size(); i != e; ++i) { + BasicBlock *I = Intersection[i]; + BasicBlock *newBB = clone(I); + for (pred_iterator p = pred_begin(I), pe = pred_end(I); p != pe; ++p) { + BasicBlock *pred = *p; + if (contains(Blocks1, pred)) + pred->getTerminator()->replaceUsesOfWith(I, newBB); + } + for (succ_iterator s = succ_begin(newBB), se = succ_end(newBB); s != se; + ++s) { + BasicBlock *succ = *s; + if (contains(Blocks1, succ)) { + BasicBlock *newSucc = clone(succ); + newBB->getTerminator()->replaceUsesOfWith(succ, newSucc); + } + } + } + } + #endif + + // extract each code region to a new function + for (ParallelInfo::iterator i = PI.begin(), e = PI.end(); i != e; ++i) { + ParallelSeq *PS = *i; + for (ParallelSeq::riterator r = PS->rbegin(), re = PS->rend(); r!=re; ++r) { + Changed = true; + ParallelRegion *PR = *r; + std::vector RegionBlocks(PR->begin(), PR->end()); + if (RegionBlocks.empty()) continue; + if (containsThreadCall(RegionBlocks[0])) continue; + ExtractCodeRegion(DS, RegionBlocks, true /* aggregate args */); + for (std::vector::iterator BBr = RegionBlocks.begin(), + BBre = RegionBlocks.end(); BBr != BBre; ++BBr) + PR->removeBasicBlock(*BBr); + } + } + + return Changed; + } + + bool PSeqExtractor::containsThreadCall(BasicBlock *BB) { + static const std::string llvmThreadFn("__llvm_thread_start"); + for (BasicBlock::iterator i = BB->begin(), e = BB->end(); i != e; ++i) + if (CallInst *CI = dyn_cast(i)) + if (CI->getCalledFunction()->getName() == llvmThreadFn) + return true; + + return false; + } From gaeke at cs.uiuc.edu Fri May 7 16:47:02 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Fri May 7 16:47:02 2004 Subject: [llvm-commits] CVS: llvm/tools/gccld/gccld.cpp Message-ID: <200405072147.QAA21959@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccld: gccld.cpp updated: 1.70 -> 1.71 --- Log message: Allow the user to set the LLVMINTERP environment variable as a workaround, for when they have to run a gccld shell script without having lli in their path. This is intended to address Bug 289: http://llvm.cs.uiuc.edu/PR289 . Also, emit the traditional syntax ${1+"$@"} for passing all of a shell script's args to a subprocess. If you have arguments that have spaces in them, $* will not preserve the quoting (i.e., the quoted string "foo bar" as an argument will end up as two arguments "foo" "bar" to lli.) --- Diffs of the changes: (+5 -2) Index: llvm/tools/gccld/gccld.cpp diff -u llvm/tools/gccld/gccld.cpp:1.70 llvm/tools/gccld/gccld.cpp:1.71 --- llvm/tools/gccld/gccld.cpp:1.70 Tue Apr 6 11:43:13 2004 +++ llvm/tools/gccld/gccld.cpp Fri May 7 16:47:36 2004 @@ -309,7 +309,10 @@ if (!Out2.good()) return PrintAndReturn(argv[0], "error opening '" + OutputFilename + "' for writing!"); - Out2 << "#!/bin/sh\nlli \\\n"; + Out2 << "#!/bin/sh\n"; + // Allow user to setenv LLVMINTERP if lli is not in their PATH. + Out2 << "lli=${LLVMINTERP-lli}\n"; + Out2 << "exec $lli \\\n"; // gcc accepts -l and implicitly searches /lib and /usr/lib. LibPaths.push_back("/lib"); LibPaths.push_back("/usr/lib"); @@ -327,7 +330,7 @@ if (!FullLibraryPath.empty() && IsSharedObject(FullLibraryPath)) Out2 << " -load=" << FullLibraryPath << " \\\n"; } - Out2 << " $0.bc $*\n"; + Out2 << " $0.bc ${1+\"$@\"}\n"; Out2.close(); } From lattner at cs.uiuc.edu Fri May 7 17:09:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri May 7 17:09:02 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200405072209.RAA23771@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.199 -> 1.200 --- Log message: Implement folding of GEP's like: %tmp.0 = getelementptr [50 x sbyte]* %ar, uint 0, int 5 ; [#uses=2] %tmp.7 = getelementptr sbyte* %tmp.0, int 8 ; [#uses=1] together. This patch actually allows us to simplify and generalize the code. --- Diffs of the changes: (+43 -53) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.199 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.200 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.199 Fri May 7 10:35:56 2004 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Fri May 7 17:09:22 2004 @@ -2535,17 +2535,18 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) { + Value *PtrOp = GEP.getOperand(0); // Is it 'getelementptr %P, long 0' or 'getelementptr %P' // If so, eliminate the noop. if (GEP.getNumOperands() == 1) - return ReplaceInstUsesWith(GEP, GEP.getOperand(0)); + return ReplaceInstUsesWith(GEP, PtrOp); bool HasZeroPointerIndex = false; if (Constant *C = dyn_cast(GEP.getOperand(1))) HasZeroPointerIndex = C->isNullValue(); if (GEP.getNumOperands() == 2 && HasZeroPointerIndex) - return ReplaceInstUsesWith(GEP, GEP.getOperand(0)); + return ReplaceInstUsesWith(GEP, PtrOp); // Eliminate unneeded casts for indices. bool MadeChange = false; @@ -2601,46 +2602,37 @@ // getelementptr instructions into a single instruction. // std::vector SrcGEPOperands; - if (GetElementPtrInst *Src = dyn_cast(GEP.getOperand(0))) { + if (GetElementPtrInst *Src = dyn_cast(PtrOp)) { SrcGEPOperands.assign(Src->op_begin(), Src->op_end()); - } else if (ConstantExpr *CE = dyn_cast(GEP.getOperand(0))) { + } else if (ConstantExpr *CE = dyn_cast(PtrOp)) { if (CE->getOpcode() == Instruction::GetElementPtr) SrcGEPOperands.assign(CE->op_begin(), CE->op_end()); } if (!SrcGEPOperands.empty()) { + // Note that if our source is a gep chain itself that we wait for that + // chain to be resolved before we perform this transformation. This + // avoids us creating a TON of code in some cases. + // + if (isa(SrcGEPOperands[0]) && + cast(SrcGEPOperands[0])->getNumOperands() == 2) + return 0; // Wait until our source is folded to completion. + std::vector Indices; + + // Find out whether the last index in the source GEP is a sequential idx. + bool EndsWithSequential = false; + for (gep_type_iterator I = gep_type_begin(*cast(PtrOp)), + E = gep_type_end(*cast(PtrOp)); I != E; ++I) + if (!isa(*I)) + EndsWithSequential = true; // Can we combine the two pointer arithmetics offsets? - if (SrcGEPOperands.size() == 2 && isa(SrcGEPOperands[1]) && - isa(GEP.getOperand(1))) { - Constant *SGC = cast(SrcGEPOperands[1]); - Constant *GC = cast(GEP.getOperand(1)); - if (SGC->getType() != GC->getType()) { - SGC = ConstantExpr::getSignExtend(SGC, Type::LongTy); - GC = ConstantExpr::getSignExtend(GC, Type::LongTy); - } - - // Replace: gep (gep %P, long C1), long C2, ... - // With: gep %P, long (C1+C2), ... - GEP.setOperand(0, SrcGEPOperands[0]); - GEP.setOperand(1, ConstantExpr::getAdd(SGC, GC)); - if (Instruction *I = dyn_cast(GEP.getOperand(0))) - AddUsersToWorkList(*I); // Reduce use count of Src - return &GEP; - } else if (SrcGEPOperands.size() == 2) { + if (EndsWithSequential) { // Replace: gep (gep %P, long B), long A, ... // With: T = long A+B; gep %P, T, ... // - // Note that if our source is a gep chain itself that we wait for that - // chain to be resolved before we perform this transformation. This - // avoids us creating a TON of code in some cases. - // - if (isa(SrcGEPOperands[0]) && - cast(SrcGEPOperands[0])->getNumOperands() == 2) - return 0; // Wait until our source is folded to completion. - - Value *Sum, *SO1 = SrcGEPOperands[1], *GO1 = GEP.getOperand(1); + Value *Sum, *SO1 = SrcGEPOperands.back(), *GO1 = GEP.getOperand(1); if (SO1 == Constant::getNullValue(SO1->getType())) { Sum = GO1; } else if (GO1 == Constant::getNullValue(GO1->getType())) { @@ -2670,13 +2662,26 @@ } } } - Sum = BinaryOperator::create(Instruction::Add, SO1, GO1, - GEP.getOperand(0)->getName()+".sum", &GEP); - WorkList.push_back(cast(Sum)); + if (isa(SO1) && isa(GO1)) + Sum = ConstantExpr::getAdd(cast(SO1), cast(GO1)); + else { + Sum = BinaryOperator::create(Instruction::Add, SO1, GO1, + PtrOp->getName()+".sum", &GEP); + WorkList.push_back(cast(Sum)); + } + } + + // Recycle the GEP we already have if possible. + if (SrcGEPOperands.size() == 2) { + GEP.setOperand(0, SrcGEPOperands[0]); + GEP.setOperand(1, Sum); + return &GEP; + } else { + Indices.insert(Indices.end(), SrcGEPOperands.begin()+1, + SrcGEPOperands.end()-1); + Indices.push_back(Sum); + Indices.insert(Indices.end(), GEP.op_begin()+2, GEP.op_end()); } - GEP.setOperand(0, SrcGEPOperands[0]); - GEP.setOperand(1, Sum); - return &GEP; } else if (isa(*GEP.idx_begin()) && cast(*GEP.idx_begin())->isNullValue() && SrcGEPOperands.size() != 1) { @@ -2684,27 +2689,12 @@ Indices.insert(Indices.end(), SrcGEPOperands.begin()+1, SrcGEPOperands.end()); Indices.insert(Indices.end(), GEP.idx_begin()+1, GEP.idx_end()); - } else if (SrcGEPOperands.back() == - Constant::getNullValue(SrcGEPOperands.back()->getType())) { - // We have to check to make sure this really is an ARRAY index we are - // ending up with, not a struct index. - generic_gep_type_iterator::iterator> - GTI = gep_type_begin(SrcGEPOperands[0]->getType(), - SrcGEPOperands.begin()+1, SrcGEPOperands.end()); - std::advance(GTI, SrcGEPOperands.size()-2); - if (isa(*GTI)) { - // If the src gep ends with a constant array index, merge this get into - // it, even if we have a non-zero array index. - Indices.insert(Indices.end(), SrcGEPOperands.begin()+1, - SrcGEPOperands.end()-1); - Indices.insert(Indices.end(), GEP.idx_begin(), GEP.idx_end()); - } } if (!Indices.empty()) return new GetElementPtrInst(SrcGEPOperands[0], Indices, GEP.getName()); - } else if (GlobalValue *GV = dyn_cast(GEP.getOperand(0))) { + } else if (GlobalValue *GV = dyn_cast(PtrOp)) { // GEP of global variable. If all of the indices for this GEP are // constants, we can promote this to a constexpr instead of an instruction. @@ -2721,7 +2711,7 @@ // Replace all uses of the GEP with the new constexpr... return ReplaceInstUsesWith(GEP, CE); } - } else if (ConstantExpr *CE = dyn_cast(GEP.getOperand(0))) { + } else if (ConstantExpr *CE = dyn_cast(PtrOp)) { if (CE->getOpcode() == Instruction::Cast) { if (HasZeroPointerIndex) { // transform: GEP (cast [10 x ubyte]* X to [0 x ubyte]*), long 0, ... From alkis at cs.uiuc.edu Fri May 7 22:49:01 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri May 7 22:49:01 2004 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveIntervals.cpp Message-ID: <200405080349.WAA25468@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveIntervals.cpp updated: 1.72 -> 1.73 --- Log message: Remove unneeded header --- Diffs of the changes: (+0 -1) Index: llvm/lib/CodeGen/LiveIntervals.cpp diff -u llvm/lib/CodeGen/LiveIntervals.cpp:1.72 llvm/lib/CodeGen/LiveIntervals.cpp:1.73 --- llvm/lib/CodeGen/LiveIntervals.cpp:1.72 Thu May 6 11:25:59 2004 +++ llvm/lib/CodeGen/LiveIntervals.cpp Fri May 7 22:49:35 2004 @@ -34,7 +34,6 @@ #include "VirtRegMap.h" #include #include -#include using namespace llvm; From alkis at cs.uiuc.edu Fri May 7 22:50:00 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri May 7 22:50:00 2004 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAllocLinearScan.cpp Message-ID: <200405080350.WAA25487@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocLinearScan.cpp updated: 1.71 -> 1.72 --- Log message: Add required header --- Diffs of the changes: (+1 -0) Index: llvm/lib/CodeGen/RegAllocLinearScan.cpp diff -u llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.71 llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.72 --- llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.71 Thu May 6 11:25:59 2004 +++ llvm/lib/CodeGen/RegAllocLinearScan.cpp Fri May 7 22:50:03 2004 @@ -25,6 +25,7 @@ #include "PhysRegTracker.h" #include "VirtRegMap.h" #include +#include #include using namespace llvm; From tbrethou at cs.uiuc.edu Sat May 8 11:13:04 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat May 8 11:13:04 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetSchedInfo.cpp Message-ID: <200405081613.LAA18929@seraph.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetSchedInfo.cpp updated: 1.16 -> 1.17 --- Log message: Changed CPUResource to allow access to maxnum users. --- Diffs of the changes: (+16 -6) Index: llvm/lib/Target/TargetSchedInfo.cpp diff -u llvm/lib/Target/TargetSchedInfo.cpp:1.16 llvm/lib/Target/TargetSchedInfo.cpp:1.17 --- llvm/lib/Target/TargetSchedInfo.cpp:1.16 Sat May 1 06:17:13 2004 +++ llvm/lib/Target/TargetSchedInfo.cpp Sat May 8 11:12:50 2004 @@ -14,13 +14,25 @@ #include "llvm/Target/TargetSchedInfo.h" #include "llvm/Target/TargetMachine.h" +#include +using namespace llvm; -namespace llvm { +resourceId_t llvm::CPUResource::nextId = 0; +static std::vector *CPUResourceMap = 0; + +CPUResource::CPUResource(const std::string& resourceName, int maxUsers) + : rname(resourceName), rid(nextId++), maxNumUsers(maxUsers) { + if(!CPUResourceMap) + CPUResourceMap = new std::vector; -resourceId_t CPUResource::nextId = 0; + //Put Resource in the map + CPUResourceMap->push_back(this); +} -CPUResource::CPUResource(const std::string& resourceName, int maxUsers) - : rname(resourceName), rid(nextId++), maxNumUsers(maxUsers) {} +///Get CPUResource if you only have the resource ID +CPUResource* CPUResource::getCPUResource(resourceId_t id) { + return (*CPUResourceMap)[id]; +} // Check if fromRVec and toRVec have *any* common entries. // Assume the vectors are sorted in increasing order. @@ -254,5 +266,3 @@ assert(r >= 0 && "Resource to remove was unused in cycle c!"); } } - -} // End llvm namespace From tbrethou at cs.uiuc.edu Sat May 8 11:13:19 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat May 8 11:13:19 2004 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.cpp MSchedGraph.h ModuloScheduling.cpp ModuloScheduling.h Message-ID: <200405081612.LAA18917@seraph.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/ModuloScheduling: MSchedGraph.cpp updated: 1.1 -> 1.2 MSchedGraph.h updated: 1.1 -> 1.2 ModuloScheduling.cpp updated: 1.16 -> 1.17 ModuloScheduling.h updated: 1.11 -> 1.12 --- Log message: Updating my versions of ModuloScheduling in cvs. Still not complete. --- Diffs of the changes: (+863 -306) Index: llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.cpp diff -u llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.cpp:1.1 llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.cpp:1.2 --- llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.cpp:1.1 Sun Feb 29 20:50:57 2004 +++ llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.cpp Sat May 8 11:12:10 2004 @@ -29,7 +29,7 @@ } void MSchedGraphNode::print(std::ostream &os) const { - os << "MSehedGraphNode: Inst=" << *Inst << ", latency= " << latency << "\n"; + os << "MSchedGraphNode: Inst=" << *Inst << ", latency= " << latency << "\n"; } MSchedGraphEdge MSchedGraphNode::getInEdge(MSchedGraphNode *pred) { @@ -41,9 +41,38 @@ return I.getEdge(); } assert(0 && "Should have found edge between this node and its predecessor!"); - + } +unsigned MSchedGraphNode::getInEdgeNum(MSchedGraphNode *pred) { + //Loop over all the successors of our predecessor + //return the edge the corresponds to this in edge + int count = 0; + for(MSchedGraphNode::succ_iterator I = pred->succ_begin(), E = pred->succ_end(); + I != E; ++I) { + if(*I == this) + return count; + count++; + } + assert(0 && "Should have found edge between this node and its predecessor!"); + abort(); +} +bool MSchedGraphNode::isSuccessor(MSchedGraphNode *succ) { + for(succ_iterator I = succ_begin(), E = succ_end(); I != E; ++I) + if(*I == succ) + return true; + return false; +} + + +bool MSchedGraphNode::isPredecessor(MSchedGraphNode *pred) { + if(find( Predecessors.begin(), Predecessors.end(), pred) != Predecessors.end()) + return true; + else + return false; +} + + void MSchedGraph::addNode(const MachineInstr *MI, MSchedGraphNode *node) { @@ -92,12 +121,15 @@ MachineOpCode MIopCode = MI->getOpcode(); int delay; +#if 0 // FIXME: LOOK INTO THIS //Check if subsequent instructions can be issued before //the result is ready, if so use min delay. if(MTI.hasResultInterlock(MIopCode)) delay = MTI.minLatency(MIopCode); else - delay = MTI.maxLatency(MIopCode); +#endif + /// FIxME: get this from the sched class. + delay = 7; //MTI.maxLatency(MIopCode); //Create new node for this machine instruction and add to the graph. //Create only if not a nop Index: llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.h diff -u llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.h:1.1 llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.h:1.2 --- llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.h:1.1 Sun Feb 29 20:50:57 2004 +++ llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.h Sat May 8 11:12:10 2004 @@ -99,6 +99,10 @@ bool hasSuccessors() { return (Successors.size() > 0); } int getLatency() { return latency; } MSchedGraphEdge getInEdge(MSchedGraphNode *pred); + unsigned getInEdgeNum(MSchedGraphNode *pred); + + bool isSuccessor(MSchedGraphNode *); + bool isPredecessor(MSchedGraphNode *); //Debug support void print(std::ostream &os) const; Index: llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp diff -u llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp:1.16 llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp:1.17 --- llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp:1.16 Sun Feb 29 20:50:01 2004 +++ llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp Sat May 8 11:12:10 2004 @@ -20,12 +20,14 @@ #include "llvm/Target/TargetSchedInfo.h" #include "Support/Debug.h" #include "Support/GraphWriter.h" +#include "Support/StringExtras.h" #include #include #include #include #include + using namespace llvm; /// Create ModuloSchedulingPass @@ -88,14 +90,20 @@ edgelabel = "Unknown"; break; } - if(I.getEdge().getIteDiff() > 0) - edgelabel += I.getEdge().getIteDiff(); - - return edgelabel; - } + //FIXME + int iteDiff = I.getEdge().getIteDiff(); + std::string intStr = "(IteDiff: "; + intStr += itostr(iteDiff); + intStr += ")"; + edgelabel += intStr; + return edgelabel; + } + + + }; } @@ -114,7 +122,7 @@ MSchedGraph *MSG = new MSchedGraph(BI, target); //Write Graph out to file - DEBUG(WriteGraphToFile(std::cerr, "dependgraph", MSG)); + DEBUG(WriteGraphToFile(std::cerr, F.getName(), MSG)); //Print out BB for debugging DEBUG(BI->print(std::cerr)); @@ -122,9 +130,64 @@ //Calculate Resource II int ResMII = calculateResMII(BI); + //Calculate Recurrence II + int RecMII = calculateRecMII(MSG, ResMII); + + II = std::max(RecMII, ResMII); + + DEBUG(std::cerr << "II starts out as " << II << "\n"); + + //Calculate Node Properties calculateNodeAttributes(MSG, ResMII); + + //Dump node properties if in debug mode + for(std::map::iterator I = nodeToAttributesMap.begin(), E = nodeToAttributesMap.end(); I !=E; ++I) { + DEBUG(std::cerr << "Node: " << *(I->first) << " ASAP: " << I->second.ASAP << " ALAP: " << I->second.ALAP << " MOB: " << I->second.MOB << " Depth: " << I->second.depth << " Height: " << I->second.height << "\n"); + } + + //Put nodes in order to schedule them + computePartialOrder(); + + //Dump out partial order + for(std::vector >::iterator I = partialOrder.begin(), E = partialOrder.end(); I !=E; ++I) { + DEBUG(std::cerr << "Start set in PO\n"); + for(std::vector::iterator J = I->begin(), JE = I->end(); J != JE; ++J) + DEBUG(std::cerr << "PO:" << **J << "\n"); + } + + orderNodes(); + + //Dump out order of nodes + for(std::vector::iterator I = FinalNodeOrder.begin(), E = FinalNodeOrder.end(); I != E; ++I) + DEBUG(std::cerr << "FO:" << **I << "\n"); + + + //Finally schedule nodes + computeSchedule(); + + + //Dump out final schedule + //std::cerr << "FINALSCHEDULE\n"; + //Dump out current schedule + /*for(std::map > >::iterator J = schedule.begin(), + JE = schedule.end(); J != JE; ++J) { + std::cerr << "Cycle " << J->first << ":\n"; + for(std::vector >::iterator VI = J->second.begin(), VE = J->second.end(); VI != VE; ++VI) + std::cerr << "Resource ID: " << VI->first << " by node " << *(VI->second) << "\n"; + } + std::cerr << "END FINAL SCHEDULE\n"; + + DEBUG(std::cerr << "II ends up as " << II << "\n"); + */ + + + nodeToAttributesMap.clear(); + partialOrder.clear(); + recurrenceList.clear(); + FinalNodeOrder.clear(); + schedule.clear(); + } - } } @@ -201,8 +264,8 @@ //Find maximum usage count - //Get max number of instructions that can be issued at once. - int issueSlots = msi.maxNumIssueTotal; + //Get max number of instructions that can be issued at once. (FIXME) + int issueSlots = 1; // msi.maxNumIssueTotal; for(std::map::iterator RB = resourceUsageCount.begin(), RE = resourceUsageCount.end(); RB != RE; ++RB) { //Get the total number of the resources in our cpu @@ -228,10 +291,34 @@ } DEBUG(std::cerr << "Final Resource MII: " << ResMII << "\n"); + return ResMII; } +int ModuloSchedulingPass::calculateRecMII(MSchedGraph *graph, int MII) { + std::vector vNodes; + //Loop over all nodes in the graph + for(MSchedGraph::iterator I = graph->begin(), E = graph->end(); I != E; ++I) { + findAllReccurrences(I->second, vNodes, MII); + vNodes.clear(); + } + + int RecMII = 0; + + for(std::set > >::iterator I = recurrenceList.begin(), E=recurrenceList.end(); I !=E; ++I) { + std::cerr << "Recurrence: \n"; + for(std::vector::const_iterator N = I->second.begin(), NE = I->second.end(); N != NE; ++N) { + std::cerr << **N << "\n"; + } + RecMII = std::max(RecMII, I->first); + std::cerr << "End Recurrence with RecMII: " << I->first << "\n"; + } + DEBUG(std::cerr << "RecMII: " << RecMII << "\n"); + + return MII; +} + void ModuloSchedulingPass::calculateNodeAttributes(MSchedGraph *graph, int MII) { //Loop over the nodes and add them to the map @@ -245,114 +332,135 @@ //Create set to deal with reccurrences std::set visitedNodes; - std::vector vNodes; + //Now Loop over map and calculate the node attributes for(std::map::iterator I = nodeToAttributesMap.begin(), E = nodeToAttributesMap.end(); I != E; ++I) { - // calculateASAP(I->first, (I->second), MII, visitedNodes); - findAllReccurrences(I->first, vNodes); - vNodes.clear(); + calculateASAP(I->first, MII, (MSchedGraphNode*) 0); visitedNodes.clear(); } + int maxASAP = findMaxASAP(); //Calculate ALAP which depends on ASAP being totally calculated - /*for(std::map::iterator I = nodeToAttributesMap.begin(), E = nodeToAttributesMap.end(); I != E; ++I) { - calculateALAP(I->first, (I->second), MII, MII, visitedNodes); + for(std::map::iterator I = nodeToAttributesMap.begin(), E = nodeToAttributesMap.end(); I != E; ++I) { + calculateALAP(I->first, MII, maxASAP, (MSchedGraphNode*) 0); visitedNodes.clear(); - }*/ + } //Calculate MOB which depends on ASAP being totally calculated, also do depth and height - /*for(std::map::iterator I = nodeToAttributesMap.begin(), E = nodeToAttributesMap.end(); I != E; ++I) { - (I->second).MOB = (I->second).ALAP - (I->second).ASAP; + for(std::map::iterator I = nodeToAttributesMap.begin(), E = nodeToAttributesMap.end(); I != E; ++I) { + (I->second).MOB = std::max(0,(I->second).ALAP - (I->second).ASAP); + DEBUG(std::cerr << "MOB: " << (I->second).MOB << " (" << *(I->first) << ")\n"); - calculateDepth(I->first, (I->second), visitedNodes); - visitedNodes.clear(); - calculateHeight(I->first, (I->second), visitedNodes); - visitedNodes.clear(); - }*/ + calculateDepth(I->first, (MSchedGraphNode*) 0); + calculateHeight(I->first, (MSchedGraphNode*) 0); + } + + +} +bool ModuloSchedulingPass::ignoreEdge(MSchedGraphNode *srcNode, MSchedGraphNode *destNode) { + if(destNode == 0 || srcNode ==0) + return false; + bool findEdge = edgesToIgnore.count(std::make_pair(srcNode, destNode->getInEdgeNum(srcNode))); + DEBUG(std::cerr << "Ignore Edge from " << *srcNode << " to " << *destNode << "? " << findEdge << "\n"); + return findEdge; } -void ModuloSchedulingPass::calculateASAP(MSchedGraphNode *node, MSNodeAttributes &attributes, - int MII, std::set &visitedNodes) { +int ModuloSchedulingPass::calculateASAP(MSchedGraphNode *node, int MII, MSchedGraphNode *destNode) { DEBUG(std::cerr << "Calculating ASAP for " << *node << "\n"); - if(attributes.ASAP != -1 || (visitedNodes.find(node) != visitedNodes.end())) { - visitedNodes.erase(node); - return; - } - if(node->hasPredecessors()) { - int maxPredValue = 0; - - //Iterate over all of the predecessors and fine max - for(MSchedGraphNode::pred_iterator P = node->pred_begin(), E = node->pred_end(); P != E; ++P) { + //Get current node attributes + MSNodeAttributes &attributes = nodeToAttributesMap.find(node)->second; - //Get that nodes ASAP - MSNodeAttributes predAttributes = nodeToAttributesMap.find(*P)->second; - if(predAttributes.ASAP == -1) { - //Put into set before you recurse - visitedNodes.insert(node); - calculateASAP(*P, predAttributes, MII, visitedNodes); - predAttributes = nodeToAttributesMap.find(*P)->second; - } + if(attributes.ASAP != -1) + return attributes.ASAP; + + int maxPredValue = 0; + + //Iterate over all of the predecessors and find max + for(MSchedGraphNode::pred_iterator P = node->pred_begin(), E = node->pred_end(); P != E; ++P) { + + //Only process if we are not ignoring the edge + if(!ignoreEdge(*P, node)) { + int predASAP = -1; + predASAP = calculateASAP(*P, MII, node); + + assert(predASAP != -1 && "ASAP has not been calculated"); int iteDiff = node->getInEdge(*P).getIteDiff(); - - int currentPredValue = predAttributes.ASAP + node->getLatency() - iteDiff * MII; - DEBUG(std::cerr << "Current ASAP pred: " << currentPredValue << "\n"); + + int currentPredValue = predASAP + (*P)->getLatency() - (iteDiff * MII); + DEBUG(std::cerr << "pred ASAP: " << predASAP << ", iteDiff: " << iteDiff << ", PredLatency: " << (*P)->getLatency() << ", Current ASAP pred: " << currentPredValue << "\n"); maxPredValue = std::max(maxPredValue, currentPredValue); } - visitedNodes.erase(node); - attributes.ASAP = maxPredValue; - } - else { - visitedNodes.erase(node); - attributes.ASAP = 0; } + + attributes.ASAP = maxPredValue; DEBUG(std::cerr << "ASAP: " << attributes.ASAP << " (" << *node << ")\n"); + + return maxPredValue; } -void ModuloSchedulingPass::calculateALAP(MSchedGraphNode *node, MSNodeAttributes &attributes, - int MII, int maxASAP, - std::set &visitedNodes) { - - DEBUG(std::cerr << "Calculating AlAP for " << *node << "\n"); - - if(attributes.ALAP != -1|| (visitedNodes.find(node) != visitedNodes.end())) { - visitedNodes.erase(node); - return; - } +int ModuloSchedulingPass::calculateALAP(MSchedGraphNode *node, int MII, + int maxASAP, MSchedGraphNode *srcNode) { + + DEBUG(std::cerr << "Calculating ALAP for " << *node << "\n"); + + MSNodeAttributes &attributes = nodeToAttributesMap.find(node)->second; + + if(attributes.ALAP != -1) + return attributes.ALAP; + if(node->hasSuccessors()) { - int minSuccValue = 0; + + //Trying to deal with the issue where the node has successors, but + //we are ignoring all of the edges to them. So this is my hack for + //now.. there is probably a more elegant way of doing this (FIXME) + bool processedOneEdge = false; + + //FIXME, set to something high to start + int minSuccValue = 9999999; //Iterate over all of the predecessors and fine max for(MSchedGraphNode::succ_iterator P = node->succ_begin(), E = node->succ_end(); P != E; ++P) { - - MSNodeAttributes succAttributes = nodeToAttributesMap.find(*P)->second; - if(succAttributes.ASAP == -1) { + + //Only process if we are not ignoring the edge + if(!ignoreEdge(node, *P)) { + processedOneEdge = true; + int succALAP = -1; + succALAP = calculateALAP(*P, MII, maxASAP, node); + + assert(succALAP != -1 && "Successors ALAP should have been caclulated"); + + int iteDiff = P.getEdge().getIteDiff(); - //Put into set before recursing - visitedNodes.insert(node); + int currentSuccValue = succALAP - node->getLatency() + iteDiff * MII; + + DEBUG(std::cerr << "succ ALAP: " << succALAP << ", iteDiff: " << iteDiff << ", SuccLatency: " << (*P)->getLatency() << ", Current ALAP succ: " << currentSuccValue << "\n"); - calculateALAP(*P, succAttributes, MII, maxASAP, visitedNodes); - succAttributes = nodeToAttributesMap.find(*P)->second; - assert(succAttributes.ASAP == -1 && "Successors ALAP should have been caclulated"); + minSuccValue = std::min(minSuccValue, currentSuccValue); } - int iteDiff = P.getEdge().getIteDiff(); - int currentSuccValue = succAttributes.ALAP + node->getLatency() + iteDiff * MII; - minSuccValue = std::min(minSuccValue, currentSuccValue); } - visitedNodes.erase(node); - attributes.ALAP = minSuccValue; + + if(processedOneEdge) + attributes.ALAP = minSuccValue; + + else + attributes.ALAP = maxASAP; } - else { - visitedNodes.erase(node); + else attributes.ALAP = maxASAP; - } + DEBUG(std::cerr << "ALAP: " << attributes.ALAP << " (" << *node << ")\n"); + + if(attributes.ALAP < 0) + attributes.ALAP = 0; + + return attributes.ALAP; } int ModuloSchedulingPass::findMaxASAP() { @@ -365,127 +473,303 @@ } -void ModuloSchedulingPass::calculateHeight(MSchedGraphNode *node, - MSNodeAttributes &attributes, - std::set &visitedNodes) { - - if(attributes.depth != -1 || (visitedNodes.find(node) != visitedNodes.end())) { - //Remove from map before returning - visitedNodes.erase(node); - return; - } +int ModuloSchedulingPass::calculateHeight(MSchedGraphNode *node,MSchedGraphNode *srcNode) { + + MSNodeAttributes &attributes = nodeToAttributesMap.find(node)->second; - if(node->hasSuccessors()) { - int maxHeight = 0; + if(attributes.height != -1) + return attributes.height; + + int maxHeight = 0; - //Iterate over all of the predecessors and fine max - for(MSchedGraphNode::succ_iterator P = node->succ_begin(), - E = node->succ_end(); P != E; ++P) { + //Iterate over all of the predecessors and find max + for(MSchedGraphNode::succ_iterator P = node->succ_begin(), + E = node->succ_end(); P != E; ++P) { + + + if(!ignoreEdge(node, *P)) { + int succHeight = calculateHeight(*P, node); - MSNodeAttributes succAttributes = nodeToAttributesMap.find(*P)->second; - if(succAttributes.height == -1) { - - //Put into map before recursing - visitedNodes.insert(node); + assert(succHeight != -1 && "Successors Height should have been caclulated"); - calculateHeight(*P, succAttributes, visitedNodes); - succAttributes = nodeToAttributesMap.find(*P)->second; - assert(succAttributes.height == -1 && "Successors Height should have been caclulated"); - } - int currentHeight = succAttributes.height + node->getLatency(); + int currentHeight = succHeight + node->getLatency(); maxHeight = std::max(maxHeight, currentHeight); } - visitedNodes.erase(node); - attributes.height = maxHeight; } - else { - visitedNodes.erase(node); - attributes.height = 0; - } - - DEBUG(std::cerr << "Height: " << attributes.height << " (" << *node << ")\n"); + attributes.height = maxHeight; + DEBUG(std::cerr << "Height: " << attributes.height << " (" << *node << ")\n"); + return maxHeight; } -void ModuloSchedulingPass::calculateDepth(MSchedGraphNode *node, - MSNodeAttributes &attributes, - std::set &visitedNodes) { - - if(attributes.depth != -1 || (visitedNodes.find(node) != visitedNodes.end())) { - //Remove from map before returning - visitedNodes.erase(node); - return; - } +int ModuloSchedulingPass::calculateDepth(MSchedGraphNode *node, + MSchedGraphNode *destNode) { - if(node->hasPredecessors()) { - int maxDepth = 0; - - //Iterate over all of the predecessors and fine max - for(MSchedGraphNode::pred_iterator P = node->pred_begin(), E = node->pred_end(); P != E; ++P) { + MSNodeAttributes &attributes = nodeToAttributesMap.find(node)->second; - //Get that nodes depth - MSNodeAttributes predAttributes = nodeToAttributesMap.find(*P)->second; - if(predAttributes.depth == -1) { - - //Put into set before recursing - visitedNodes.insert(node); - - calculateDepth(*P, predAttributes, visitedNodes); - predAttributes = nodeToAttributesMap.find(*P)->second; - assert(predAttributes.depth == -1 && "Predecessors ASAP should have been caclulated"); - } - int currentDepth = predAttributes.depth + node->getLatency(); + if(attributes.depth != -1) + return attributes.depth; + + int maxDepth = 0; + + //Iterate over all of the predecessors and fine max + for(MSchedGraphNode::pred_iterator P = node->pred_begin(), E = node->pred_end(); P != E; ++P) { + + if(!ignoreEdge(*P, node)) { + int predDepth = -1; + predDepth = calculateDepth(*P, node); + + assert(predDepth != -1 && "Predecessors ASAP should have been caclulated"); + + int currentDepth = predDepth + (*P)->getLatency(); maxDepth = std::max(maxDepth, currentDepth); } - - //Remove from map before returning - visitedNodes.erase(node); - - attributes.height = maxDepth; - } - else { - //Remove from map before returning - visitedNodes.erase(node); - attributes.depth = 0; } - + attributes.depth = maxDepth; + DEBUG(std::cerr << "Depth: " << attributes.depth << " (" << *node << "*)\n"); - + return maxDepth; } -void ModuloSchedulingPass::findAllReccurrences(MSchedGraphNode *node, - std::vector &visitedNodes) { + +void ModuloSchedulingPass::addReccurrence(std::vector &recurrence, int II, MSchedGraphNode *srcBENode, MSchedGraphNode *destBENode) { + //Check to make sure that this recurrence is unique + bool same = false; + + + //Loop over all recurrences already in our list + for(std::set > >::iterator R = recurrenceList.begin(), RE = recurrenceList.end(); R != RE; ++R) { + + bool all_same = true; + //First compare size + if(R->second.size() == recurrence.size()) { + + for(std::vector::const_iterator node = R->second.begin(), end = R->second.end(); node != end; ++node) { + if(find(recurrence.begin(), recurrence.end(), *node) == recurrence.end()) { + all_same = all_same && false; + break; + } + else + all_same = all_same && true; + } + if(all_same) { + same = true; + break; + } + } + } + + if(!same) { + //if(srcBENode == 0 || destBENode == 0) { + srcBENode = recurrence.back(); + destBENode = recurrence.front(); + //} + DEBUG(std::cerr << "Back Edge to Remove: " << *srcBENode << " to " << *destBENode << "\n"); + edgesToIgnore.insert(std::make_pair(srcBENode, destBENode->getInEdgeNum(srcBENode))); + recurrenceList.insert(std::make_pair(II, recurrence)); + } +} + +void ModuloSchedulingPass::findAllReccurrences(MSchedGraphNode *node, + std::vector &visitedNodes, + int II) { + if(find(visitedNodes.begin(), visitedNodes.end(), node) != visitedNodes.end()) { - //DUMP out recurrence - DEBUG(std::cerr << "Reccurrence:\n"); + std::vector recurrence; bool first = true; + int delay = 0; + int distance = 0; + int RecMII = II; //Starting value + MSchedGraphNode *last = node; + MSchedGraphNode *srcBackEdge; + MSchedGraphNode *destBackEdge; + + + for(std::vector::iterator I = visitedNodes.begin(), E = visitedNodes.end(); I !=E; ++I) { - if(*I == node) + + if(*I == node) first = false; if(first) continue; - DEBUG(std::cerr << **I << "\n"); + + delay = delay + (*I)->getLatency(); + + if(*I != node) { + int diff = (*I)->getInEdge(last).getIteDiff(); + distance += diff; + if(diff > 0) { + srcBackEdge = last; + destBackEdge = *I; + } + } + + recurrence.push_back(*I); + last = *I; } - DEBUG(std::cerr << "End Reccurrence:\n"); + + + + //Get final distance calc + distance += node->getInEdge(last).getIteDiff(); + + + //Adjust II until we get close to the inequality delay - II*distance <= 0 + + int value = delay-(RecMII * distance); + int lastII = II; + while(value <= 0) { + + lastII = RecMII; + RecMII--; + value = delay-(RecMII * distance); + } + + + DEBUG(std::cerr << "Final II for this recurrence: " << lastII << "\n"); + addReccurrence(recurrence, lastII, srcBackEdge, destBackEdge); + assert(distance != 0 && "Recurrence distance should not be zero"); return; } for(MSchedGraphNode::succ_iterator I = node->succ_begin(), E = node->succ_end(); I != E; ++I) { visitedNodes.push_back(node); - findAllReccurrences(*I, visitedNodes); + findAllReccurrences(*I, visitedNodes, II); visitedNodes.pop_back(); } +} + + + + + +void ModuloSchedulingPass::computePartialOrder() { + + + //Loop over all recurrences and add to our partial order + //be sure to remove nodes that are already in the partial order in + //a different recurrence and don't add empty recurrences. + for(std::set > >::reverse_iterator I = recurrenceList.rbegin(), E=recurrenceList.rend(); I !=E; ++I) { + + //Add nodes that connect this recurrence to the previous recurrence + + //If this is the first recurrence in the partial order, add all predecessors + for(std::vector::const_iterator N = I->second.begin(), NE = I->second.end(); N != NE; ++N) { + + } + + + std::vector new_recurrence; + //Loop through recurrence and remove any nodes already in the partial order + for(std::vector::const_iterator N = I->second.begin(), NE = I->second.end(); N != NE; ++N) { + bool found = false; + for(std::vector >::iterator PO = partialOrder.begin(), PE = partialOrder.end(); PO != PE; ++PO) { + if(find(PO->begin(), PO->end(), *N) != PO->end()) + found = true; + } + if(!found) { + new_recurrence.push_back(*N); + + if(partialOrder.size() == 0) + //For each predecessors, add it to this recurrence ONLY if it is not already in it + for(MSchedGraphNode::pred_iterator P = (*N)->pred_begin(), + PE = (*N)->pred_end(); P != PE; ++P) { + + //Check if we are supposed to ignore this edge or not + if(!ignoreEdge(*P, *N)) + //Check if already in this recurrence + if(find(I->second.begin(), I->second.end(), *P) == I->second.end()) { + //Also need to check if in partial order + bool predFound = false; + for(std::vector >::iterator PO = partialOrder.begin(), PEND = partialOrder.end(); PO != PEND; ++PO) { + if(find(PO->begin(), PO->end(), *P) != PO->end()) + predFound = true; + } + + if(!predFound) + if(find(new_recurrence.begin(), new_recurrence.end(), *P) == new_recurrence.end()) + new_recurrence.push_back(*P); + + } + } + } + } + + + if(new_recurrence.size() > 0) + partialOrder.push_back(new_recurrence); + } + + //Add any nodes that are not already in the partial order + std::vector lastNodes; + for(std::map::iterator I = nodeToAttributesMap.begin(), E = nodeToAttributesMap.end(); I != E; ++I) { + bool found = false; + //Check if its already in our partial order, if not add it to the final vector + for(std::vector >::iterator PO = partialOrder.begin(), PE = partialOrder.end(); PO != PE; ++PO) { + if(find(PO->begin(), PO->end(), I->first) != PO->end()) + found = true; + } + if(!found) + lastNodes.push_back(I->first); + } + if(lastNodes.size() > 0) + partialOrder.push_back(lastNodes); + } +void ModuloSchedulingPass::predIntersect(std::vector &CurrentSet, std::vector &IntersectResult) { + + //Sort CurrentSet so we can use lowerbound + sort(CurrentSet.begin(), CurrentSet.end()); + + for(unsigned j=0; j < FinalNodeOrder.size(); ++j) { + for(MSchedGraphNode::pred_iterator P = FinalNodeOrder[j]->pred_begin(), + E = FinalNodeOrder[j]->pred_end(); P != E; ++P) { + + //Check if we are supposed to ignore this edge or not + if(ignoreEdge(*P,FinalNodeOrder[j])) + continue; + + if(find(CurrentSet.begin(), + CurrentSet.end(), *P) != CurrentSet.end()) + if(find(FinalNodeOrder.begin(), FinalNodeOrder.end(), *P) == FinalNodeOrder.end()) + IntersectResult.push_back(*P); + } + } +} + +void ModuloSchedulingPass::succIntersect(std::vector &CurrentSet, std::vector &IntersectResult) { + //Sort CurrentSet so we can use lowerbound + sort(CurrentSet.begin(), CurrentSet.end()); + + for(unsigned j=0; j < FinalNodeOrder.size(); ++j) { + for(MSchedGraphNode::succ_iterator P = FinalNodeOrder[j]->succ_begin(), + E = FinalNodeOrder[j]->succ_end(); P != E; ++P) { + //Check if we are supposed to ignore this edge or not + if(ignoreEdge(FinalNodeOrder[j],*P)) + continue; + if(find(CurrentSet.begin(), + CurrentSet.end(), *P) != CurrentSet.end()) + if(find(FinalNodeOrder.begin(), FinalNodeOrder.end(), *P) == FinalNodeOrder.end()) + IntersectResult.push_back(*P); + } + } +} +void dumpIntersection(std::vector &IntersectCurrent) { + std::cerr << "Intersection ("; + for(std::vector::iterator I = IntersectCurrent.begin(), E = IntersectCurrent.end(); I != E; ++I) + std::cerr << **I << ", "; + std::cerr << ")\n"; +} @@ -494,124 +778,112 @@ int BOTTOM_UP = 0; int TOP_DOWN = 1; - //FIXME: Group nodes into sets and order all the sets based on RecMII - typedef std::vector NodeVector; - typedef std::pair NodeSet; - - std::vector NodeSetsToOrder; - - //Order the resulting sets - NodeVector FinalNodeOrder; + //Set default order + int order = BOTTOM_UP; - //Loop over all the sets and place them in the final node order - for(unsigned i=0; i < NodeSetsToOrder.size(); ++i) { - //Set default order - int order = BOTTOM_UP; + //Loop over all the sets and place them in the final node order + for(std::vector >::iterator CurrentSet = partialOrder.begin(), E= partialOrder.end(); CurrentSet != E; ++CurrentSet) { - //Get Nodes in Current set - NodeVector CurrentSet = NodeSetsToOrder[i].second; + DEBUG(std::cerr << "Processing set in S\n"); + dumpIntersection(*CurrentSet); + //Result of intersection + std::vector IntersectCurrent; - //Loop through the predecessors for each node in the final order - //and only keeps nodes both in the pred_set and currentset - NodeVector IntersectCurrent; - - //Sort CurrentSet so we can use lowerbound - sort(CurrentSet.begin(), CurrentSet.end()); - - for(unsigned j=0; j < FinalNodeOrder.size(); ++j) { - for(MSchedGraphNode::pred_iterator P = FinalNodeOrder[j]->pred_begin(), - E = FinalNodeOrder[j]->pred_end(); P != E; ++P) { - if(lower_bound(CurrentSet.begin(), - CurrentSet.end(), *P) != CurrentSet.end()) - IntersectCurrent.push_back(*P); - } - } + predIntersect(*CurrentSet, IntersectCurrent); //If the intersection of predecessor and current set is not empty //sort nodes bottom up - if(IntersectCurrent.size() != 0) + if(IntersectCurrent.size() != 0) { + DEBUG(std::cerr << "Final Node Order Predecessors and Current Set interesection is NOT empty\n"); order = BOTTOM_UP; - + } //If empty, use successors else { + DEBUG(std::cerr << "Final Node Order Predecessors and Current Set interesection is empty\n"); - for(unsigned j=0; j < FinalNodeOrder.size(); ++j) { - for(MSchedGraphNode::succ_iterator P = FinalNodeOrder[j]->succ_begin(), - E = FinalNodeOrder[j]->succ_end(); P != E; ++P) { - if(lower_bound(CurrentSet.begin(), - CurrentSet.end(), *P) != CurrentSet.end()) - IntersectCurrent.push_back(*P); - } - } + succIntersect(*CurrentSet, IntersectCurrent); //sort top-down - if(IntersectCurrent.size() != 0) + if(IntersectCurrent.size() != 0) { + DEBUG(std::cerr << "Final Node Order Successors and Current Set interesection is NOT empty\n"); order = TOP_DOWN; - + } else { + DEBUG(std::cerr << "Final Node Order Successors and Current Set interesection is empty\n"); //Find node with max ASAP in current Set MSchedGraphNode *node; int maxASAP = 0; - for(unsigned j=0; j < CurrentSet.size(); ++j) { + DEBUG(std::cerr << "Using current set of size " << CurrentSet->size() << "to find max ASAP\n"); + for(unsigned j=0; j < CurrentSet->size(); ++j) { //Get node attributes - MSNodeAttributes nodeAttr= nodeToAttributesMap.find(CurrentSet[j])->second; + MSNodeAttributes nodeAttr= nodeToAttributesMap.find((*CurrentSet)[j])->second; //assert(nodeAttr != nodeToAttributesMap.end() && "Node not in attributes map!"); - + DEBUG(std::cerr << "CurrentSet index " << j << "has ASAP: " << nodeAttr.ASAP << "\n"); if(maxASAP < nodeAttr.ASAP) { maxASAP = nodeAttr.ASAP; - node = CurrentSet[j]; + node = (*CurrentSet)[j]; } } + assert(node != 0 && "In node ordering node should not be null"); + IntersectCurrent.push_back(node); order = BOTTOM_UP; } } //Repeat until all nodes are put into the final order from current set - /*while(IntersectCurrent.size() > 0) { - + while(IntersectCurrent.size() > 0) { + if(order == TOP_DOWN) { - while(IntersectCurrent.size() > 0) { + DEBUG(std::cerr << "Order is TOP DOWN\n"); - //FIXME - //Get node attributes - MSNodeAttributes nodeAttr= nodeToAttributesMap.find(IntersectCurrent[0])->second; - assert(nodeAttr != nodeToAttributesMap.end() && "Node not in attributes map!"); + while(IntersectCurrent.size() > 0) { + DEBUG(std::cerr << "Intersection is not empty, so find heighest height\n"); + + int MOB = 0; + int height = 0; + MSchedGraphNode *highestHeightNode = IntersectCurrent[0]; + + //Find node in intersection with highest heigh and lowest MOB + for(std::vector::iterator I = IntersectCurrent.begin(), + E = IntersectCurrent.end(); I != E; ++I) { + + //Get current nodes properties + MSNodeAttributes nodeAttr= nodeToAttributesMap.find(*I)->second; - //Get node with highest height, if a tie, use one with lowest - //MOB - int MOB = nodeAttr.MBO; - int height = nodeAttr.height; - ModuloSchedGraphNode *V = IntersectCurrent[0]; - - for(unsigned j=0; j < IntersectCurrent.size(); ++j) { - int temp = IntersectCurrent[j]->getHeight(); - if(height < temp) { - V = IntersectCurrent[j]; - height = temp; - MOB = V->getMobility(); + if(height < nodeAttr.height) { + highestHeightNode = *I; + height = nodeAttr.height; + MOB = nodeAttr.MOB; } - else if(height == temp) { - if(MOB > IntersectCurrent[j]->getMobility()) { - V = IntersectCurrent[j]; - height = temp; - MOB = V->getMobility(); + else if(height == nodeAttr.height) { + if(MOB > nodeAttr.height) { + highestHeightNode = *I; + height = nodeAttr.height; + MOB = nodeAttr.MOB; } } } - //Append V to the NodeOrder - NodeOrder.push_back(V); + //Append our node with greatest height to the NodeOrder + if(find(FinalNodeOrder.begin(), FinalNodeOrder.end(), highestHeightNode) == FinalNodeOrder.end()) { + DEBUG(std::cerr << "Adding node to Final Order: " << *highestHeightNode << "\n"); + FinalNodeOrder.push_back(highestHeightNode); + } //Remove V from IntersectOrder IntersectCurrent.erase(find(IntersectCurrent.begin(), - IntersectCurrent.end(), V)); + IntersectCurrent.end(), highestHeightNode)); + //Intersect V's successors with CurrentSet - for(mod_succ_iterator P = succ_begin(V), - E = succ_end(V); P != E; ++P) { - if(lower_bound(CurrentSet.begin(), - CurrentSet.end(), *P) != CurrentSet.end()) { + for(MSchedGraphNode::succ_iterator P = highestHeightNode->succ_begin(), + E = highestHeightNode->succ_end(); P != E; ++P) { + //if(lower_bound(CurrentSet->begin(), + // CurrentSet->end(), *P) != CurrentSet->end()) { + if(find(CurrentSet->begin(), CurrentSet->end(), *P) != CurrentSet->end()) { + if(ignoreEdge(highestHeightNode, *P)) + continue; //If not already in Intersect, add if(find(IntersectCurrent.begin(), IntersectCurrent.end(), *P) == IntersectCurrent.end()) IntersectCurrent.push_back(*P); @@ -624,81 +896,299 @@ //Reset Intersect to reflect changes in OrderNodes IntersectCurrent.clear(); - for(unsigned j=0; j < NodeOrder.size(); ++j) { - for(mod_pred_iterator P = pred_begin(NodeOrder[j]), - E = pred_end(NodeOrder[j]); P != E; ++P) { - if(lower_bound(CurrentSet.begin(), - CurrentSet.end(), *P) != CurrentSet.end()) - IntersectCurrent.push_back(*P); - } - } + predIntersect(*CurrentSet, IntersectCurrent); + } //End If TOP_DOWN //Begin if BOTTOM_UP - else { - while(IntersectCurrent.size() > 0) { - //Get node with highest depth, if a tie, use one with lowest - //MOB - int MOB = IntersectCurrent[0]->getMobility(); - int depth = IntersectCurrent[0]->getDepth(); - ModuloSchedGraphNode *V = IntersectCurrent[0]; + else { + DEBUG(std::cerr << "Order is BOTTOM UP\n"); + while(IntersectCurrent.size() > 0) { + DEBUG(std::cerr << "Intersection of size " << IntersectCurrent.size() << ", finding highest depth\n"); + + //dump intersection + DEBUG(dumpIntersection(IntersectCurrent)); + //Get node with highest depth, if a tie, use one with lowest + //MOB + int MOB = 0; + int depth = 0; + MSchedGraphNode *highestDepthNode = IntersectCurrent[0]; + + for(std::vector::iterator I = IntersectCurrent.begin(), + E = IntersectCurrent.end(); I != E; ++I) { + //Find node attribute in graph + MSNodeAttributes nodeAttr= nodeToAttributesMap.find(*I)->second; - for(unsigned j=0; j < IntersectCurrent.size(); ++j) { - int temp = IntersectCurrent[j]->getDepth(); - if(depth < temp) { - V = IntersectCurrent[j]; - depth = temp; - MOB = V->getMobility(); - } - else if(depth == temp) { - if(MOB > IntersectCurrent[j]->getMobility()) { - V = IntersectCurrent[j]; - depth = temp; - MOB = V->getMobility(); - } - } + if(depth < nodeAttr.depth) { + highestDepthNode = *I; + depth = nodeAttr.depth; + MOB = nodeAttr.MOB; } - - //Append V to the NodeOrder - NodeOrder.push_back(V); - - //Remove V from IntersectOrder - IntersectCurrent.erase(find(IntersectCurrent.begin(), - IntersectCurrent.end(),V)); - - //Intersect V's pred with CurrentSet - for(mod_pred_iterator P = pred_begin(V), - E = pred_end(V); P != E; ++P) { - if(lower_bound(CurrentSet.begin(), - CurrentSet.end(), *P) != CurrentSet.end()) { - //If not already in Intersect, add - if(find(IntersectCurrent.begin(), IntersectCurrent.end(), *P) == IntersectCurrent.end()) - IntersectCurrent.push_back(*P); + else if(depth == nodeAttr.depth) { + if(MOB > nodeAttr.MOB) { + highestDepthNode = *I; + depth = nodeAttr.depth; + MOB = nodeAttr.MOB; } } - } //End while loop over Intersect Size + } - //Change order - order = TOP_DOWN; - //Reset IntersectCurrent to reflect changes in OrderNodes - IntersectCurrent.clear(); - for(unsigned j=0; j < NodeOrder.size(); ++j) { - for(mod_succ_iterator P = succ_begin(NodeOrder[j]), - E = succ_end(NodeOrder[j]); P != E; ++P) { - if(lower_bound(CurrentSet.begin(), - CurrentSet.end(), *P) != CurrentSet.end()) + + //Append highest depth node to the NodeOrder + if(find(FinalNodeOrder.begin(), FinalNodeOrder.end(), highestDepthNode) == FinalNodeOrder.end()) { + DEBUG(std::cerr << "Adding node to Final Order: " << *highestDepthNode << "\n"); + FinalNodeOrder.push_back(highestDepthNode); + } + //Remove heightestDepthNode from IntersectOrder + IntersectCurrent.erase(find(IntersectCurrent.begin(), + IntersectCurrent.end(),highestDepthNode)); + + + //Intersect heightDepthNode's pred with CurrentSet + for(MSchedGraphNode::pred_iterator P = highestDepthNode->pred_begin(), + E = highestDepthNode->pred_end(); P != E; ++P) { + //if(lower_bound(CurrentSet->begin(), + // CurrentSet->end(), *P) != CurrentSet->end()) { + if(find(CurrentSet->begin(), CurrentSet->end(), *P) != CurrentSet->end()) { + + if(ignoreEdge(*P, highestDepthNode)) + continue; + + //If not already in Intersect, add + if(find(IntersectCurrent.begin(), + IntersectCurrent.end(), *P) == IntersectCurrent.end()) IntersectCurrent.push_back(*P); } - } + + } //End while loop over Intersect Size + + //Change order + order = TOP_DOWN; + + //Reset IntersectCurrent to reflect changes in OrderNodes + IntersectCurrent.clear(); + succIntersect(*CurrentSet, IntersectCurrent); } //End if BOTTOM_DOWN - }*/ -//End Wrapping while loop + } + //End Wrapping while loop - }//End for over all sets of nodes + }//End for over all sets of nodes - //Return final Order - //return FinalNodeOrder; + //Return final Order + //return FinalNodeOrder; +} + +void ModuloSchedulingPass::computeSchedule() { + + bool success = false; + + while(!success) { + + //Loop over the final node order and process each node + for(std::vector::iterator I = FinalNodeOrder.begin(), + E = FinalNodeOrder.end(); I != E; ++I) { + + //CalculateEarly and Late start + int EarlyStart = -1; + int LateStart = 99999; //Set to something higher then we would ever expect (FIXME) + bool hasSucc = false; + bool hasPred = false; + std::set seenNodes; + + for(std::map > > >::iterator J = schedule.begin(), + JE = schedule.end(); J != JE; ++J) { + + //For each resource with nodes scheduled, loop over the nodes and see if they + //are a predecessor or successor of this current node we are trying + //to schedule. + for(std::vector > >::iterator schedNodeVec = J->second.begin(), SNE = J->second.end(); schedNodeVec != SNE; ++schedNodeVec) { + + for(std::vector::iterator schedNode = schedNodeVec->second.begin(), schedNodeEnd = schedNodeVec->second.end(); schedNode != schedNodeEnd; ++schedNode) { + if((*I)->isPredecessor(*schedNode) && !seenNodes.count(*schedNode)) { + if(!ignoreEdge(*schedNode, *I)) { + int diff = (*I)->getInEdge(*schedNode).getIteDiff(); + int ES_Temp = J->first + (*schedNode)->getLatency() - diff * II; + DEBUG(std::cerr << "Diff: " << diff << " Cycle: " << J->first << "\n"); + DEBUG(std::cerr << "Temp EarlyStart: " << ES_Temp << " Prev EarlyStart: " << EarlyStart << "\n"); + EarlyStart = std::max(EarlyStart, ES_Temp); + hasPred = true; + } + } + if((*I)->isSuccessor(*schedNode) && !seenNodes.count(*schedNode)) { + if(!ignoreEdge(*I,*schedNode)) { + int diff = (*schedNode)->getInEdge(*I).getIteDiff(); + int LS_Temp = J->first - (*I)->getLatency() + diff * II; + DEBUG(std::cerr << "Diff: " << diff << " Cycle: " << J->first << "\n"); + DEBUG(std::cerr << "Temp LateStart: " << LS_Temp << " Prev LateStart: " << LateStart << "\n"); + LateStart = std::min(LateStart, LS_Temp); + hasSucc = true; + } + } + seenNodes.insert(*schedNode); + } + } + } + seenNodes.clear(); + + DEBUG(std::cerr << "Has Successors: " << hasSucc << ", Has Pred: " << hasPred << "\n"); + DEBUG(std::cerr << "EarlyStart: " << EarlyStart << ", LateStart: " << LateStart << "\n"); + + //Check if the node has no pred or successors and set Early Start to its ASAP + if(!hasSucc && !hasPred) + EarlyStart = nodeToAttributesMap.find(*I)->second.ASAP; + + //Now, try to schedule this node depending upon its pred and successor in the schedule + //already + if(!hasSucc && hasPred) + success = scheduleNode(*I, EarlyStart, (EarlyStart + II -1)); + else if(!hasPred && hasSucc) + success = scheduleNode(*I, LateStart, (LateStart - II +1)); + else if(hasPred && hasSucc) + success = scheduleNode(*I, EarlyStart, std::min(LateStart, (EarlyStart + II -1))); + else + success = scheduleNode(*I, EarlyStart, EarlyStart + II - 1); + + if(!success) { + ++II; + schedule.clear(); + break; + } + + } + } +} + + +bool ModuloSchedulingPass::scheduleNode(MSchedGraphNode *node, + int start, int end) { + bool success = false; + + DEBUG(std::cerr << *node << " (Start Cycle: " << start << ", End Cycle: " << end << ")\n"); + + /*std::cerr << "CURRENT SCHEDULE\n"; + //Dump out current schedule + for(std::map > >::iterator J = schedule.begin(), + JE = schedule.end(); J != JE; ++J) { + std::cerr << "Cycle " << J->first << ":\n"; + for(std::vector >::iterator VI = J->second.begin(), VE = J->second.end(); VI != VE; ++VI) + std::cerr << "Resource ID: " << VI->first << " by node " << *(VI->second) << "\n"; + } + std::cerr << "END CURRENT SCHEDULE\n"; + */ + + //Make sure start and end are not negative + if(start < 0) + start = 0; + if(end < 0) + end = 0; + + bool forward = true; + if(start > end) + forward = false; + + const TargetSchedInfo & msi = target.getSchedInfo(); + + bool increaseSC = true; + + int cycle = start ; + + + while(increaseSC) { + + increaseSC = false; + + //Get the resource used by this instruction + //Get resource usage for this instruction + InstrRUsage rUsage = msi.getInstrRUsage(node->getInst()->getOpcode()); + std::vector > resources = rUsage.resourcesByCycle; + + //Loop over each resource and see if we can put it into the schedule + for(unsigned r=0; r < resources.size(); ++r) { + unsigned intermediateCycle = cycle + r; + + for(unsigned j=0; j < resources[r].size(); ++j) { + //Put it into the schedule + DEBUG(std::cerr << "Attempting to put resource " << resources[r][j] << " in schedule at cycle: " << intermediateCycle << "\n"); + + //Check if resource is free at this cycle + std::vector > > resourceForCycle = schedule[intermediateCycle]; + + //Vector of nodes using this resource + std::vector *nodesUsingResource; + + for(std::vector > >::iterator I = resourceForCycle.begin(), E= resourceForCycle.end(); I != E; ++I) { + + if(I->first == resources[r][j]) { + //Get the number of available for this resource + unsigned numResource = CPUResource::getCPUResource(resources[r][j])->maxNumUsers; + nodesUsingResource = &(I->second); + + //Check that there are enough of this resource, otherwise + //we need to increase/decrease the cycle + if(I->second.size() >= numResource) { + DEBUG(std::cerr << "No open spot for this resource in this cycle\n"); + increaseSC = true; + } + break; + + } + //safe to put into schedule + } + + if(increaseSC) + break; + + else { + DEBUG(std::cerr << "Found spot in schedule\n"); + //Add node to resource vector + if(nodesUsingResource == 0) { + nodesUsingResource = new std::vector; + resourceForCycle.push_back(std::make_pair(resources[r][j], *nodesUsingResource)); + } + + nodesUsingResource->push_back(node); + + schedule[intermediateCycle] = resourceForCycle; + } + } + if(increaseSC) { + /*for(unsigned x = 0; x < r; ++x) { + unsigned removeCycle = x + start; + for(unsigned j=0; j < resources[x].size(); ++j) { + std::vector > resourceForCycle = schedule[removeCycle]; + for(std::vector >::iterator I = resourceForCycle.begin(), E= resourceForCycle.end(); I != E; ++I) { + if(I->first == resources[x][j]) { + //remove it + resourceForCycle.erase(I); + } + } + //Put vector back + schedule[removeCycle] = resourceForCycle; + } + }*/ + + break; + } + } + if(!increaseSC) + return true; + + //Increment cycle to try again + if(forward) { + ++cycle; + DEBUG(std::cerr << "Increase cycle: " << cycle << "\n"); + if(cycle > end) + return false; + } + else { + --cycle; + DEBUG(std::cerr << "Decrease cycle: " << cycle << "\n"); + if(cycle < end) + return false; + } + } + return success; } Index: llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.h diff -u llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.h:1.11 llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.h:1.12 --- llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.h:1.11 Sun Feb 29 20:50:57 2004 +++ llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.h Sat May 8 11:12:10 2004 @@ -41,22 +41,53 @@ //Map that holds node to node attribute information std::map nodeToAttributesMap; + //Map to hold all reccurrences + std::set > > recurrenceList; + + //Set of edges to ignore, stored as src node and index into vector of successors + std::set > edgesToIgnore; + + //Vector containing the partial order + std::vector > partialOrder; + + //Vector containing the final node order + std::vector FinalNodeOrder; + + //Schedule table, key is the cycle number and the vector is resource, node pairs + std::map > > > schedule; + + //Current initiation interval + int II; + //Internal functions bool MachineBBisValid(const MachineBasicBlock *BI); int calculateResMII(const MachineBasicBlock *BI); + int calculateRecMII(MSchedGraph *graph, int MII); void calculateNodeAttributes(MSchedGraph *graph, int MII); - void calculateASAP(MSchedGraphNode *node, MSNodeAttributes &attributes, - int MII,std::set &visitedNodes); - void calculateALAP(MSchedGraphNode *node, MSNodeAttributes &attributes, int MII, - int maxASAP, std::set &visitedNodes); - void calculateHeight(MSchedGraphNode *node, - MSNodeAttributes &attributes, std::set &visitedNodes); - void calculateDepth(MSchedGraphNode *node, MSNodeAttributes &attributes, - std::set &visitedNodes); + + bool ignoreEdge(MSchedGraphNode *srcNode, MSchedGraphNode *destNode); + + + int calculateASAP(MSchedGraphNode *node, int MII,MSchedGraphNode *destNode); + int calculateALAP(MSchedGraphNode *node, int MII, int maxASAP, MSchedGraphNode *srcNode); + + int calculateHeight(MSchedGraphNode *node,MSchedGraphNode *srcNode); + int calculateDepth(MSchedGraphNode *node, MSchedGraphNode *destNode); int findMaxASAP(); - void ModuloSchedulingPass::orderNodes(); - void findAllReccurrences(MSchedGraphNode *node, std::vector &visitedNodes); + void orderNodes(); + void findAllReccurrences(MSchedGraphNode *node, + std::vector &visitedNodes, int II); + void addReccurrence(std::vector &recurrence, int II, MSchedGraphNode*, MSchedGraphNode*); + + void computePartialOrder(); + void computeSchedule(); + bool scheduleNode(MSchedGraphNode *node, + int start, int end); + + void predIntersect(std::vector &CurrentSet, std::vector &IntersectResult); + void succIntersect(std::vector &CurrentSet, std::vector &IntersectResult); + public: ModuloSchedulingPass(TargetMachine &targ) : target(targ) {} virtual bool runOnFunction(Function &F); From tbrethou at cs.uiuc.edu Sat May 8 11:14:04 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat May 8 11:14:04 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetSchedInfo.h Message-ID: <200405081613.LAA18941@seraph.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetSchedInfo.h updated: 1.26 -> 1.27 --- Log message: Changed CPUResource to allow access to max num users for a resource. Also added ModuloScheduling as a friend. --- Diffs of the changes: (+2 -3) Index: llvm/include/llvm/Target/TargetSchedInfo.h diff -u llvm/include/llvm/Target/TargetSchedInfo.h:1.26 llvm/include/llvm/Target/TargetSchedInfo.h:1.27 --- llvm/include/llvm/Target/TargetSchedInfo.h:1.26 Fri Apr 30 15:48:37 2004 +++ llvm/include/llvm/Target/TargetSchedInfo.h Sat May 8 11:13:26 2004 @@ -68,7 +68,7 @@ int maxNumUsers; // MAXINT if no restriction CPUResource(const std::string& resourceName, int maxUsers); - + static CPUResource* getCPUResource(resourceId_t id); private: static resourceId_t nextId; }; @@ -302,8 +302,7 @@ conflictLists; // indexed by [opcode] - friend class ModuloSchedGraph; - friend class ModuloScheduling; + friend class ModuloSchedulingPass; }; From tbrethou at cs.uiuc.edu Sat May 8 11:15:02 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat May 8 11:15:02 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SchedGraphCommon.h Message-ID: <200405081614.LAA18966@seraph.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SchedGraphCommon.h updated: 1.10 -> 1.11 --- Log message: Fixed up sched graph. --- Diffs of the changes: (+3 -4) Index: llvm/include/llvm/CodeGen/SchedGraphCommon.h diff -u llvm/include/llvm/CodeGen/SchedGraphCommon.h:1.10 llvm/include/llvm/CodeGen/SchedGraphCommon.h:1.11 --- llvm/include/llvm/CodeGen/SchedGraphCommon.h:1.10 Mon Feb 9 12:43:06 2004 +++ llvm/include/llvm/CodeGen/SchedGraphCommon.h Sat May 8 11:14:24 2004 @@ -79,9 +79,7 @@ // disable default constructor and provide a ctor for single-block graphs SchedGraphNodeCommon(); // DO NOT IMPLEMENT - inline SchedGraphNodeCommon(unsigned Id, int index) : ID(Id), latency(0), - origIndexInBB(index) {} - inline SchedGraphNodeCommon(unsigned Id, int late, int index) : ID(Id), latency(late), origIndexInBB(index) {} + inline SchedGraphNodeCommon(unsigned Id, int index, int late=0) : ID(Id), latency(late), origIndexInBB(index) {} virtual ~SchedGraphNodeCommon(); @@ -160,7 +158,8 @@ SchedGraphNodeCommon* getSink() const { return sink; } int getMinDelay() const { return minDelay; } SchedGraphEdgeDepType getDepType() const { return depType; } - + unsigned int getDepOrderType() const { return depOrderType; } + const Value* getValue() const { assert(depType == ValueDep); return val; } From tbrethou at cs.uiuc.edu Sat May 8 11:15:06 2004 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Sat May 8 11:15:06 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/Passes.h Message-ID: <200405081614.LAA18954@seraph.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: Passes.h updated: 1.14 -> 1.15 --- Log message: Registering the ModuloScheduling pass. --- Diffs of the changes: (+4 -0) Index: llvm/include/llvm/CodeGen/Passes.h diff -u llvm/include/llvm/CodeGen/Passes.h:1.14 llvm/include/llvm/CodeGen/Passes.h:1.15 --- llvm/include/llvm/CodeGen/Passes.h:1.14 Wed Feb 4 15:41:10 2004 +++ llvm/include/llvm/CodeGen/Passes.h Sat May 8 11:14:02 2004 @@ -75,6 +75,10 @@ /// getRegisterAllocator - This creates an instance of the register allocator /// for the Sparc. FunctionPass *getRegisterAllocator(TargetMachine &T); + + //createModuloSchedulingPass - Creates the Swing Modulo Scheduling Pass + FunctionPass *createModuloSchedulingPass(TargetMachine & targ); + } // End llvm namespace #endif From lattner at cs.uiuc.edu Sat May 8 17:42:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat May 8 17:42:02 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200405082241.RAA09435@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.200 -> 1.201 --- Log message: Fix stupid bug in my checkin yesterday --- Diffs of the changes: (+1 -2) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.200 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.201 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.200 Fri May 7 17:09:22 2004 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Sat May 8 17:41:42 2004 @@ -2624,8 +2624,7 @@ bool EndsWithSequential = false; for (gep_type_iterator I = gep_type_begin(*cast(PtrOp)), E = gep_type_end(*cast(PtrOp)); I != E; ++I) - if (!isa(*I)) - EndsWithSequential = true; + EndsWithSequential = !isa(*I); // Can we combine the two pointer arithmetics offsets? if (EndsWithSequential) { From lattner at cs.uiuc.edu Sat May 8 22:43:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat May 8 22:43:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/CBackend/Writer.cpp Message-ID: <200405090342.WAA18347@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/CBackend: Writer.cpp updated: 1.169 -> 1.170 --- Log message: Print all PHI copies for successor blocks before the terminator, whether it be a conditional branch or switch. --- Diffs of the changes: (+23 -10) Index: llvm/lib/Target/CBackend/Writer.cpp diff -u llvm/lib/Target/CBackend/Writer.cpp:1.169 llvm/lib/Target/CBackend/Writer.cpp:1.170 --- llvm/lib/Target/CBackend/Writer.cpp:1.169 Tue Apr 27 10:13:11 2004 +++ llvm/lib/Target/CBackend/Writer.cpp Sat May 8 22:42:48 2004 @@ -27,6 +27,7 @@ #include "llvm/Analysis/ConstantsScanner.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Support/CallSite.h" +#include "llvm/Support/CFG.h" #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/InstVisitor.h" #include "llvm/Support/Mangler.h" @@ -162,6 +163,8 @@ void outputLValue(Instruction *I) { Out << " " << Mang->getValueName(I) << " = "; } + void printPHICopiesForSuccessors(BasicBlock *CurBlock, + unsigned Indent); void printBranchToBlock(BasicBlock *CurBlock, BasicBlock *SuccBlock, unsigned Indent); void printIndexingExpression(Value *Ptr, gep_type_iterator I, @@ -1035,6 +1038,8 @@ } void CWriter::visitSwitchInst(SwitchInst &SI) { + printPHICopiesForSuccessors(SI.getParent(), 0); + Out << " switch ("; writeOperand(SI.getOperand(0)); Out << ") {\n default:\n"; @@ -1061,7 +1066,7 @@ assert(0 && "Lowerinvoke pass didn't work!"); } -bool isGotoCodeNecessary(BasicBlock *From, BasicBlock *To) { +static bool isGotoCodeNecessary(BasicBlock *From, BasicBlock *To) { // If PHI nodes need copies, we need the copy code... if (isa(To->front()) || From->getNext() != To) // Not directly successor, need goto @@ -1071,17 +1076,23 @@ return false; } +void CWriter::printPHICopiesForSuccessors(BasicBlock *CurBlock, + unsigned Indent) { + for (succ_iterator SI = succ_begin(CurBlock), E = succ_end(CurBlock); + SI != E; ++SI) + for (BasicBlock::iterator I = SI->begin(); + PHINode *PN = dyn_cast(I); ++I) { + // now we have to do the printing + Out << std::string(Indent, ' '); + Out << " " << Mang->getValueName(I) << "__PHI_TEMPORARY = "; + writeOperand(PN->getIncomingValue(PN->getBasicBlockIndex(CurBlock))); + Out << "; /* for PHI node */\n"; + } +} + + void CWriter::printBranchToBlock(BasicBlock *CurBB, BasicBlock *Succ, unsigned Indent) { - for (BasicBlock::iterator I = Succ->begin(); - PHINode *PN = dyn_cast(I); ++I) { - // now we have to do the printing - Out << std::string(Indent, ' '); - Out << " " << Mang->getValueName(I) << "__PHI_TEMPORARY = "; - writeOperand(PN->getIncomingValue(PN->getBasicBlockIndex(CurBB))); - Out << "; /* for PHI node */\n"; - } - if (CurBB->getNext() != Succ || isa(CurBB->getTerminator()) || isa(CurBB->getTerminator())) { @@ -1095,6 +1106,8 @@ // that immediately succeeds the current one. // void CWriter::visitBranchInst(BranchInst &I) { + printPHICopiesForSuccessors(I.getParent(), 0); + if (I.isConditional()) { if (isGotoCodeNecessary(I.getParent(), I.getSuccessor(0))) { Out << " if ("; From lattner at cs.uiuc.edu Sat May 8 23:30:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat May 8 23:30:02 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/CBackend/Writer.cpp Message-ID: <200405090430.XAA23347@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/CBackend: Writer.cpp updated: 1.170 -> 1.171 --- Log message: Get this looking more like a function pass. --- Diffs of the changes: (+33 -32) Index: llvm/lib/Target/CBackend/Writer.cpp diff -u llvm/lib/Target/CBackend/Writer.cpp:1.170 llvm/lib/Target/CBackend/Writer.cpp:1.171 --- llvm/lib/Target/CBackend/Writer.cpp:1.170 Sat May 8 22:42:48 2004 +++ llvm/lib/Target/CBackend/Writer.cpp Sat May 8 23:30:20 2004 @@ -59,14 +59,14 @@ bool doInitialization(Module &M); bool run(Module &M) { - // First pass, lower all unhandled intrinsics. - lowerIntrinsics(M); - doInitialization(M); for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) - if (!I->isExternal()) + if (!I->isExternal()) { + // First pass, lower all unhandled intrinsics. + lowerIntrinsics(*I); printFunction(*I); + } // Free memory... delete Mang; @@ -82,7 +82,7 @@ void writeOperandInternal(Value *Operand); private : - void lowerIntrinsics(Module &M); + void lowerIntrinsics(Function &F); bool nameAllUsedStructureTypes(Module &M); void printModule(Module *M); @@ -655,6 +655,8 @@ // Initialize TheModule = &M; FUT = &getAnalysis(); + + IL.AddPrototypes(M); // Ensure that all structure types have names... bool Changed = nameAllUsedStructureTypes(M); @@ -776,7 +778,7 @@ void CWriter::printFloatingPointConstants(Module &M) { union { double D; - unsigned long long U; + uint64_t U; } DBLUnion; union { @@ -1219,33 +1221,32 @@ } -void CWriter::lowerIntrinsics(Module &M) { - for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) - for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) - for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) - if (CallInst *CI = dyn_cast(I++)) - if (Function *F = CI->getCalledFunction()) - switch (F->getIntrinsicID()) { - case Intrinsic::not_intrinsic: - case Intrinsic::vastart: - case Intrinsic::vacopy: - case Intrinsic::vaend: - case Intrinsic::returnaddress: - case Intrinsic::frameaddress: - case Intrinsic::setjmp: - case Intrinsic::longjmp: - // We directly implement these intrinsics - break; - default: - // All other intrinsic calls we must lower. - Instruction *Before = CI->getPrev(); - IL.LowerIntrinsicCall(CI); - if (Before) { // Move iterator to instruction after call - I = Before; ++I; - } else { - I = BB->begin(); - } +void CWriter::lowerIntrinsics(Function &F) { + for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) + if (CallInst *CI = dyn_cast(I++)) + if (Function *F = CI->getCalledFunction()) + switch (F->getIntrinsicID()) { + case Intrinsic::not_intrinsic: + case Intrinsic::vastart: + case Intrinsic::vacopy: + case Intrinsic::vaend: + case Intrinsic::returnaddress: + case Intrinsic::frameaddress: + case Intrinsic::setjmp: + case Intrinsic::longjmp: + // We directly implement these intrinsics + break; + default: + // All other intrinsic calls we must lower. + Instruction *Before = CI->getPrev(); + IL.LowerIntrinsicCall(CI); + if (Before) { // Move iterator to instruction after call + I = Before; ++I; + } else { + I = BB->begin(); } + } } From lattner at cs.uiuc.edu Sat May 8 23:30:11 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat May 8 23:30:11 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/IntrinsicLowering.cpp Message-ID: <200405090430.XAA23336@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: IntrinsicLowering.cpp updated: 1.11 -> 1.12 --- Log message: Implement the AddPrototypes method --- Diffs of the changes: (+43 -1) Index: llvm/lib/VMCore/IntrinsicLowering.cpp diff -u llvm/lib/VMCore/IntrinsicLowering.cpp:1.11 llvm/lib/VMCore/IntrinsicLowering.cpp:1.12 --- llvm/lib/VMCore/IntrinsicLowering.cpp:1.11 Sun Feb 15 16:24:51 2004 +++ llvm/lib/VMCore/IntrinsicLowering.cpp Sat May 8 23:29:57 2004 @@ -18,6 +18,18 @@ #include "llvm/iOther.h" using namespace llvm; +template +static Function *EnsureFunctionExists(Module &M, const char *Name, + ArgIt ArgBegin, ArgIt ArgEnd, + const Type *RetTy) { + if (Function *F = M.getNamedFunction(Name)) return F; + // It doesn't already exist in the program, insert a new definition now. + std::vector ParamTys; + for (ArgIt I = ArgBegin; I != ArgEnd; ++I) + ParamTys.push_back(I->getType()); + return M.getOrInsertFunction(Name, FunctionType::get(RetTy, ParamTys, false)); +} + /// ReplaceCallWith - This function is used when we want to lower an intrinsic /// call to a call of an external function. This handles hard cases such as /// when there was already a prototype for the external function, and if that @@ -39,7 +51,7 @@ FCache = M->getOrInsertFunction(NewFn, FunctionType::get(RetTy, ParamTys, false)); } - } + } const FunctionType *FT = FCache->getFunctionType(); std::vector Operands; @@ -60,6 +72,36 @@ return new CallInst(FCache, Operands, Name, CI); } +void DefaultIntrinsicLowering::AddPrototypes(Module &M) { + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) + if (I->isExternal() && !I->use_empty()) + switch (I->getIntrinsicID()) { + default: break; + case Intrinsic::setjmp: + EnsureFunctionExists(M, "setjmp", I->abegin(), I->aend(), Type::IntTy); + break; + case Intrinsic::longjmp: + EnsureFunctionExists(M, "longjmp", I->abegin(), I->aend(),Type::VoidTy); + break; + case Intrinsic::siglongjmp: + EnsureFunctionExists(M, "abort", I->aend(), I->aend(), Type::VoidTy); + break; + case Intrinsic::memcpy: + EnsureFunctionExists(M, "memcpy", I->abegin(), --I->aend(), + I->abegin()->getType()); + break; + case Intrinsic::memmove: + EnsureFunctionExists(M, "memmove", I->abegin(), --I->aend(), + I->abegin()->getType()); + break; + case Intrinsic::memset: + EnsureFunctionExists(M, "memset", I->abegin(), --I->aend(), + I->abegin()->getType()); + break; + + } + +} void DefaultIntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { Function *Callee = CI->getCalledFunction(); From lattner at cs.uiuc.edu Sat May 8 23:30:20 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat May 8 23:30:20 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/IntrinsicLowering.h Message-ID: <200405090429.XAA23327@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: IntrinsicLowering.h updated: 1.4 -> 1.5 --- Log message: Add support for inserting all prototypes up-front --- Diffs of the changes: (+7 -0) Index: llvm/include/llvm/IntrinsicLowering.h diff -u llvm/include/llvm/IntrinsicLowering.h:1.4 llvm/include/llvm/IntrinsicLowering.h:1.5 --- llvm/include/llvm/IntrinsicLowering.h:1.4 Sun Dec 28 15:22:35 2003 +++ llvm/include/llvm/IntrinsicLowering.h Sat May 8 23:29:49 2004 @@ -37,10 +37,16 @@ namespace llvm { class CallInst; + class Module; struct IntrinsicLowering { virtual ~IntrinsicLowering() {} + /// AddPrototypes - This method, if called, causes all of the prototypes + /// that might be needed by an intrinsic lowering implementation to be + /// inserted into the module specified. + virtual void AddPrototypes(Module &M) = 0; + /// LowerIntrinsicCall - This method returns the LLVM function which should /// be used to implement the specified intrinsic function call. If an /// intrinsic function must be implemented by the code generator (such as @@ -59,6 +65,7 @@ /// implementations should pass any unhandled intrinsics to this /// implementation to allow for future extensibility. struct DefaultIntrinsicLowering : public IntrinsicLowering { + virtual void AddPrototypes(Module &M); virtual void LowerIntrinsicCall(CallInst *CI); }; } From gaeke at cs.uiuc.edu Sun May 9 00:28:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Sun May 9 00:28:01 2004 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200405090528.AAA23954@zion.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.175 -> 1.176 --- Log message: Bug fixed. Rewrite portability intro. --- Diffs of the changes: (+13 -9) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.175 llvm/docs/ReleaseNotes.html:1.176 --- llvm/docs/ReleaseNotes.html:1.175 Fri May 7 14:23:05 2004 +++ llvm/docs/ReleaseNotes.html Sun May 9 00:28:35 2004 @@ -142,6 +142,7 @@
      1. Minor configure bugs with -disable/enable-povray and -disable-spec
      2. +
      3. shell scripts output by gccld don't work if you change PATH
      @@ -227,14 +228,17 @@
      -

      LLVM has been extensively tested on Intel and AMD machines running Red -Hat Linux and FreeBSD. It has also been tested on Sun UltraSPARC workstations -running Solaris 8. Additionally, LLVM works on Mac OS X 10.3 and above, but -only with the C backend or interpreter (no native backend for the PowerPC is -available yet). The core LLVM infrastructure uses "autoconf" for portability, -so hopefully we work on more platforms than that. However, it is likely that we -missed something and that minor porting is required to get LLVM to work on new -platforms. We welcome portability patches and error messages.

      +

      LLVM has been extensively tested on Intel and AMD machines running Red Hat +Linux. It has also been tested under FreeBSD, and on Sun UltraSPARC +workstations running Solaris 8. Additionally, LLVM works on Mac OS X 10.3 and +above, but only with the C backend and interpreter; no native machine-code +generator for the PowerPC is available yet.

      + +

      The core LLVM infrastructure uses +GNU autoconf to adapt itself +to the machine and operating system on which it is built. However, minor +porting may be required to get LLVM to work on new platforms. We welcome your +portability patches and reports of successful builds or error messages.

      @@ -637,7 +641,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
      - Last modified: $Date: 2004/05/07 19:23:05 $ + Last modified: $Date: 2004/05/09 05:28:35 $ From lattner at cs.uiuc.edu Sun May 9 01:21:03 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun May 9 01:21:03 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/CBackend/Writer.cpp Message-ID: <200405090621.BAA26394@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/CBackend: Writer.cpp updated: 1.171 -> 1.172 --- Log message: Make the floating point constant pools local to each function, split the FindUsedTypes manipulation stuff out to be a seperate pass, and make the main CWriter be a function pass now! --- Diffs of the changes: (+113 -100) Index: llvm/lib/Target/CBackend/Writer.cpp diff -u llvm/lib/Target/CBackend/Writer.cpp:1.171 llvm/lib/Target/CBackend/Writer.cpp:1.172 --- llvm/lib/Target/CBackend/Writer.cpp:1.171 Sat May 8 23:30:20 2004 +++ llvm/lib/Target/CBackend/Writer.cpp Sun May 9 01:20:51 2004 @@ -38,36 +38,49 @@ using namespace llvm; namespace { - class CWriter : public Pass, public InstVisitor { + /// NameAllUsedStructs - This pass inserts names for any unnamed structure + /// types that are used by the program. + /// + class CBackendNameAllUsedStructs : public Pass { + void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + } + + virtual const char *getPassName() const { + return "C backend type canonicalizer"; + } + + virtual bool run(Module &M); + }; + + /// CWriter - This class is the main chunk of code that converts an LLVM + /// module to a C translation unit. + class CWriter : public FunctionPass, public InstVisitor { std::ostream &Out; IntrinsicLowering &IL; Mangler *Mang; const Module *TheModule; - FindUsedTypes *FUT; - std::map TypeNames; std::map FPConstantMap; public: CWriter(std::ostream &o, IntrinsicLowering &il) : Out(o), IL(il) {} - void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired(); - } - virtual const char *getPassName() const { return "C backend"; } - bool doInitialization(Module &M); - bool run(Module &M) { - doInitialization(M); - - for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) - if (!I->isExternal()) { - // First pass, lower all unhandled intrinsics. - lowerIntrinsics(*I); - printFunction(*I); - } + virtual bool doInitialization(Module &M); + bool runOnFunction(Function &F) { + // Output all floating point constants that cannot be printed accurately. + printFloatingPointConstants(F); + + lowerIntrinsics(F); + printFunction(F); + FPConstantMap.clear(); + return false; + } + + virtual bool doFinalization(Module &M) { // Free memory... delete Mang; TypeNames.clear(); @@ -86,9 +99,9 @@ bool nameAllUsedStructureTypes(Module &M); void printModule(Module *M); - void printFloatingPointConstants(Module &M); - void printSymbolTable(const SymbolTable &ST); + void printModuleTypes(const SymbolTable &ST); void printContainedStructs(const Type *Ty, std::set &); + void printFloatingPointConstants(Function &F); void printFunctionSignature(const Function *F, bool Prototype); void printFunction(Function &); @@ -172,6 +185,46 @@ }; } +/// This method inserts names for any unnamed structure types that are used by +/// the program, and removes names from structure types that are not used by the +/// program. +/// +bool CBackendNameAllUsedStructs::run(Module &M) { + // Get a set of types that are used by the program... + std::set UT = getAnalysis().getTypes(); + + // Loop over the module symbol table, removing types from UT that are + // already named, and removing names for structure types that are not used. + // + SymbolTable &MST = M.getSymbolTable(); + if (MST.find(Type::TypeTy) != MST.end()) + for (SymbolTable::type_iterator I = MST.type_begin(Type::TypeTy), + E = MST.type_end(Type::TypeTy); I != E; ) { + SymbolTable::type_iterator It = I++; + if (StructType *STy = dyn_cast(It->second)) { + // If this is not used, remove it from the symbol table. + std::set::iterator UTI = UT.find(STy); + if (UTI == UT.end()) + MST.remove(It->first, It->second); + else + UT.erase(UTI); + } + } + + // UT now contains types that are not named. Loop over it, naming + // structure types. + // + bool Changed = false; + for (std::set::const_iterator I = UT.begin(), E = UT.end(); + I != E; ++I) + if (const StructType *ST = dyn_cast(*I)) { + ((Value*)ST)->setName("unnamed", &MST); + Changed = true; + } + return Changed; +} + + // Pass the Type* and the variable name and this prints out the variable // declaration. // @@ -578,36 +631,6 @@ Out << ")"; } -// nameAllUsedStructureTypes - If there are structure types in the module that -// are used but do not have names assigned to them in the symbol table yet then -// we assign them names now. -// -bool CWriter::nameAllUsedStructureTypes(Module &M) { - // Get a set of types that are used by the program... - std::set UT = FUT->getTypes(); - - // Loop over the module symbol table, removing types from UT that are already - // named. - // - SymbolTable &MST = M.getSymbolTable(); - if (MST.find(Type::TypeTy) != MST.end()) - for (SymbolTable::type_iterator I = MST.type_begin(Type::TypeTy), - E = MST.type_end(Type::TypeTy); I != E; ++I) - UT.erase(cast(I->second)); - - // UT now contains types that are not named. Loop over it, naming structure - // types. - // - bool Changed = false; - for (std::set::const_iterator I = UT.begin(), E = UT.end(); - I != E; ++I) - if (const StructType *ST = dyn_cast(*I)) { - ((Value*)ST)->setName("unnamed", &MST); - Changed = true; - } - return Changed; -} - // generateCompilerSpecificCode - This is where we add conditional compilation // directives to cater to specific compilers as need be. // @@ -654,12 +677,10 @@ bool CWriter::doInitialization(Module &M) { // Initialize TheModule = &M; - FUT = &getAnalysis(); IL.AddPrototypes(M); // Ensure that all structure types have names... - bool Changed = nameAllUsedStructureTypes(M); Mang = new Mangler(M); // get declaration for alloca @@ -683,7 +704,7 @@ // // Loop over the symbol table, emitting all named constants... - printSymbolTable(M.getSymbolTable()); + printModuleTypes(M.getSymbolTable()); // Global variable declarations... if (!M.gempty()) { @@ -765,9 +786,6 @@ } } - // Output all floating point constants that cannot be printed accurately... - printFloatingPointConstants(M); - if (!M.empty()) Out << "\n\n/* Function Bodies */\n"; return false; @@ -775,7 +793,7 @@ /// Output all floating point constants that cannot be printed accurately... -void CWriter::printFloatingPointConstants(Module &M) { +void CWriter::printFloatingPointConstants(Function &F) { union { double D; uint64_t U; @@ -791,39 +809,38 @@ // the precision of the printed form, unless the printed form preserves // precision. // - unsigned FPCounter = 0; - for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) - for (constant_iterator I = constant_begin(F), E = constant_end(F); - I != E; ++I) - if (const ConstantFP *FPC = dyn_cast(*I)) - if (!isFPCSafeToPrint(FPC) && // Do not put in FPConstantMap if safe. - !FPConstantMap.count(FPC)) { - double Val = FPC->getValue(); - - FPConstantMap[FPC] = FPCounter; // Number the FP constants - - if (FPC->getType() == Type::DoubleTy) { - DBLUnion.D = Val; - Out << "static const ConstantDoubleTy FPConstant" << FPCounter++ - << " = 0x" << std::hex << DBLUnion.U << std::dec - << "ULL; /* " << Val << " */\n"; - } else if (FPC->getType() == Type::FloatTy) { - FLTUnion.F = Val; - Out << "static const ConstantFloatTy FPConstant" << FPCounter++ - << " = 0x" << std::hex << FLTUnion.U << std::dec - << "U; /* " << Val << " */\n"; - } else - assert(0 && "Unknown float type!"); - } + static unsigned FPCounter = 0; + for (constant_iterator I = constant_begin(&F), E = constant_end(&F); + I != E; ++I) + if (const ConstantFP *FPC = dyn_cast(*I)) + if (!isFPCSafeToPrint(FPC) && // Do not put in FPConstantMap if safe. + !FPConstantMap.count(FPC)) { + double Val = FPC->getValue(); + + FPConstantMap[FPC] = FPCounter; // Number the FP constants + + if (FPC->getType() == Type::DoubleTy) { + DBLUnion.D = Val; + Out << "static const ConstantDoubleTy FPConstant" << FPCounter++ + << " = 0x" << std::hex << DBLUnion.U << std::dec + << "ULL; /* " << Val << " */\n"; + } else if (FPC->getType() == Type::FloatTy) { + FLTUnion.F = Val; + Out << "static const ConstantFloatTy FPConstant" << FPCounter++ + << " = 0x" << std::hex << FLTUnion.U << std::dec + << "U; /* " << Val << " */\n"; + } else + assert(0 && "Unknown float type!"); + } Out << "\n"; - } +} /// printSymbolTable - Run through symbol table looking for type names. If a /// type name is found, emit it's declaration... /// -void CWriter::printSymbolTable(const SymbolTable &ST) { +void CWriter::printModuleTypes(const SymbolTable &ST) { // If there are no type names, exit early. if (ST.find(Type::TypeTy) == ST.end()) return; @@ -835,27 +852,23 @@ // Print out forward declarations for structure types before anything else! Out << "/* Structure forward decls */\n"; for (; I != End; ++I) - if (const Type *STy = dyn_cast(I->second)) - // Only print out used types! - if (FUT->getTypes().count(STy)) { - std::string Name = "struct l_" + Mangler::makeNameProper(I->first); - Out << Name << ";\n"; - TypeNames.insert(std::make_pair(STy, Name)); - } + if (const Type *STy = dyn_cast(I->second)) { + std::string Name = "struct l_" + Mangler::makeNameProper(I->first); + Out << Name << ";\n"; + TypeNames.insert(std::make_pair(STy, Name)); + } Out << "\n"; // Now we can print out typedefs... Out << "/* Typedefs */\n"; - for (I = ST.type_begin(Type::TypeTy); I != End; ++I) - // Only print out used types! - if (FUT->getTypes().count(cast(I->second))) { - const Type *Ty = cast(I->second); - std::string Name = "l_" + Mangler::makeNameProper(I->first); - Out << "typedef "; - printType(Out, Ty, Name); - Out << ";\n"; - } + for (I = ST.type_begin(Type::TypeTy); I != End; ++I) { + const Type *Ty = cast(I->second); + std::string Name = "l_" + Mangler::makeNameProper(I->first); + Out << "typedef "; + printType(Out, Ty, Name); + Out << ";\n"; + } Out << "\n"; @@ -869,8 +882,7 @@ for (I = ST.type_begin(Type::TypeTy); I != End; ++I) if (const StructType *STy = dyn_cast(I->second)) // Only print out used types! - if (FUT->getTypes().count(STy)) - printContainedStructs(STy, StructPrinted); + printContainedStructs(STy, StructPrinted); } // Push the struct onto the stack and recursively push all structs @@ -1450,6 +1462,7 @@ bool CTargetMachine::addPassesToEmitAssembly(PassManager &PM, std::ostream &o) { PM.add(createLowerAllocationsPass()); PM.add(createLowerInvokePass()); + PM.add(new CBackendNameAllUsedStructs()); PM.add(new CWriter(o, getIntrinsicLowering())); return false; } From lattner at cs.uiuc.edu Sun May 9 01:22:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun May 9 01:22:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/FindUsedTypes.cpp Message-ID: <200405090622.BAA26828@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: FindUsedTypes.cpp updated: 1.25 -> 1.26 --- Log message: Fine grainify namespacification --- Diffs of the changes: (+1 -4) Index: llvm/lib/Analysis/IPA/FindUsedTypes.cpp diff -u llvm/lib/Analysis/IPA/FindUsedTypes.cpp:1.25 llvm/lib/Analysis/IPA/FindUsedTypes.cpp:1.26 --- llvm/lib/Analysis/IPA/FindUsedTypes.cpp:1.25 Tue Apr 27 10:12:48 2004 +++ llvm/lib/Analysis/IPA/FindUsedTypes.cpp Sun May 9 01:22:29 2004 @@ -20,8 +20,7 @@ #include "llvm/SymbolTable.h" #include "llvm/Assembly/CachedWriter.h" #include "llvm/Support/InstIterator.h" - -namespace llvm { +using namespace llvm; static RegisterAnalysis X("printusedtypes", "Find Used Types"); @@ -108,5 +107,3 @@ E = UsedTypes.end(); I != E; ++I) o << " " << *I << "\n"; } - -} // End llvm namespace From lattner at cs.uiuc.edu Sun May 9 11:03:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun May 9 11:03:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/CBackend/Writer.cpp Message-ID: <200405091603.LAA11108@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/CBackend: Writer.cpp updated: 1.172 -> 1.173 --- Log message: Do not emit prototypes for setjmp/longjmp, as they are handled specially --- Diffs of the changes: (+2 -1) Index: llvm/lib/Target/CBackend/Writer.cpp diff -u llvm/lib/Target/CBackend/Writer.cpp:1.172 llvm/lib/Target/CBackend/Writer.cpp:1.173 --- llvm/lib/Target/CBackend/Writer.cpp:1.172 Sun May 9 01:20:51 2004 +++ llvm/lib/Target/CBackend/Writer.cpp Sun May 9 11:03:29 2004 @@ -723,7 +723,8 @@ Out << "\n/* Function Declarations */\n"; for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { // Don't print declarations for intrinsic functions. - if (!I->getIntrinsicID()) { + if (!I->getIntrinsicID() && + I->getName() != "setjmp" && I->getName() != "longjmp") { printFunctionSignature(I, true); if (I->hasWeakLinkage()) Out << " __ATTRIBUTE_WEAK__"; if (I->hasLinkOnceLinkage()) Out << " __ATTRIBUTE_WEAK__"; From lattner at cs.uiuc.edu Sun May 9 15:41:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun May 9 15:41:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/CBackend/Writer.cpp Message-ID: <200405092041.PAA17022@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/CBackend: Writer.cpp updated: 1.173 -> 1.174 --- Log message: syntactically loopify natural loops so that the GCC loop optimizer can find them. This should *dramatically* improve the performance of CBE compiled code on targets that depend on GCC's loop optimizations (like PPC) --- Diffs of the changes: (+86 -53) Index: llvm/lib/Target/CBackend/Writer.cpp diff -u llvm/lib/Target/CBackend/Writer.cpp:1.173 llvm/lib/Target/CBackend/Writer.cpp:1.174 --- llvm/lib/Target/CBackend/Writer.cpp:1.173 Sun May 9 11:03:29 2004 +++ llvm/lib/Target/CBackend/Writer.cpp Sun May 9 15:41:32 2004 @@ -23,8 +23,9 @@ #include "llvm/SymbolTable.h" #include "llvm/Intrinsics.h" #include "llvm/IntrinsicLowering.h" -#include "llvm/Analysis/FindUsedTypes.h" #include "llvm/Analysis/ConstantsScanner.h" +#include "llvm/Analysis/FindUsedTypes.h" +#include "llvm/Analysis/LoopInfo.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/CFG.h" @@ -59,6 +60,7 @@ std::ostream &Out; IntrinsicLowering &IL; Mangler *Mang; + LoopInfo *LI; const Module *TheModule; std::map TypeNames; @@ -68,9 +70,16 @@ virtual const char *getPassName() const { return "C backend"; } + void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + AU.setPreservesAll(); + } + virtual bool doInitialization(Module &M); bool runOnFunction(Function &F) { + LI = &getAnalysis(); + // Output all floating point constants that cannot be printed accurately. printFloatingPointConstants(F); @@ -84,7 +93,7 @@ // Free memory... delete Mang; TypeNames.clear(); - return true; + return false; } std::ostream &printType(std::ostream &Out, const Type *Ty, @@ -105,6 +114,8 @@ void printFunctionSignature(const Function *F, bool Prototype); void printFunction(Function &); + void printBasicBlock(BasicBlock *BB); + void printLoop(Loop *L); void printConstant(Constant *CPV); void printConstantArray(ConstantArray *CPA); @@ -147,8 +158,13 @@ void visitReturnInst(ReturnInst &I); void visitBranchInst(BranchInst &I); void visitSwitchInst(SwitchInst &I); - void visitInvokeInst(InvokeInst &I); - void visitUnwindInst(UnwindInst &I); + void visitInvokeInst(InvokeInst &I) { + assert(0 && "Lowerinvoke pass didn't work!"); + } + + void visitUnwindInst(UnwindInst &I) { + assert(0 && "Lowerinvoke pass didn't work!"); + } void visitPHINode(PHINode &I); void visitBinaryOperator(Instruction &I); @@ -176,6 +192,8 @@ void outputLValue(Instruction *I) { Out << " " << Mang->getValueName(I) << " = "; } + + bool isGotoCodeNecessary(BasicBlock *From, BasicBlock *To); void printPHICopiesForSuccessors(BasicBlock *CurBlock, unsigned Indent); void printBranchToBlock(BasicBlock *CurBlock, BasicBlock *SuccBlock, @@ -399,7 +417,7 @@ // compiler agreeing on the conversion process (which is pretty likely since we // only deal in IEEE FP). // -bool isFPCSafeToPrint(const ConstantFP *CFP) { +static bool isFPCSafeToPrint(const ConstantFP *CFP) { #if HAVE_PRINTF_A char Buffer[100]; sprintf(Buffer, "%a", CFP->getValue()); @@ -994,45 +1012,66 @@ // print the basic blocks for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { - BasicBlock *Prev = BB->getPrev(); - - // Don't print the label for the basic block if there are no uses, or if the - // only terminator use is the predecessor basic block's terminator. We have - // to scan the use list because PHI nodes use basic blocks too but do not - // require a label to be generated. - // - bool NeedsLabel = false; - for (Value::use_iterator UI = BB->use_begin(), UE = BB->use_end(); - UI != UE; ++UI) - if (TerminatorInst *TI = dyn_cast(*UI)) - if (TI != Prev->getTerminator() || - isa(Prev->getTerminator()) || - isa(Prev->getTerminator())) { - NeedsLabel = true; - break; - } - - if (NeedsLabel) Out << Mang->getValueName(BB) << ":\n"; - - // Output all of the instructions in the basic block... - for (BasicBlock::iterator II = BB->begin(), E = --BB->end(); II != E; ++II){ - if (!isInlinableInst(*II) && !isDirectAlloca(II)) { - if (II->getType() != Type::VoidTy) - outputLValue(II); - else - Out << " "; - visit(*II); - Out << ";\n"; - } + if (Loop *L = LI->getLoopFor(BB)) { + if (L->getHeader() == BB && L->getParentLoop() == 0) + printLoop(L); + } else { + printBasicBlock(BB); } - - // Don't emit prefix or suffix for the terminator... - visit(*BB->getTerminator()); } Out << "}\n\n"; } +void CWriter::printLoop(Loop *L) { + Out << " do { /* Syntactic loop '" << L->getHeader()->getName() + << "' to make GCC happy */\n"; + for (unsigned i = 0, e = L->getBlocks().size(); i != e; ++i) { + BasicBlock *BB = L->getBlocks()[i]; + Loop *BBLoop = LI->getLoopFor(BB); + if (BBLoop == L) + printBasicBlock(BB); + else if (BB == BBLoop->getHeader() && BBLoop->getParentLoop() == L) + printLoop(BBLoop); + } + Out << " } while (1); /* end of syntactic loop '" + << L->getHeader()->getName() << "' */\n"; +} + +void CWriter::printBasicBlock(BasicBlock *BB) { + + // Don't print the label for the basic block if there are no uses, or if + // the only terminator use is the predecessor basic block's terminator. + // We have to scan the use list because PHI nodes use basic blocks too but + // do not require a label to be generated. + // + bool NeedsLabel = false; + for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) + if (isGotoCodeNecessary(*PI, BB)) { + NeedsLabel = true; + break; + } + + if (NeedsLabel) Out << Mang->getValueName(BB) << ":\n"; + + // Output all of the instructions in the basic block... + for (BasicBlock::iterator II = BB->begin(), E = --BB->end(); II != E; + ++II) { + if (!isInlinableInst(*II) && !isDirectAlloca(II)) { + if (II->getType() != Type::VoidTy) + outputLValue(II); + else + Out << " "; + visit(*II); + Out << ";\n"; + } + } + + // Don't emit prefix or suffix for the terminator... + visit(*BB->getTerminator()); +} + + // Specific Instruction type classes... note that all of the casts are // necessary because we use the instruction classes as opaque types... // @@ -1072,22 +1111,18 @@ Out << " }\n"; } -void CWriter::visitInvokeInst(InvokeInst &II) { - assert(0 && "Lowerinvoke pass didn't work!"); -} +bool CWriter::isGotoCodeNecessary(BasicBlock *From, BasicBlock *To) { + /// FIXME: This should be reenabled, but loop reordering safe!! + return true; + if (From->getNext() != To) // Not the direct successor, we need a goto + return true; -void CWriter::visitUnwindInst(UnwindInst &I) { - assert(0 && "Lowerinvoke pass didn't work!"); -} + //isa(From->getTerminator()) -static bool isGotoCodeNecessary(BasicBlock *From, BasicBlock *To) { - // If PHI nodes need copies, we need the copy code... - if (isa(To->front()) || - From->getNext() != To) // Not directly successor, need goto - return true; - // Otherwise we don't need the code. + if (LI->getLoopFor(From) != LI->getLoopFor(To)) + return true; return false; } @@ -1108,9 +1143,7 @@ void CWriter::printBranchToBlock(BasicBlock *CurBB, BasicBlock *Succ, unsigned Indent) { - if (CurBB->getNext() != Succ || - isa(CurBB->getTerminator()) || - isa(CurBB->getTerminator())) { + if (isGotoCodeNecessary(CurBB, Succ)) { Out << std::string(Indent, ' ') << " goto "; writeOperand(Succ); Out << ";\n"; From lattner at cs.uiuc.edu Sun May 9 17:29:00 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun May 9 17:29:00 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200405092228.RAA18925@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.247 -> 1.248 --- Log message: Generate more efficient code for casting booleans to integers (no sign extension required) --- Diffs of the changes: (+1 -1) Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.247 llvm/lib/Target/X86/InstSelectSimple.cpp:1.248 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.247 Fri May 7 16:18:15 2004 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Sun May 9 17:28:45 2004 @@ -3051,7 +3051,7 @@ { X86::MOVZX16rr8, X86::MOVZX32rr8, X86::MOVZX32rr16, X86::MOV32rr } // u }; - bool isUnsigned = SrcTy->isUnsigned(); + bool isUnsigned = SrcTy->isUnsigned() || SrcTy == Type::BoolTy; BuildMI(*BB, IP, Opc[isUnsigned][SrcClass + DestClass - 1], 1, DestReg).addReg(SrcReg); From lattner at cs.uiuc.edu Sun May 9 18:16:00 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun May 9 18:16:00 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200405092316.SAA19761@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.248 -> 1.249 --- Log message: Fix some comments, avoid sign extending booleans when zero extend works fine --- Diffs of the changes: (+5 -5) Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.248 llvm/lib/Target/X86/InstSelectSimple.cpp:1.249 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.248 Sun May 9 17:28:45 2004 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Sun May 9 18:16:33 2004 @@ -886,9 +886,9 @@ // each, then uses a conditional move to handle the overflow case. For // example, a setlt for long would generate code like this: // - // AL = lo(op1) < lo(op2) // Signedness depends on operands - // BL = hi(op1) < hi(op2) // Always unsigned comparison - // dest = hi(op1) == hi(op2) ? AL : BL; + // AL = lo(op1) < lo(op2) // Always unsigned comparison + // BL = hi(op1) < hi(op2) // Signedness depends on operands + // dest = hi(op1) == hi(op2) ? BL : AL; // // FIXME: This would be much better if we had hierarchical register @@ -960,7 +960,7 @@ // // AL = lo(op1) < lo(op2) // Signedness depends on operands // BL = hi(op1) < hi(op2) // Always unsigned comparison - // dest = hi(op1) == hi(op2) ? AL : BL; + // dest = hi(op1) == hi(op2) ? BL : AL; // // FIXME: This would be much better if we had hierarchical register @@ -1193,7 +1193,7 @@ /// operand, in the specified target register. /// void ISel::promote32(unsigned targetReg, const ValueRecord &VR) { - bool isUnsigned = VR.Ty->isUnsigned(); + bool isUnsigned = VR.Ty->isUnsigned() || VR.Ty == Type::BoolTy; Value *Val = VR.Val; const Type *Ty = VR.Ty; From llvm at cs.uiuc.edu Sun May 9 18:20:01 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Sun May 9 18:20:01 2004 Subject: [llvm-commits] CVS: llvm/projects/Stacker/lib/runtime/stacker_rt.c Message-ID: <200405092320.SAA19960@zion.cs.uiuc.edu> Changes in directory llvm/projects/Stacker/lib/runtime: stacker_rt.c updated: 1.4 -> 1.5 --- Log message: Changes to make the Stacker Stack use 64 bit values. This *should* get around the problem with Stacker on Solaris because the Stack can handle 64-bit entries (pointer sized). --- Diffs of the changes: (+5 -5) Index: llvm/projects/Stacker/lib/runtime/stacker_rt.c diff -u llvm/projects/Stacker/lib/runtime/stacker_rt.c:1.4 llvm/projects/Stacker/lib/runtime/stacker_rt.c:1.5 --- llvm/projects/Stacker/lib/runtime/stacker_rt.c:1.4 Thu Nov 27 01:48:45 2003 +++ llvm/projects/Stacker/lib/runtime/stacker_rt.c Sun May 9 18:20:19 2004 @@ -21,18 +21,18 @@ #include #include -extern long long _index_; -extern int _stack_[]; +extern int64_t _index_; +extern int64_t _stack_[]; extern void _MAIN_(); void _stacker_dump_stack_() { - int i; + int64_t i; printf("Stack Dump:\n"); for (i = _index_; i > 0; i-- ) { - printf("#%03d: %d\n", i, _stack_[i] ); + printf("#%03lld: %lld\n", i, _stack_[i] ); } } @@ -51,7 +51,7 @@ { if ( isdigit( (int) argv[--a][0] ) ) { - _stack_[_index_++] = atoi( argv[a] ); + _stack_[_index_++] = atoll( argv[a] ); } else { From llvm at cs.uiuc.edu Sun May 9 18:20:06 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Sun May 9 18:20:06 2004 Subject: [llvm-commits] CVS: llvm/projects/Stacker/lib/compiler/Lexer.l StackerCompiler.cpp StackerCompiler.h StackerParser.y Message-ID: <200405092320.SAA19958@zion.cs.uiuc.edu> Changes in directory llvm/projects/Stacker/lib/compiler: Lexer.l updated: 1.2 -> 1.3 StackerCompiler.cpp updated: 1.5 -> 1.6 StackerCompiler.h updated: 1.2 -> 1.3 StackerParser.y updated: 1.4 -> 1.5 --- Log message: Changes to make the Stacker Stack use 64 bit values. This *should* get around the problem with Stacker on Solaris because the Stack can handle 64-bit entries (pointer sized). --- Diffs of the changes: (+32 -37) Index: llvm/projects/Stacker/lib/compiler/Lexer.l diff -u llvm/projects/Stacker/lib/compiler/Lexer.l:1.2 llvm/projects/Stacker/lib/compiler/Lexer.l:1.3 --- llvm/projects/Stacker/lib/compiler/Lexer.l:1.2 Tue Mar 30 21:49:47 2004 +++ llvm/projects/Stacker/lib/compiler/Lexer.l Sun May 9 18:20:19 2004 @@ -31,10 +31,10 @@ #include "StackerParser.h" /* Conversion of text ints to binary */ -static uint64_t IntToVal(const char *Buffer) { - uint64_t Result = 0; +static int64_t IntToVal(const char *Buffer) { + int64_t Result = 0; for (; *Buffer; Buffer++) { - uint64_t OldRes = Result; + int64_t OldRes = Result; Result *= 10; Result += *Buffer-'0'; if (Result < OldRes) // Uh, oh, overflow detected!!! @@ -44,10 +44,10 @@ } /* Conversion of text hexadecimal ints to binary */ -static uint64_t HexIntToVal(const char *Buffer) { - uint64_t Result = 0; +static int64_t HexIntToVal(const char *Buffer) { + int64_t Result = 0; for (; *Buffer; ++Buffer) { - uint64_t OldRes = Result; + int64_t OldRes = Result; Result *= 16; char C = *Buffer; if (C >= '0' && C <= '9') Index: llvm/projects/Stacker/lib/compiler/StackerCompiler.cpp diff -u llvm/projects/Stacker/lib/compiler/StackerCompiler.cpp:1.5 llvm/projects/Stacker/lib/compiler/StackerCompiler.cpp:1.6 --- llvm/projects/Stacker/lib/compiler/StackerCompiler.cpp:1.5 Tue Mar 30 21:49:47 2004 +++ llvm/projects/Stacker/lib/compiler/StackerCompiler.cpp Sun May 9 18:20:19 2004 @@ -60,9 +60,6 @@ , Three(0) , Four(0) , Five(0) - , IZero(0) - , IOne(0) - , ITwo(0) , no_arguments() , echo(false) , stack_size(256) @@ -121,8 +118,8 @@ TheModule = new Module( CurFilename ); // Create a type to represent the stack. This is the same as the LLVM - // Assembly type [ 256 x int ] - stack_type = ArrayType::get( Type::IntTy, stack_size ); + // Assembly type [ 256 x long ] + stack_type = ArrayType::get( Type::LongTy, stack_size ); // Create a global variable for the stack. Note the use of appending // linkage linkage so that multiple modules will make the stack larger. @@ -240,9 +237,6 @@ Three = ConstantInt::get( Type::LongTy, 3 ); Four = ConstantInt::get( Type::LongTy, 4 ); Five = ConstantInt::get( Type::LongTy, 5 ); - IZero = ConstantInt::get( Type::IntTy, 0 ); - IOne = ConstantInt::get( Type::IntTy, 1 ); - ITwo = ConstantInt::get( Type::IntTy, 2 ); // Reset the current line number Stackerlineno = 1; @@ -366,8 +360,8 @@ GetElementPtrInst* gep = cast( get_stack_pointer( bb ) ); - // Cast the value to an integer .. hopefully it works - CastInst* cast_inst = new CastInst( val, Type::IntTy ); + // Cast the value to a long .. hopefully it works + CastInst* cast_inst = new CastInst( val, Type::LongTy ); bb->getInstList().push_back( cast_inst ); // Store the value @@ -378,10 +372,10 @@ } Instruction* -StackerCompiler::push_integer(BasicBlock* bb, int32_t value ) +StackerCompiler::push_integer(BasicBlock* bb, int64_t value ) { // Just push a constant integer value - return push_value( bb, ConstantSInt::get( Type::IntTy, value ) ); + return push_value( bb, ConstantSInt::get( Type::LongTy, value ) ); } Instruction* @@ -639,7 +633,7 @@ // Compare the condition against 0 SetCondInst* cond_inst = new SetCondInst( Instruction::SetNE, cond, - ConstantSInt::get( Type::IntTy, 0) ); + ConstantSInt::get( Type::LongTy, 0) ); bb->getInstList().push_back( cond_inst ); // Create an exit block @@ -723,7 +717,7 @@ // Compare the condition against 0 SetCondInst* cond_inst = new SetCondInst( - Instruction::SetNE, cond, ConstantSInt::get( Type::IntTy, 0) ); + Instruction::SetNE, cond, ConstantSInt::get( Type::LongTy, 0) ); test->getInstList().push_back( cond_inst ); // Add the branch instruction @@ -789,7 +783,7 @@ } BasicBlock* -StackerCompiler::handle_integer( const int32_t value ) +StackerCompiler::handle_integer( const int64_t value ) { // Create a new basic block for the push operation BasicBlock* bb = new BasicBlock((echo?"int":"")); @@ -927,7 +921,7 @@ if (echo) bb->setName("INCR"); LoadInst* op1 = cast(pop_integer(bb)); BinaryOperator* addop = - BinaryOperator::create( Instruction::Add, op1, IOne ); + BinaryOperator::create( Instruction::Add, op1, One ); bb->getInstList().push_back( addop ); push_value( bb, addop ); break; @@ -937,7 +931,7 @@ if (echo) bb->setName("DECR"); LoadInst* op1 = cast(pop_integer(bb)); BinaryOperator* subop = BinaryOperator::create( Instruction::Sub, op1, - ConstantSInt::get( Type::IntTy, 1 ) ); + ConstantSInt::get( Type::LongTy, 1 ) ); bb->getInstList().push_back( subop ); push_value( bb, subop ); break; @@ -1007,7 +1001,7 @@ // bb->getInstList().push_back( negop ); // So we'll multiply by -1 (ugh) BinaryOperator* multop = BinaryOperator::create( Instruction::Mul, op1, - ConstantSInt::get( Type::IntTy, -1 ) ); + ConstantSInt::get( Type::LongTy, -1 ) ); bb->getInstList().push_back( multop ); push_value( bb, multop ); break; @@ -1020,7 +1014,7 @@ // Determine if its negative SetCondInst* cond_inst = - new SetCondInst( Instruction::SetLT, op1, IZero ); + new SetCondInst( Instruction::SetLT, op1, Zero ); bb->getInstList().push_back( cond_inst ); // Create a block for storing the result @@ -1367,7 +1361,7 @@ if (echo) bb->setName("PICK"); LoadInst* n = cast( stack_top( bb ) ); BinaryOperator* addop = - BinaryOperator::create( Instruction::Add, n, IOne ); + BinaryOperator::create( Instruction::Add, n, One ); bb->getInstList().push_back( addop ); LoadInst* x0 = cast( stack_top( bb, addop ) ); replace_top( bb, x0 ); @@ -1379,11 +1373,11 @@ LoadInst* m = cast( stack_top(bb) ); LoadInst* n = cast( stack_top(bb, One) ); BinaryOperator* index = - BinaryOperator::create( Instruction::Add, m, IOne ); + BinaryOperator::create( Instruction::Add, m, One ); bb->getInstList().push_back( index ); LoadInst* Xm = cast( stack_top(bb, index ) ); BinaryOperator* n_plus_1 = - BinaryOperator::create( Instruction::Add, n, IOne ); + BinaryOperator::create( Instruction::Add, n, One ); bb->getInstList().push_back( n_plus_1 ); decr_stack_index( bb, n_plus_1 ); replace_top( bb, Xm ); @@ -1496,9 +1490,13 @@ // Get the result value LoadInst* op1 = cast(pop_integer(bb)); + // Cast down to an integer + CastInst* caster = new CastInst( op1, Type::IntTy ); + bb->getInstList().push_back( caster ); + // Call exit(3) std::vector params; - params.push_back(op1); + params.push_back(caster); CallInst* call_inst = new CallInst( TheExit, params ); bb->getInstList().push_back( call_inst ); break; @@ -1514,7 +1512,7 @@ new GetElementPtrInst( ChrFormat, indexVec ); bb->getInstList().push_back( format_gep ); - // Get the character to print (a newline) + // Get the character to print (a tab) ConstantSInt* newline = ConstantSInt::get(Type::IntTy, static_cast('\t')); @@ -1536,7 +1534,7 @@ new GetElementPtrInst( ChrFormat, indexVec ); bb->getInstList().push_back( format_gep ); - // Get the character to print (a newline) + // Get the character to print (a space) ConstantSInt* newline = ConstantSInt::get(Type::IntTy, static_cast(' ')); Index: llvm/projects/Stacker/lib/compiler/StackerCompiler.h diff -u llvm/projects/Stacker/lib/compiler/StackerCompiler.h:1.2 llvm/projects/Stacker/lib/compiler/StackerCompiler.h:1.3 --- llvm/projects/Stacker/lib/compiler/StackerCompiler.h:1.2 Thu Apr 15 10:38:48 2004 +++ llvm/projects/Stacker/lib/compiler/StackerCompiler.h Sun May 9 18:20:19 2004 @@ -140,7 +140,7 @@ /// @brief Handle the push of an integer onto the stack. /// @param value The integer value to be pushed. - BasicBlock* handle_integer( const int32_t value ); + BasicBlock* handle_integer( const int64_t value ); /// @brief Handle one of the reserved words (given as a token) BasicBlock* handle_word( int tkn ); @@ -169,7 +169,7 @@ /// @brief Generate code to push any value onto the stack. Instruction* push_value( BasicBlock* bb, Value* value ); /// @brief Generate code to push a constant integer onto the stack. - Instruction* push_integer( BasicBlock* bb, int32_t value ); + Instruction* push_integer( BasicBlock* bb, int64_t value ); /// @brief Generate code to pop an integer off the stack. Instruction* pop_integer( BasicBlock* bb ); /// @brief Generate code to push a string pointer onto the stack. @@ -211,9 +211,6 @@ ConstantInt* Three; ///< long constant 3 ConstantInt* Four; ///< long constant 4 ConstantInt* Five; ///< long constant 5 - ConstantInt* IZero; ///< int constant 0 - ConstantInt* IOne; ///< int constant 1 - ConstantInt* ITwo; ///< int constant 2 std::vector no_arguments; ///< no arguments for Stacker bool echo; ///< Echo flag size_t stack_size; ///< Size of stack to gen. Index: llvm/projects/Stacker/lib/compiler/StackerParser.y diff -u llvm/projects/Stacker/lib/compiler/StackerParser.y:1.4 llvm/projects/Stacker/lib/compiler/StackerParser.y:1.5 --- llvm/projects/Stacker/lib/compiler/StackerParser.y:1.4 Tue Mar 30 21:49:47 2004 +++ llvm/projects/Stacker/lib/compiler/StackerParser.y Sun May 9 18:20:19 2004 @@ -39,7 +39,7 @@ llvm::Module* ModuleVal; llvm::Function* FunctionVal; llvm::BasicBlock* BasicBlockVal; - uint32_t IntegerVal; + int64_t IntegerVal; char* StringVal; } From llvm at cs.uiuc.edu Sun May 9 18:32:00 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Sun May 9 18:32:00 2004 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200405092332.SAA20089@zion.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.176 -> 1.177 --- Log message: Bug 178: http://llvm.cs.uiuc.edu/PR178 Fixed --- Diffs of the changes: (+3 -1) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.176 llvm/docs/ReleaseNotes.html:1.177 --- llvm/docs/ReleaseNotes.html:1.176 Sun May 9 00:28:35 2004 +++ llvm/docs/ReleaseNotes.html Sun May 9 18:32:39 2004 @@ -118,6 +118,8 @@ more than 256 elements
    9. [bugpoint] External functions used in non-instruction entities, such as global constant initializer
    10. +
    11. Stacker does not handle targets +with 64-bit pointers.
    12. Bugpoint doesn't support uses of external fns by immediate constant exprs
    @@ -641,7 +643,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/05/09 05:28:35 $ + Last modified: $Date: 2004/05/09 23:32:39 $