From sabre at nondot.org Mon Dec 1 00:11:33 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 01 Dec 2008 06:11:33 -0000 Subject: [llvm-commits] [llvm] r60329 - /llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200812010611.mB16BXFE009610@zion.cs.uiuc.edu> Author: lattner Date: Mon Dec 1 00:11:32 2008 New Revision: 60329 URL: http://llvm.org/viewvc/llvm-project?rev=60329&view=rev Log: simplify DeleteTriviallyDeadInstructions again, unlike my previous buggy rewrite, this notifies ScalarEvolution of a pending instruction about to be removed and then erases it, instead of erasing it then notifying. Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=60329&r1=60328&r2=60329&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Mon Dec 1 00:11:32 2008 @@ -244,28 +244,21 @@ Instruction *I = Insts.back(); Insts.pop_back(); - if (PHINode *PN = dyn_cast(I)) { - // If all incoming values to the Phi are the same, we can replace the Phi - // with that value. - if (Value *PNV = PN->hasConstantValue()) { - if (Instruction *U = dyn_cast(PNV)) - Insts.insert(U); - SE->deleteValueFromRecords(PN); - PN->replaceAllUsesWith(PNV); - PN->eraseFromParent(); - Changed = true; - continue; - } - } + if (!isInstructionTriviallyDead(I)) + continue; + + SE->deleteValueFromRecords(I); - if (isInstructionTriviallyDead(I)) { - for (User::op_iterator i = I->op_begin(), e = I->op_end(); i != e; ++i) - if (Instruction *U = dyn_cast(*i)) + for (User::op_iterator i = I->op_begin(), e = I->op_end(); i != e; ++i) { + if (Instruction *U = dyn_cast(*i)) { + *i = 0; + if (U->use_empty()) Insts.insert(U); - SE->deleteValueFromRecords(I); - I->eraseFromParent(); - Changed = true; + } } + + I->eraseFromParent(); + Changed = true; } } @@ -2067,7 +2060,7 @@ BasicBlock::iterator I = L->getHeader()->begin(); while (PHINode *PN = dyn_cast(I++)) { // At this point, we know that we have killed one or more IV users. - // It is worth checking to see if the cann indvar is also + // It is worth checking to see if the cannonical indvar is also // dead, so that we can remove it as well. // // We can remove a PHI if it is on a cycle in the def-use graph From sabre at nondot.org Mon Dec 1 00:14:28 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 01 Dec 2008 06:14:28 -0000 Subject: [llvm-commits] [llvm] r60330 - /llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200812010614.mB16ESAT009694@zion.cs.uiuc.edu> Author: lattner Date: Mon Dec 1 00:14:28 2008 New Revision: 60330 URL: http://llvm.org/viewvc/llvm-project?rev=60330&view=rev Log: DeleteTriviallyDeadInstructions is always passed the DeadInsts ivar, just use it directly. Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=60330&r1=60329&r2=60330&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Mon Dec 1 00:14:28 2008 @@ -205,7 +205,7 @@ void StrengthReduceStridedIVUsers(const SCEVHandle &Stride, IVUsersOfOneStride &Uses, Loop *L, bool isOnlyStride); - void DeleteTriviallyDeadInstructions(SetVector &Insts); + void DeleteTriviallyDeadInstructions(); }; } @@ -238,11 +238,10 @@ /// DeleteTriviallyDeadInstructions - If any of the instructions is the /// specified set are trivially dead, delete them and see if this makes any of /// their operands subsequently dead. -void LoopStrengthReduce:: -DeleteTriviallyDeadInstructions(SetVector &Insts) { - while (!Insts.empty()) { - Instruction *I = Insts.back(); - Insts.pop_back(); +void LoopStrengthReduce::DeleteTriviallyDeadInstructions() { + while (!DeadInsts.empty()) { + Instruction *I = DeadInsts.back(); + DeadInsts.pop_back(); if (!isInstructionTriviallyDead(I)) continue; @@ -253,7 +252,7 @@ if (Instruction *U = dyn_cast(*i)) { *i = 0; if (U->use_empty()) - Insts.insert(U); + DeadInsts.insert(U); } } @@ -1441,7 +1440,7 @@ Rewriter, L, this, DeadInsts); - // Mark old value we replaced as possibly dead, so that it is elminated + // Mark old value we replaced as possibly dead, so that it is eliminated // if we just replaced the last use of that value. DeadInsts.insert(cast(User.OperandValToReplace)); @@ -2055,7 +2054,7 @@ // Clean up after ourselves if (!DeadInsts.empty()) { - DeleteTriviallyDeadInstructions(DeadInsts); + DeleteTriviallyDeadInstructions(); BasicBlock::iterator I = L->getHeader()->begin(); while (PHINode *PN = dyn_cast(I++)) { @@ -2091,7 +2090,7 @@ break; } } - DeleteTriviallyDeadInstructions(DeadInsts); + DeleteTriviallyDeadInstructions(); } return Changed; } From sabre at nondot.org Mon Dec 1 00:27:42 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 01 Dec 2008 06:27:42 -0000 Subject: [llvm-commits] [llvm] r60332 - /llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200812010627.mB16RgaT010178@zion.cs.uiuc.edu> Author: lattner Date: Mon Dec 1 00:27:41 2008 New Revision: 60332 URL: http://llvm.org/viewvc/llvm-project?rev=60332&view=rev Log: Eliminate use of setvector for the DeadInsts set, just use a smallvector. This is a lot cheaper and conceptually simpler. Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=60332&r1=60331&r2=60332&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Mon Dec 1 00:27:41 2008 @@ -31,7 +31,6 @@ #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Target/TargetData.h" -#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/Debug.h" @@ -138,7 +137,7 @@ /// DeadInsts - Keep track of instructions we may have made dead, so that /// we can remove them after we are done working. - SetVector DeadInsts; + SmallVector DeadInsts; /// TLI - Keep a pointer of a TargetLowering to consult for determining /// transformation profitability. @@ -230,7 +229,7 @@ if (New) return New; New = SCEVExpander::InsertCastOfTo(opcode, V, UIntPtrTy); - DeadInsts.insert(cast(New)); + DeadInsts.push_back(cast(New)); return New; } @@ -239,20 +238,35 @@ /// specified set are trivially dead, delete them and see if this makes any of /// their operands subsequently dead. void LoopStrengthReduce::DeleteTriviallyDeadInstructions() { + if (DeadInsts.empty()) return; + + // Sort the deadinsts list so that we can trivially eliminate duplicates as we + // go. The code below never adds a non-dead instruction to the worklist, but + // callers may not be so careful. + std::sort(DeadInsts.begin(), DeadInsts.end()); + + // Drop duplicate instructions and those with uses. + for (unsigned i = 0, e = DeadInsts.size()-1; i < e; ++i) { + Instruction *I = DeadInsts[i]; + if (!I->use_empty()) DeadInsts[i] = 0; + while (DeadInsts[i+1] == I && i != e) + DeadInsts[++i] = 0; + } + while (!DeadInsts.empty()) { Instruction *I = DeadInsts.back(); DeadInsts.pop_back(); - - if (!isInstructionTriviallyDead(I)) + + if (I == 0 || !isInstructionTriviallyDead(I)) continue; SE->deleteValueFromRecords(I); - for (User::op_iterator i = I->op_begin(), e = I->op_end(); i != e; ++i) { - if (Instruction *U = dyn_cast(*i)) { - *i = 0; + for (User::op_iterator OI = I->op_begin(), E = I->op_end(); OI != E; ++OI) { + if (Instruction *U = dyn_cast(*OI)) { + *OI = 0; if (U->use_empty()) - DeadInsts.insert(U); + DeadInsts.push_back(U); } } @@ -383,7 +397,7 @@ /// should use the post-inc value). static bool IVUseShouldUsePostIncValue(Instruction *User, Instruction *IV, Loop *L, DominatorTree *DT, Pass *P, - SetVector &DeadInsts){ + SmallVectorImpl &DeadInsts){ // If the user is in the loop, use the preinc value. if (L->contains(User->getParent())) return false; @@ -425,7 +439,7 @@ } // PHI node might have become a constant value after SplitCriticalEdge. - DeadInsts.insert(User); + DeadInsts.push_back(User); return true; } @@ -551,7 +565,7 @@ void RewriteInstructionToUseNewBase(const SCEVHandle &NewBase, Instruction *InsertPt, SCEVExpander &Rewriter, Loop *L, Pass *P, - SetVector &DeadInsts); + SmallVectorImpl &DeadInsts); Value *InsertCodeForBaseAtPosition(const SCEVHandle &NewBase, SCEVExpander &Rewriter, @@ -616,7 +630,7 @@ void BasedUser::RewriteInstructionToUseNewBase(const SCEVHandle &NewBase, Instruction *NewBasePt, SCEVExpander &Rewriter, Loop *L, Pass *P, - SetVector &DeadInsts) { + SmallVectorImpl &DeadInsts){ if (!isa(Inst)) { // By default, insert code at the user instruction. BasicBlock::iterator InsertPt = Inst; @@ -713,7 +727,7 @@ } // PHI node might have become a constant value after SplitCriticalEdge. - DeadInsts.insert(Inst); + DeadInsts.push_back(Inst); DOUT << " CHANGED: IMM =" << *Imm << " Inst = " << *Inst; } @@ -1442,7 +1456,7 @@ // Mark old value we replaced as possibly dead, so that it is eliminated // if we just replaced the last use of that value. - DeadInsts.insert(cast(User.OperandValToReplace)); + DeadInsts.push_back(cast(User.OperandValToReplace)); UsersToProcess.pop_back(); ++NumReduced; @@ -1672,7 +1686,7 @@ OldCond); // Remove the old compare instruction. The old indvar is probably dead too. - DeadInsts.insert(cast(CondUse->OperandValToReplace)); + DeadInsts.push_back(cast(CondUse->OperandValToReplace)); SE->deleteValueFromRecords(OldCond); OldCond->replaceAllUsesWith(Cond); OldCond->eraseFromParent(); @@ -2080,7 +2094,7 @@ // Break the cycle and mark the PHI for deletion. SE->deleteValueFromRecords(PN); PN->replaceAllUsesWith(UndefValue::get(PN->getType())); - DeadInsts.insert(PN); + DeadInsts.push_back(PN); Changed = true; break; } From sabre at nondot.org Mon Dec 1 00:49:59 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 01 Dec 2008 06:49:59 -0000 Subject: [llvm-commits] [llvm] r60335 - in /llvm/trunk: include/llvm/ADT/STLExtras.h lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200812010649.mB16nxiS010841@zion.cs.uiuc.edu> Author: lattner Date: Mon Dec 1 00:49:59 2008 New Revision: 60335 URL: http://llvm.org/viewvc/llvm-project?rev=60335&view=rev Log: Introduce a new array_pod_sort function and switch LSR to use it instead of std::sort. This shrinks the release-asserts LSR.o file by 1100 bytes of code on my system. We should start using array_pod_sort where possible. Modified: llvm/trunk/include/llvm/ADT/STLExtras.h llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/include/llvm/ADT/STLExtras.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/STLExtras.h?rev=60335&r1=60334&r2=60335&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/STLExtras.h (original) +++ llvm/trunk/include/llvm/ADT/STLExtras.h Mon Dec 1 00:49:59 2008 @@ -204,7 +204,7 @@ } //===----------------------------------------------------------------------===// -// Extra additions to arrays +// Extra additions for arrays //===----------------------------------------------------------------------===// /// Find where an array ends (for ending iterators) @@ -221,6 +221,43 @@ return N; } +/// array_pod_sort_comparator - This is helper function for array_pod_sort, +/// which does a memcmp of a specific size. +template +static inline int array_pod_sort_comparator(const void *P1, const void *P2) { + if (Size == sizeof(char)) + return *(const char*)P1 - *(const char*)P2; + if (Size == sizeof(int)) + return *(const int*)P1 - *(const int*)P2; + if (Size == sizeof(long long)) + return *(const long long*)P1 - *(const long long*)P2; + if (Size == sizeof(intptr_t)) + return *(intptr_t*)P1 - *(intptr_t*)P2; + return memcmp(P1, P2, Size); +} + +/// array_pod_sort - This sorts an array with the specified start and end +/// extent. This is just like std::sort, except that it calls qsort instead of +/// using an inlined template. qsort is slightly slower than std::sort, but +/// most sorts are not performance critical in LLVM and std::sort has to be +/// template instantiated for each type, leading to significant measured code +/// bloat. This function should generally be used instead of std::sort where +/// possible. +/// +/// This function assumes that you have simple POD-like types that can be +/// compared with memcmp and can be moved with memcpy. If this isn't true, you +/// should use std::sort. +/// +/// NOTE: If qsort_r were portable, we could allow a custom comparator and +/// default to std::less. +template +static inline void array_pod_sort(IteratorTy Start, IteratorTy End) { + // Don't dereference start iterator of empty sequence. + if (Start == End) return; + qsort(Start, End-Start, sizeof(*Start), + array_pod_sort_comparator); +} + } // End llvm namespace #endif Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=60335&r1=60334&r2=60335&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Mon Dec 1 00:49:59 2008 @@ -243,7 +243,7 @@ // Sort the deadinsts list so that we can trivially eliminate duplicates as we // go. The code below never adds a non-dead instruction to the worklist, but // callers may not be so careful. - std::sort(DeadInsts.begin(), DeadInsts.end()); + array_pod_sort(DeadInsts.begin(), DeadInsts.end()); // Drop duplicate instructions and those with uses. for (unsigned i = 0, e = DeadInsts.size()-1; i < e; ++i) { From sabre at nondot.org Mon Dec 1 00:50:46 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 01 Dec 2008 06:50:46 -0000 Subject: [llvm-commits] [llvm] r60336 - /llvm/trunk/include/llvm/ADT/STLExtras.h Message-ID: <200812010650.mB16okVE010879@zion.cs.uiuc.edu> Author: lattner Date: Mon Dec 1 00:50:46 2008 New Revision: 60336 URL: http://llvm.org/viewvc/llvm-project?rev=60336&view=rev Log: don't assume iterators implicitly convert to pointers. Modified: llvm/trunk/include/llvm/ADT/STLExtras.h Modified: llvm/trunk/include/llvm/ADT/STLExtras.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/STLExtras.h?rev=60336&r1=60335&r2=60336&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/STLExtras.h (original) +++ llvm/trunk/include/llvm/ADT/STLExtras.h Mon Dec 1 00:50:46 2008 @@ -254,7 +254,7 @@ static inline void array_pod_sort(IteratorTy Start, IteratorTy End) { // Don't dereference start iterator of empty sequence. if (Start == End) return; - qsort(Start, End-Start, sizeof(*Start), + qsort(&*Start, End-Start, sizeof(*Start), array_pod_sort_comparator); } From sabre at nondot.org Mon Dec 1 00:52:58 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 01 Dec 2008 06:52:58 -0000 Subject: [llvm-commits] [llvm] r60337 - in /llvm/trunk/lib/Transforms/Scalar: JumpThreading.cpp LoopUnswitch.cpp Message-ID: <200812010652.mB16qw0L010943@zion.cs.uiuc.edu> Author: lattner Date: Mon Dec 1 00:52:57 2008 New Revision: 60337 URL: http://llvm.org/viewvc/llvm-project?rev=60337&view=rev Log: switch a couple more calls to use array_pod_sort. Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=60337&r1=60336&r2=60337&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Mon Dec 1 00:52:57 2008 @@ -17,6 +17,7 @@ #include "llvm/Pass.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Statistic.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/Local.h" @@ -380,7 +381,7 @@ // Now we know that each predecessor of this block has a value in // AvailablePreds, sort them for efficient access as we're walking the preds. - std::sort(AvailablePreds.begin(), AvailablePreds.end()); + array_pod_sort(AvailablePreds.begin(), AvailablePreds.end()); // Create a PHI node at the start of the block for the PRE'd load value. PHINode *PN = PHINode::Create(LI->getType(), "", LoadBB->begin()); Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp?rev=60337&r1=60336&r2=60337&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp Mon Dec 1 00:52:57 2008 @@ -41,6 +41,7 @@ #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" @@ -834,14 +835,14 @@ // Remove phi node entries in successors for this block. TerminatorInst *TI = BB->getTerminator(); - std::vector Succs; + SmallVector Succs; for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) { Succs.push_back(TI->getSuccessor(i)); TI->getSuccessor(i)->removePredecessor(BB); } // Unique the successors, remove anything with multiple uses. - std::sort(Succs.begin(), Succs.end()); + array_pod_sort(Succs.begin(), Succs.end()); Succs.erase(std::unique(Succs.begin(), Succs.end()), Succs.end()); // Remove the basic block, including all of the instructions contained in it. From sabre at nondot.org Mon Dec 1 01:29:03 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 01 Dec 2008 07:29:03 -0000 Subject: [llvm-commits] [llvm] r60338 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp Message-ID: <200812010729.mB17T3pI012084@zion.cs.uiuc.edu> Author: lattner Date: Mon Dec 1 01:29:03 2008 New Revision: 60338 URL: http://llvm.org/viewvc/llvm-project?rev=60338&view=rev Log: pull the predMap densemap out of the inner loop of performPRE, so that it isn't reallocated all the time. This is a tiny speedup for GVN: 3.90->3.88s Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=60338&r1=60337&r2=60338&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Mon Dec 1 01:29:03 2008 @@ -1225,6 +1225,7 @@ bool GVN::performPRE(Function& F) { bool changed = false; SmallVector, 4> toSplit; + DenseMap predMap; for (df_iterator DI = df_begin(&F.getEntryBlock()), DE = df_end(&F.getEntryBlock()); DI != DE; ++DI) { BasicBlock* CurrentBlock = *DI; @@ -1252,7 +1253,8 @@ unsigned numWith = 0; unsigned numWithout = 0; BasicBlock* PREPred = 0; - DenseMap predMap; + predMap.clear(); + for (pred_iterator PI = pred_begin(CurrentBlock), PE = pred_end(CurrentBlock); PI != PE; ++PI) { // We're not interested in PRE where the block is its @@ -1359,7 +1361,7 @@ Instruction* erase = BI; BI++; - DEBUG(cerr << "GVN removed: " << *erase); + DEBUG(cerr << "GVN PRE removed: " << *erase); MD->removeInstruction(erase); erase->eraseFromParent(); changed = true; From sabre at nondot.org Mon Dec 1 01:35:54 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 01 Dec 2008 07:35:54 -0000 Subject: [llvm-commits] [llvm] r60339 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp Message-ID: <200812010735.mB17ZsOK012261@zion.cs.uiuc.edu> Author: lattner Date: Mon Dec 1 01:35:54 2008 New Revision: 60339 URL: http://llvm.org/viewvc/llvm-project?rev=60339&view=rev Log: Rename some variables, only increment BI once at the start of the loop instead of throughout it. Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=60339&r1=60338&r2=60339&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Mon Dec 1 01:35:54 2008 @@ -1223,7 +1223,7 @@ /// performPRE - Perform a purely local form of PRE that looks for diamond /// control flow patterns and attempts to perform simple PRE at the join point. bool GVN::performPRE(Function& F) { - bool changed = false; + bool Changed = false; SmallVector, 4> toSplit; DenseMap predMap; for (df_iterator DI = df_begin(&F.getEntryBlock()), @@ -1235,14 +1235,14 @@ for (BasicBlock::iterator BI = CurrentBlock->begin(), BE = CurrentBlock->end(); BI != BE; ) { - if (isa(BI) || isa(BI) || - isa(BI) || BI->mayReadFromMemory() || - BI->mayWriteToMemory()) { - BI++; + Instruction *CurInst = BI++; + + if (isa(CurInst) || isa(CurInst) || + isa(CurInst) || CurInst->mayReadFromMemory() || + CurInst->mayWriteToMemory()) continue; - } - uint32_t valno = VN.lookup(BI); + uint32_t valno = VN.lookup(CurInst); // Look for the predecessors for PRE opportunities. We're // only trying to solve the basic diamond case, where @@ -1273,7 +1273,7 @@ if (predV == localAvail[*PI]->table.end()) { PREPred = *PI; numWithout++; - } else if (predV->second == BI) { + } else if (predV->second == CurInst) { numWithout = 2; } else { predMap[*PI] = predV->second; @@ -1283,10 +1283,8 @@ // Don't do PRE when it might increase code size, i.e. when // we would need to insert instructions in more than one pred. - if (numWithout != 1 || numWith == 0) { - BI++; + if (numWithout != 1 || numWith == 0) continue; - } // We can't do PRE safely on a critical edge, so instead we schedule // the edge to be split and perform the PRE the next time we iterate @@ -1301,8 +1299,6 @@ if (isCriticalEdge(PREPred->getTerminator(), succNum)) { toSplit.push_back(std::make_pair(PREPred->getTerminator(), succNum)); - changed = true; - BI++; continue; } @@ -1311,19 +1307,18 @@ // will be available in the predecessor by the time we need them. Any // that weren't original present will have been instantiated earlier // in this loop. - Instruction* PREInstr = BI->clone(); + Instruction* PREInstr = CurInst->clone(); bool success = true; - for (unsigned i = 0; i < BI->getNumOperands(); ++i) { - Value* op = BI->getOperand(i); - if (isa(op) || isa(op) || isa(op)) - PREInstr->setOperand(i, op); - else { - Value* V = lookupNumber(PREPred, VN.lookup(op)); - if (!V) { - success = false; - break; - } else - PREInstr->setOperand(i, V); + for (unsigned i = 0, e = CurInst->getNumOperands(); i != e; ++i) { + Value *Op = PREInstr->getOperand(i); + if (isa(Op) || isa(Op) || isa(Op)) + continue; + + if (Value *V = lookupNumber(PREPred, VN.lookup(Op))) { + PREInstr->setOperand(i, V); + } else { + success = false; + break; } } @@ -1332,12 +1327,11 @@ // are not value numbered precisely. if (!success) { delete PREInstr; - BI++; continue; } PREInstr->insertBefore(PREPred->getTerminator()); - PREInstr->setName(BI->getName() + ".pre"); + PREInstr->setName(CurInst->getName() + ".pre"); predMap[PREPred] = PREInstr; VN.add(PREInstr, valno); NumGVNPRE++; @@ -1346,8 +1340,8 @@ localAvail[PREPred]->table.insert(std::make_pair(valno, PREInstr)); // Create a PHI to make the value available in this block. - PHINode* Phi = PHINode::Create(BI->getType(), - BI->getName() + ".pre-phi", + PHINode* Phi = PHINode::Create(CurInst->getType(), + CurInst->getName() + ".pre-phi", CurrentBlock->begin()); for (pred_iterator PI = pred_begin(CurrentBlock), PE = pred_end(CurrentBlock); PI != PE; ++PI) @@ -1356,15 +1350,13 @@ VN.add(Phi, valno); localAvail[CurrentBlock]->table[valno] = Phi; - BI->replaceAllUsesWith(Phi); - VN.erase(BI); + CurInst->replaceAllUsesWith(Phi); + VN.erase(CurInst); - Instruction* erase = BI; - BI++; - DEBUG(cerr << "GVN PRE removed: " << *erase); - MD->removeInstruction(erase); - erase->eraseFromParent(); - changed = true; + DEBUG(cerr << "GVN PRE removed: " << *CurInst); + MD->removeInstruction(CurInst); + CurInst->eraseFromParent(); + Changed = true; } } @@ -1372,7 +1364,7 @@ I = toSplit.begin(), E = toSplit.end(); I != E; ++I) SplitCriticalEdge(I->first, I->second, this); - return changed || toSplit.size(); + return Changed || toSplit.size(); } // iterateOnFunction - Executes one iteration of GVN From isanbard at gmail.com Mon Dec 1 01:47:03 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 01 Dec 2008 07:47:03 -0000 Subject: [llvm-commits] [llvm] r60340 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200812010747.mB17l3m2012595@zion.cs.uiuc.edu> Author: void Date: Mon Dec 1 01:47:02 2008 New Revision: 60340 URL: http://llvm.org/viewvc/llvm-project?rev=60340&view=rev Log: Move pattern check outside of the if-then statement. This prevents us from fiddling with constants unless we have to. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60340&r1=60339&r2=60340&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Mon Dec 1 01:47:02 2008 @@ -2928,17 +2928,19 @@ if (RHS->isAllOnesValue()) return BinaryOperator::CreateNeg(Op0); - ConstantInt *RHSNeg = cast(ConstantExpr::getNeg(RHS)); - APInt RHSNegAPI(RHSNeg->getValue()); - - APInt NegOne = -APInt(RHSNeg->getBitWidth(), 1, true); - APInt TwoToExp(RHSNeg->getBitWidth(), 1 << (RHSNeg->getBitWidth() - 1)); - // -X/C -> X/-C, if and only if negation doesn't overflow. - if ((RHS->getValue().isNegative() && RHSNegAPI.slt(TwoToExp - 1)) || - (RHS->getValue().isNonNegative() && RHSNegAPI.sgt(TwoToExp * NegOne))) { - if (Value *LHSNeg = dyn_castNegVal(Op0)) { - if (ConstantInt *CI = dyn_cast(LHSNeg)) { + if (Value *LHSNeg = dyn_castNegVal(Op0)) { + if (ConstantInt *CI = dyn_cast(LHSNeg)) { + ConstantInt *RHSNeg = cast(ConstantExpr::getNeg(RHS)); + APInt RHSNegAPI(RHSNeg->getValue()); + + APInt NegOne = -APInt(RHSNeg->getBitWidth(), 1, true); + APInt TwoToExp(RHSNeg->getBitWidth(), 1 << (RHSNeg->getBitWidth() - 1)); + + if ((RHS->getValue().isNegative() && + RHSNegAPI.slt(TwoToExp - 1)) || + (RHS->getValue().isNonNegative() && + RHSNegAPI.sgt(TwoToExp * NegOne))) { ConstantInt *CINeg = cast(ConstantExpr::getNeg(CI)); APInt CINegAPI(CINeg->getValue()); From baldrick at free.fr Mon Dec 1 01:50:30 2008 From: baldrick at free.fr (Duncan Sands) Date: Mon, 1 Dec 2008 08:50:30 +0100 Subject: [llvm-commits] [llvm] r60288 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/sdiv-2.ll In-Reply-To: <200811301238.mAUCcQvT026737@zion.cs.uiuc.edu> References: <200811301238.mAUCcQvT026737@zion.cs.uiuc.edu> Message-ID: <200812010850.31088.baldrick@free.fr> Hi Bill, > - if ((RHS->getSExtValue() < 0 && RHSNegAPI.slt(TwoToExp - 1)) || > - (RHS->getSExtValue() > 0 && RHSNegAPI.sgt(TwoToExp * NegOne))) { > + if ((RHS->getValue().isNegative() && RHSNegAPI.slt(TwoToExp - 1)) || > + (RHS->getValue().isNonNegative() && RHSNegAPI.sgt(TwoToExp * NegOne))) { before you were testing RHS > 0, but it looks like you are now testing RHS >= 0. > - if ((CI->getSExtValue() < 0 && CINegAPI.slt(TwoToExp - 1)) || > - (CI->getSExtValue() > 0 && CINegAPI.sgt(TwoToExp * NegOne))) > + if ((CI->getValue().isNegative() && CINegAPI.slt(TwoToExp - 1)) || > + (CI->getValue().isNonNegative() && CINegAPI.sgt(TwoToExp*NegOne))) Likewise. No idea if this matters! Ciao, Duncan. From isanbard at gmail.com Mon Dec 1 01:59:28 2008 From: isanbard at gmail.com (Bill Wendling) Date: Sun, 30 Nov 2008 23:59:28 -0800 Subject: [llvm-commits] [llvm] r60275 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/apint-sub.ll test/Transforms/InstCombine/sdiv-1.ll test/Transforms/InstCombine/sub.ll In-Reply-To: References: <200811300342.mAU3gD0i009322@zion.cs.uiuc.edu> Message-ID: <34480359-8CB1-4609-B68F-372D5233E7F0@gmail.com> On Nov 30, 2008, at 8:23 PM, Chris Lattner wrote: > On Nov 29, 2008, at 7:42 PM, Bill Wendling wrote: > >> Author: void >> Date: Sat Nov 29 21:42:12 2008 >> New Revision: 60275 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=60275&view=rev >> Log: >> Instcombine was illegally transforming -X/C into X/-C when either X >> or C >> overflowed on negation. This commit checks to make sure that neithe >> C nor X >> overflows. This requires that the RHS of X (a subtract instruction) >> be a >> constant integer. > > Hi Bill, > > I think that negate only overflows on minint, instead of: > >> + ConstantInt *RHSNeg = >> cast(ConstantExpr::getNeg(RHS)); >> + >> + // -X/C -> X/-C, if and only if negation doesn't overflow. >> + if ((RHS->getSExtValue() < 0 && >> + RHS->getSExtValue() < RHSNeg->getSExtValue()) || >> + (RHS->getSExtValue() > 0 && >> + RHS->getSExtValue() > RHSNeg->getSExtValue())) { > > How about checking: "RHSNext != RHS" ? > I've since changed this. It's now: if ((RHS->getValue().isNegative() && RHSNegAPI.slt(TwoToExp - 1)) || (RHS->getValue().isNonNegative() && RHSNegAPI.sgt(TwoToExp * NegOne))) { This is what Hacker's Delight gave me (for -1*y). I can change it to RHSNeg != RHS if you think that this will always hold in this case (the non-negative part seems to be not necessary). What do you think? > Also, please check the "if (Value *LHSNeg = dyn_castNegVal(Op0)) {" > condition before computing the negation of the RHS. This is a very > uncommon transformation, so you shouldn't be fiddling with constants > unless the pattern matches. > Done. -bw From isanbard at gmail.com Mon Dec 1 02:03:05 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 1 Dec 2008 00:03:05 -0800 Subject: [llvm-commits] [llvm] r60288 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/sdiv-2.ll In-Reply-To: <200812010850.31088.baldrick@free.fr> References: <200811301238.mAUCcQvT026737@zion.cs.uiuc.edu> <200812010850.31088.baldrick@free.fr> Message-ID: <5B93F618-6B23-4716-BE26-93AFA58EBF2A@gmail.com> On Nov 30, 2008, at 11:50 PM, Duncan Sands wrote: > Hi Bill, > >> - if ((RHS->getSExtValue() < 0 && RHSNegAPI.slt(TwoToExp - 1)) || >> - (RHS->getSExtValue() > 0 && RHSNegAPI.sgt(TwoToExp * >> NegOne))) { >> + if ((RHS->getValue().isNegative() && RHSNegAPI.slt(TwoToExp - >> 1)) || >> + (RHS->getValue().isNonNegative() && RHSNegAPI.sgt(TwoToExp >> * NegOne))) { > > before you were testing RHS > 0, but it looks like you are now > testing RHS >= 0. > >> - if ((CI->getSExtValue() < 0 && CINegAPI.slt(TwoToExp - >> 1)) || >> - (CI->getSExtValue() > 0 && CINegAPI.sgt(TwoToExp * >> NegOne))) >> + if ((CI->getValue().isNegative() && >> CINegAPI.slt(TwoToExp - 1)) || >> + (CI->getValue().isNonNegative() && >> CINegAPI.sgt(TwoToExp*NegOne))) > > Likewise. No idea if this matters! > I think that it will be okay. In the case of RHS == 0, negation of that should also be 0 (for integers). -bw From baldrick at free.fr Mon Dec 1 02:03:21 2008 From: baldrick at free.fr (Duncan Sands) Date: Mon, 1 Dec 2008 09:03:21 +0100 Subject: [llvm-commits] [llvm] r60275 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/apint-sub.ll test/Transforms/InstCombine/sdiv-1.ll test/Transforms/InstCombine/sub.ll In-Reply-To: References: <200811300342.mAU3gD0i009322@zion.cs.uiuc.edu> Message-ID: <200812010903.21449.baldrick@free.fr> Hi Bill, > I think that negate only overflows on minint, instead of: if X has any bit zero, then it can't be minint. So maybe this transform can be done for non-constants by querying some "what bits are set" mechanism. > > + // -X/C -> X/-C, if and only if negation doesn't overflow. Also, I'm a bit confused about the tests. As far as I can see, what you care about is whether X overflows, not whether C overflows, but you seem to test the later. Clearly, if (-X) overflows then the transform is wrong. Now suppose (-C) overflows. Then C is minint, so -C = minint also. Thus (-X)/C and X/(-C) are both zero (i.e. the transform is correct) unless -X or X is minint, which is the same as X = minint. In otherwords, again the transform is correct unless -X overflows. Thus checking whether -X overflows catches all cases when the transform is incorrect. Ciao, Duncan. From isanbard at gmail.com Mon Dec 1 02:09:48 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 01 Dec 2008 08:09:48 -0000 Subject: [llvm-commits] [llvm] r60341 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/or-to-xor.ll Message-ID: <200812010809.mB189ms0013149@zion.cs.uiuc.edu> Author: void Date: Mon Dec 1 02:09:47 2008 New Revision: 60341 URL: http://llvm.org/viewvc/llvm-project?rev=60341&view=rev Log: Use m_Specific() instead of double matching. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp llvm/trunk/test/Transforms/InstCombine/or-to-xor.ll Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60341&r1=60340&r2=60341&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Mon Dec 1 02:09:47 2008 @@ -4603,28 +4603,22 @@ if (Instruction *Match = MatchSelectFromAndOr(D, A, B, C)) return Match; - V1 = V2 = 0; - // ((A&~B)|(~A&B)) -> A^B - if ((match(C, m_Not(m_Value(V1))) && - match(B, m_Not(m_Value(V2))))) - if (V1 == D && V2 == A) - return BinaryOperator::CreateXor(V1, V2); + if ((match(C, m_Not(m_Specific(D))) && + match(B, m_Not(m_Specific(A))))) + return BinaryOperator::CreateXor(A, D); // ((~B&A)|(~A&B)) -> A^B - if ((match(A, m_Not(m_Value(V1))) && - match(B, m_Not(m_Value(V2))))) - if (V1 == D && V2 == C) - return BinaryOperator::CreateXor(V1, V2); + if ((match(A, m_Not(m_Specific(D))) && + match(B, m_Not(m_Specific(C))))) + return BinaryOperator::CreateXor(C, D); // ((A&~B)|(B&~A)) -> A^B - if ((match(C, m_Not(m_Value(V1))) && - match(D, m_Not(m_Value(V2))))) - if (V1 == B && V2 == A) - return BinaryOperator::CreateXor(V1, V2); + if ((match(C, m_Not(m_Specific(B))) && + match(D, m_Not(m_Specific(A))))) + return BinaryOperator::CreateXor(A, B); // ((~B&A)|(B&~A)) -> A^B - if ((match(A, m_Not(m_Value(V1))) && - match(D, m_Not(m_Value(V2))))) - if (V1 == B && V2 == C) - return BinaryOperator::CreateXor(V1, V2); + if ((match(A, m_Not(m_Specific(B))) && + match(D, m_Not(m_Specific(C))))) + return BinaryOperator::CreateXor(C, B); } // (X >> Z) | (Y >> Z) -> (X|Y) >> Z for all shifts. Modified: llvm/trunk/test/Transforms/InstCombine/or-to-xor.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/or-to-xor.ll?rev=60341&r1=60340&r2=60341&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/or-to-xor.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/or-to-xor.ll Mon Dec 1 02:09:47 2008 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {xor i32 %b, %a} | count 4 +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {xor i32 %a, %b} | count 4 ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep {and} define i32 @func1(i32 %a, i32 %b) nounwind readnone { From isanbard at gmail.com Mon Dec 1 02:10:07 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 1 Dec 2008 00:10:07 -0800 Subject: [llvm-commits] [llvm] r60291 - in /llvm/trunk: lib/Target/README.txt lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/or-to-xor.ll In-Reply-To: References: <200811301352.mAUDqoDt029527@zion.cs.uiuc.edu> Message-ID: <732B2998-6159-4C90-95D9-2A0E815FE646@gmail.com> On Nov 30, 2008, at 9:17 PM, Chris Lattner wrote: > On Nov 30, 2008, at 5:52 AM, Bill Wendling wrote: >> URL: http://llvm.org/viewvc/llvm-project?rev=60291&view=rev >> Log: >> Add instruction combining for ((A&~B)|(~A&B)) -> A^B and all >> permutations. > > Thanks Bill! > >> + V1 = V2 = 0; >> + >> + // ((A&~B)|(~A&B)) -> A^B >> + if ((match(C, m_Not(m_Value(V1))) && >> + match(B, m_Not(m_Value(V2))))) >> + if (V1 == D && V2 == A) >> + return BinaryOperator::CreateXor(V1, V2); >> + // ((~B&A)|(~A&B)) -> A^B >> + if ((match(A, m_Not(m_Value(V1))) && >> + match(B, m_Not(m_Value(V2))))) >> + if (V1 == D && V2 == C) >> + return BinaryOperator::CreateXor(V1, V2); >> + // ((A&~B)|(B&~A)) -> A^B >> + if ((match(C, m_Not(m_Value(V1))) && >> + match(D, m_Not(m_Value(V2))))) >> + if (V1 == B && V2 == A) >> + return BinaryOperator::CreateXor(V1, V2); >> + // ((~B&A)|(B&~A)) -> A^B >> + if ((match(A, m_Not(m_Value(V1))) && >> + match(D, m_Not(m_Value(V2))))) >> + if (V1 == B && V2 == C) >> + return BinaryOperator::CreateXor(V1, V2); >> } > > Please use m_Specific instead of two stage matching where possible. > Done. Good to know about this m_Specific thing. :-) -bw From baldrick at free.fr Mon Dec 1 02:11:04 2008 From: baldrick at free.fr (Duncan Sands) Date: Mon, 1 Dec 2008 09:11:04 +0100 Subject: [llvm-commits] [patch] fix bug 2843 In-Reply-To: <38a0d8450811301554q137902f0m976105ae8f3bbc78@mail.gmail.com> References: <38a0d8450811301554q137902f0m976105ae8f3bbc78@mail.gmail.com> Message-ID: <200812010911.06205.baldrick@free.fr> > This patch... Looks like you forgot to attach it ;) Ciao, Duncan. From baldrick at free.fr Mon Dec 1 02:14:21 2008 From: baldrick at free.fr (Duncan Sands) Date: Mon, 1 Dec 2008 09:14:21 +0100 Subject: [llvm-commits] [llvm] r60308 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp In-Reply-To: <200811302317.mAUNHJuJ029348@zion.cs.uiuc.edu> References: <200811302317.mAUNHJuJ029348@zion.cs.uiuc.edu> Message-ID: <200812010914.21530.baldrick@free.fr> Hi Chris, > + /// Invalid - Clients of MemDep never see this. > + Invalid = 0, > + /// Normal - This is a normal instruction dependence. The pointer member missing blank like after "Invalid = 0," > + MemDepResult getCallSiteDependency(CallSite C, BasicBlock::iterator ScanIt, > BasicBlock *BB); Bad indentation of the second line? Ciao, Duncan. From isanbard at gmail.com Mon Dec 1 02:23:26 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 01 Dec 2008 08:23:26 -0000 Subject: [llvm-commits] [llvm] r60343 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200812010823.mB18NRsh013532@zion.cs.uiuc.edu> Author: void Date: Mon Dec 1 02:23:25 2008 New Revision: 60343 URL: http://llvm.org/viewvc/llvm-project?rev=60343&view=rev Log: Reduce copy-and-paste code by splitting out the code into its own function. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60343&r1=60342&r2=60343&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Mon Dec 1 02:23:25 2008 @@ -183,6 +183,8 @@ Instruction *FoldAndOfICmps(Instruction &I, ICmpInst *LHS, ICmpInst *RHS); Instruction *visitAnd(BinaryOperator &I); Instruction *FoldOrOfICmps(Instruction &I, ICmpInst *LHS, ICmpInst *RHS); + Instruction *FoldOrWithConstants(BinaryOperator &I, + Value *A, Value *B, Value *C); Instruction *visitOr (BinaryOperator &I); Instruction *visitXor(BinaryOperator &I); Instruction *visitShl(BinaryOperator &I); @@ -4445,6 +4447,50 @@ return 0; } +/// FoldOrWithConstants - This helper function folds: +/// +/// ((A|B)&1)|(B&-2) +/// +/// into: +/// +/// (A&1) | B +Instruction *InstCombiner::FoldOrWithConstants(BinaryOperator &I, + Value *A, Value *B, Value *C) { + Value *Op1 = I.getOperand(1); + + if (ConstantInt *CI = dyn_cast(C)) { + if (CI->getValue() == 1) { + Value *V1 = 0, *C2 = 0; + if (match(Op1, m_And(m_Value(V1), m_Value(C2)))) { + ConstantInt *CI2 = dyn_cast(C2); + + if (!CI2) { + std::swap(V1, C2); + CI2 = dyn_cast(C2); + } + + if (CI2) { + APInt NegTwo = -APInt(CI2->getValue().getBitWidth(), 2, true); + if (CI2->getValue().eq(NegTwo)) { + if (V1 == B) { + Instruction *NewOp = + InsertNewInstBefore(BinaryOperator::CreateAnd(A, CI), I); + return BinaryOperator::CreateOr(NewOp, B); + } + if (V1 == A) { + Instruction *NewOp = + InsertNewInstBefore(BinaryOperator::CreateAnd(B, CI), I); + return BinaryOperator::CreateOr(NewOp, A); + } + } + } + } + } + } + + return 0; +} + Instruction *InstCombiner::visitOr(BinaryOperator &I) { bool Changed = SimplifyCommutative(I); Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); @@ -4639,68 +4685,14 @@ // ((A|B)&1)|(B&-2) -> (A&1) | B if (match(Op0, m_And(m_Or(m_Value(A), m_Value(B)), m_Value(C))) || match(Op0, m_And(m_Value(C), m_Or(m_Value(A), m_Value(B))))) { - if (ConstantInt *CI = dyn_cast(C)) { - if (CI->getValue() == 1) { - Value *V1 = 0, *C2 = 0; - if (match(Op1, m_And(m_Value(V1), m_Value(C2)))) { - ConstantInt *CI2 = dyn_cast(C2); - - if (!CI2) { - std::swap(V1, C2); - CI2 = dyn_cast(C2); - } - - if (CI2) { - APInt NegTwo = -APInt(CI2->getValue().getBitWidth(), 2, true); - if (CI2->getValue().eq(NegTwo)) { - if (V1 == B) { - Instruction *NewOp = - InsertNewInstBefore(BinaryOperator::CreateAnd(A, CI), I); - return BinaryOperator::CreateOr(NewOp, B); - } - if (V1 == A) { - Instruction *NewOp = - InsertNewInstBefore(BinaryOperator::CreateAnd(B, CI), I); - return BinaryOperator::CreateOr(NewOp, A); - } - } - } - } - } - } + Instruction *Ret = FoldOrWithConstants(I, A, B, C); + if (Ret) return Ret; } // (B&-2)|((A|B)&1) -> (A&1) | B if (match(Op1, m_And(m_Or(m_Value(A), m_Value(B)), m_Value(C))) || match(Op1, m_And(m_Value(C), m_Or(m_Value(A), m_Value(B))))) { - if (ConstantInt *CI = dyn_cast(C)) { - if (CI->getValue() == 1) { - Value *V1 = 0, *C2 = 0; - if (match(Op0, m_And(m_Value(V1), m_Value(C2)))) { - ConstantInt *CI2 = dyn_cast(C2); - - if (!CI2) { - std::swap(V1, C2); - CI2 = dyn_cast(C2); - } - - if (CI2) { - APInt NegTwo = -APInt(CI2->getValue().getBitWidth(), 2, true); - if (CI2->getValue().eq(NegTwo)) { - if (V1 == B) { - Instruction *NewOp = - InsertNewInstBefore(BinaryOperator::CreateAnd(A, CI), I); - return BinaryOperator::CreateOr(NewOp, B); - } - if (V1 == A) { - Instruction *NewOp = - InsertNewInstBefore(BinaryOperator::CreateAnd(B, CI), I); - return BinaryOperator::CreateOr(NewOp, A); - } - } - } - } - } - } + Instruction *Ret = FoldOrWithConstants(I, A, B, C); + if (Ret) return Ret; } if (match(Op0, m_Not(m_Value(A)))) { // ~A | Op1 From isanbard at gmail.com Mon Dec 1 02:32:43 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 01 Dec 2008 08:32:43 -0000 Subject: [llvm-commits] [llvm] r60344 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200812010832.mB18WiJ8013930@zion.cs.uiuc.edu> Author: void Date: Mon Dec 1 02:32:40 2008 New Revision: 60344 URL: http://llvm.org/viewvc/llvm-project?rev=60344&view=rev Log: Generalize the FoldOrWithConstant method to fold for any two constants which don't have overlapping bits. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60344&r1=60343&r2=60344&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Mon Dec 1 02:32:40 2008 @@ -183,7 +183,7 @@ Instruction *FoldAndOfICmps(Instruction &I, ICmpInst *LHS, ICmpInst *RHS); Instruction *visitAnd(BinaryOperator &I); Instruction *FoldOrOfICmps(Instruction &I, ICmpInst *LHS, ICmpInst *RHS); - Instruction *FoldOrWithConstants(BinaryOperator &I, + Instruction *FoldOrWithConstants(BinaryOperator &I, Value *Op, Value *A, Value *B, Value *C); Instruction *visitOr (BinaryOperator &I); Instruction *visitXor(BinaryOperator &I); @@ -4449,40 +4449,39 @@ /// FoldOrWithConstants - This helper function folds: /// -/// ((A|B)&1)|(B&-2) +/// ((A | B) & 1) | (B & -2) /// /// into: /// -/// (A&1) | B -Instruction *InstCombiner::FoldOrWithConstants(BinaryOperator &I, +/// (A & 1) | B +/// +/// The constants aren't important. Only that they don't overlap. (I.e., the XOR +/// of the two constants is "all ones".) +Instruction *InstCombiner::FoldOrWithConstants(BinaryOperator &I, Value *Op, Value *A, Value *B, Value *C) { - Value *Op1 = I.getOperand(1); + if (ConstantInt *CI1 = dyn_cast(C)) { + Value *V1 = 0, *C2 = 0; + if (match(Op, m_And(m_Value(V1), m_Value(C2)))) { + ConstantInt *CI2 = dyn_cast(C2); + + if (!CI2) { + std::swap(V1, C2); + CI2 = dyn_cast(C2); + } - if (ConstantInt *CI = dyn_cast(C)) { - if (CI->getValue() == 1) { - Value *V1 = 0, *C2 = 0; - if (match(Op1, m_And(m_Value(V1), m_Value(C2)))) { - ConstantInt *CI2 = dyn_cast(C2); - - if (!CI2) { - std::swap(V1, C2); - CI2 = dyn_cast(C2); - } - - if (CI2) { - APInt NegTwo = -APInt(CI2->getValue().getBitWidth(), 2, true); - if (CI2->getValue().eq(NegTwo)) { + if (CI2) { + APInt Xor = CI1->getValue() ^ CI2->getValue(); + if (Xor.isAllOnesValue()) { if (V1 == B) { Instruction *NewOp = - InsertNewInstBefore(BinaryOperator::CreateAnd(A, CI), I); + InsertNewInstBefore(BinaryOperator::CreateAnd(A, CI1), I); return BinaryOperator::CreateOr(NewOp, B); } if (V1 == A) { Instruction *NewOp = - InsertNewInstBefore(BinaryOperator::CreateAnd(B, CI), I); + InsertNewInstBefore(BinaryOperator::CreateAnd(B, CI1), I); return BinaryOperator::CreateOr(NewOp, A); } - } } } } @@ -4685,13 +4684,13 @@ // ((A|B)&1)|(B&-2) -> (A&1) | B if (match(Op0, m_And(m_Or(m_Value(A), m_Value(B)), m_Value(C))) || match(Op0, m_And(m_Value(C), m_Or(m_Value(A), m_Value(B))))) { - Instruction *Ret = FoldOrWithConstants(I, A, B, C); + Instruction *Ret = FoldOrWithConstants(I, Op1, A, B, C); if (Ret) return Ret; } // (B&-2)|((A|B)&1) -> (A&1) | B if (match(Op1, m_And(m_Or(m_Value(A), m_Value(B)), m_Value(C))) || match(Op1, m_And(m_Value(C), m_Or(m_Value(A), m_Value(B))))) { - Instruction *Ret = FoldOrWithConstants(I, A, B, C); + Instruction *Ret = FoldOrWithConstants(I, Op0, A, B, C); if (Ret) return Ret; } From isanbard at gmail.com Mon Dec 1 02:40:02 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 1 Dec 2008 00:40:02 -0800 Subject: [llvm-commits] [llvm] r60275 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/apint-sub.ll test/Transforms/InstCombine/sdiv-1.ll test/Transforms/InstCombine/sub.ll In-Reply-To: <200812010903.21449.baldrick@free.fr> References: <200811300342.mAU3gD0i009322@zion.cs.uiuc.edu> <200812010903.21449.baldrick@free.fr> Message-ID: <7F3DE1E6-A346-4CBE-8554-F722BAECA492@gmail.com> On Dec 1, 2008, at 12:03 AM, Duncan Sands wrote: > Hi Bill, > >> I think that negate only overflows on minint, instead of: > > if X has any bit zero, then it can't be minint. So maybe > this transform can be done for non-constants by querying some > "what bits are set" mechanism. > I'm not sure how that would work. >>> + // -X/C -> X/-C, if and only if negation doesn't overflow. > > Also, I'm a bit confused about the tests. As far as I can see, > what you care about is whether X overflows, not whether C overflows, > but you seem to test the later. Clearly, if (-X) overflows then > the transform is wrong. Now suppose (-C) overflows. Then C is > minint, so -C = minint also. Thus (-X)/C and X/(-C) are both > zero (i.e. the transform is correct) unless -X or X is minint, > which is the same as X = minint. In otherwords, again the transform > is correct unless -X overflows. Thus checking whether -X overflows > catches all cases when the transform is incorrect. > Actually, I test whether either -X or -C overflows. Testing whether -C overflows might be overkill because we use APInt and friends. I was dubious about this whole transform in the PR. The changes I did here really only serve to stop us from doing this transformation when X is non-constant. -bw From espindola at google.com Mon Dec 1 03:26:55 2008 From: espindola at google.com (Rafael Espindola) Date: Mon, 1 Dec 2008 09:26:55 +0000 Subject: [llvm-commits] [patch] fix bug 2843 In-Reply-To: <200812010911.06205.baldrick@free.fr> References: <38a0d8450811301554q137902f0m976105ae8f3bbc78@mail.gmail.com> <200812010911.06205.baldrick@free.fr> Message-ID: <38a0d8450812010126h35886666tf96e69250d117675@mail.gmail.com> 2008/12/1 Duncan Sands : >> This patch... > > Looks like you forgot to attach it ;) Oops :-) > Ciao, > > Duncan. > Cheers, -- Rafael Avila de Espindola Google | Gordon House | Barrow Street | Dublin 4 | Ireland Registered in Dublin, Ireland | Registration Number: 368047 -------------- next part -------------- A non-text attachment was scrubbed... Name: 2843.patch Type: text/x-diff Size: 2519 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081201/3463f34e/attachment.bin From baldrick at free.fr Mon Dec 1 05:39:31 2008 From: baldrick at free.fr (Duncan Sands) Date: Mon, 01 Dec 2008 11:39:31 -0000 Subject: [llvm-commits] [llvm] r60348 - in /llvm/trunk: include/llvm/Target/ lib/CodeGen/SelectionDAG/ lib/Target/ARM/ lib/Target/Alpha/ lib/Target/CellSPU/ lib/Target/PIC16/ lib/Target/PowerPC/ lib/Target/X86/ lib/Target/XCore/ Message-ID: <200812011139.mB1BdYej029828@zion.cs.uiuc.edu> Author: baldrick Date: Mon Dec 1 05:39:25 2008 New Revision: 60348 URL: http://llvm.org/viewvc/llvm-project?rev=60348&view=rev Log: Change the interface to the type legalization method ReplaceNodeResults: rather than returning a node which must have the same number of results as the original node (which means mucking around with MERGE_VALUES, and which is also easy to get wrong since SelectionDAG folding may mean you don't get the node you expect), return the results in a vector. Modified: llvm/trunk/include/llvm/Target/TargetLowering.h llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.h llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp llvm/trunk/lib/Target/Alpha/AlphaISelLowering.h llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.h llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp llvm/trunk/lib/Target/XCore/XCoreISelLowering.h Modified: llvm/trunk/include/llvm/Target/TargetLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=60348&r1=60347&r2=60348&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) +++ llvm/trunk/include/llvm/Target/TargetLowering.h Mon Dec 1 05:39:25 2008 @@ -1130,17 +1130,18 @@ /// implement this. The default implementation of this aborts. virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG); - /// ReplaceNodeResults - This callback is invoked for operations that are - /// unsupported by the target, which are registered to use 'custom' lowering, - /// and whose result type is illegal. This must return a node whose results - /// precisely match the results of the input node. This typically involves a - /// MERGE_VALUES node and/or BUILD_PAIR. + /// ReplaceNodeResults - This callback is invoked when a node result type is + /// illegal for the target, and the operation was registered to use 'custom' + /// lowering for that result type. The target places new result values for + /// the node in Results (their number and types must exactly match those of + /// the original return values of the node), or leaves Results empty, which + /// indicates that the node is not to be custom lowered after all. /// /// If the target has no operations that require custom lowering, it need not /// implement this. The default implementation aborts. - virtual SDNode *ReplaceNodeResults(SDNode *N, SelectionDAG &DAG) { + virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl &Results, + SelectionDAG &DAG) { assert(0 && "ReplaceNodeResults not implemented for this target!"); - return 0; } /// IsEligibleForTailCallOptimization - Check whether the call is eligible for Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=60348&r1=60347&r2=60348&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon Dec 1 05:39:25 2008 @@ -6083,8 +6083,10 @@ // the target lowering hooks to expand it. Just keep the low part of the // expanded operation, we know that we're truncating anyway. if (getTypeAction(NewOutTy) == Expand) { - Operation = SDValue(TLI.ReplaceNodeResults(Operation.getNode(), DAG), 0); - assert(Operation.getNode() && "Didn't return anything"); + SmallVector Results; + TLI.ReplaceNodeResults(Operation.getNode(), Results, DAG); + assert(Results.size() == 1 && "Incorrect FP_TO_XINT lowering!"); + Operation = Results[0]; } // Truncate the result of the extended FP_TO_*INT operation to the desired Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp?rev=60348&r1=60347&r2=60348&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp Mon Dec 1 05:39:25 2008 @@ -727,16 +727,8 @@ Lo = Hi = SDValue(); // See if the target wants to custom expand this node. - if (TLI.getOperationAction(N->getOpcode(), N->getValueType(ResNo)) == - TargetLowering::Custom) { - // If the target wants to, allow it to lower this itself. - if (SDNode *P = TLI.ReplaceNodeResults(N, DAG)) { - // Everything that once used N now uses P. We are guaranteed that the - // result value types of N and the result value types of P match. - ReplaceNodeWith(N, P); - return; - } - } + if (CustomLowerResults(N, ResNo)) + return; switch (N->getOpcode()) { default: Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp?rev=60348&r1=60347&r2=60348&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp Mon Dec 1 05:39:25 2008 @@ -34,16 +34,8 @@ SDValue Result = SDValue(); // See if the target wants to custom expand this node. - if (TLI.getOperationAction(N->getOpcode(), N->getValueType(ResNo)) == - TargetLowering::Custom) { - // If the target wants to, allow it to lower this itself. - if (SDNode *P = TLI.ReplaceNodeResults(N, DAG)) { - // Everything that once used N now uses P. We are guaranteed that the - // result value types of N and the result value types of P match. - ReplaceNodeWith(N, P); - return; - } - } + if (CustomLowerResults(N, ResNo)) + return; switch (N->getOpcode()) { default: @@ -949,16 +941,8 @@ Lo = Hi = SDValue(); // See if the target wants to custom expand this node. - if (TLI.getOperationAction(N->getOpcode(), N->getValueType(ResNo)) == - TargetLowering::Custom) { - // If the target wants to, allow it to lower this itself. - if (SDNode *P = TLI.ReplaceNodeResults(N, DAG)) { - // Everything that once used N now uses P. We are guaranteed that the - // result value types of N and the result value types of P match. - ReplaceNodeWith(N, P); - return; - } - } + if (CustomLowerResults(N, ResNo)) + return; switch (N->getOpcode()) { default: Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp?rev=60348&r1=60347&r2=60348&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp Mon Dec 1 05:39:25 2008 @@ -376,45 +376,6 @@ ReplacedValues[From] = To; } -/// ReplaceNodeWith - Replace uses of the 'from' node's results with the 'to' -/// node's results. The from and to node must define identical result types. -void DAGTypeLegalizer::ReplaceNodeWith(SDNode *From, SDNode *To) { - if (From == To) return; - - // If expansion produced new nodes, make sure they are properly marked. - ExpungeNode(From); - - To = AnalyzeNewNode(To); // Expunges To. - // If To morphed into an already processed node, its values may need - // remapping. This is done below. - - assert(From->getNumValues() == To->getNumValues() && - "Node results don't match"); - - // Anything that used the old node should now use the new one. Note that this - // can potentially cause recursive merging. - NodeUpdateListener NUL(*this); - for (unsigned i = 0, e = From->getNumValues(); i != e; ++i) { - SDValue FromVal(From, i); - SDValue ToVal(To, i); - - // AnalyzeNewNode may have morphed a new node into a processed node. Remap - // values now. - if (To->getNodeId() == Processed) - RemapValue(ToVal); - - assert(FromVal.getValueType() == ToVal.getValueType() && - "Node results don't match!"); - - // Make anything that used the old value use the new value. - DAG.ReplaceAllUsesOfValueWith(FromVal, ToVal, &NUL); - - // The old node may still be present in a map like ExpandedIntegers or - // PromotedIntegers. Inform maps about the replacement. - ReplacedValues[FromVal] = ToVal; - } -} - /// RemapValue - If the specified value was already legalized to another value, /// replace it by that value. void DAGTypeLegalizer::RemapValue(SDValue &N) { @@ -621,6 +582,28 @@ return DAG.getLoad(DestVT, Store, FIPtr, NULL, 0); } +/// CustomLowerResults - Replace the node's results with custom code provided +/// by the target and return "true", or do nothing and return "false". +bool DAGTypeLegalizer::CustomLowerResults(SDNode *N, unsigned ResNo) { + // See if the target wants to custom lower this node. + if (TLI.getOperationAction(N->getOpcode(), N->getValueType(ResNo)) != + TargetLowering::Custom) + return false; + + SmallVector Results; + TLI.ReplaceNodeResults(N, Results, DAG); + if (Results.empty()) + // The target didn't want to custom lower it after all. + return false; + + // Make everything that once used N's values now use those in Results instead. + assert(Results.size() == N->getNumValues() && + "Custom lowering returned the wrong number of results!"); + for (unsigned i = 0, e = Results.size(); i != e; ++i) + ReplaceValueWith(SDValue(N, i), Results[i]); + return true; +} + /// JoinIntegers - Build an integer with low bits Lo and high bits Hi. SDValue DAGTypeLegalizer::JoinIntegers(SDValue Lo, SDValue Hi) { MVT LVT = Lo.getValueType(); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=60348&r1=60347&r2=60348&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Mon Dec 1 05:39:25 2008 @@ -185,12 +185,13 @@ void AnalyzeNewValue(SDValue &Val); void ReplaceValueWith(SDValue From, SDValue To); - void ReplaceNodeWith(SDNode *From, SDNode *To); void RemapValue(SDValue &N); void ExpungeNode(SDNode *N); // Common routines. + bool CustomLowerResults(SDNode *N, unsigned ResNo); + SDValue CreateStackStoreLoad(SDValue Op, MVT DestVT); SDValue MakeLibCall(RTLIB::Libcall LC, MVT RetVT, const SDValue *Ops, unsigned NumOps, bool isSigned); Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=60348&r1=60347&r2=60348&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Mon Dec 1 05:39:25 2008 @@ -1344,7 +1344,7 @@ return DAG.getNode(ISD::TokenFactor, MVT::Other, &TFOps[0], i); } -static SDNode *ExpandBIT_CONVERT(SDNode *N, SelectionDAG &DAG) { +static SDValue ExpandBIT_CONVERT(SDNode *N, SelectionDAG &DAG) { SDValue Op = N->getOperand(0); if (N->getValueType(0) == MVT::f64) { // Turn i64->f64 into FMDRR. @@ -1352,7 +1352,7 @@ DAG.getConstant(0, MVT::i32)); SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op, DAG.getConstant(1, MVT::i32)); - return DAG.getNode(ARMISD::FMDRR, MVT::f64, Lo, Hi).getNode(); + return DAG.getNode(ARMISD::FMDRR, MVT::f64, Lo, Hi); } // Turn f64->i64 into FMRRD. @@ -1360,21 +1360,21 @@ &Op, 1); // Merge the pieces into a single i64 value. - return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Cvt, Cvt.getValue(1)).getNode(); + return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Cvt, Cvt.getValue(1)); } -static SDNode *ExpandSRx(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *ST) { +static SDValue ExpandSRx(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *ST) { assert(N->getValueType(0) == MVT::i64 && (N->getOpcode() == ISD::SRL || N->getOpcode() == ISD::SRA) && "Unknown shift to lower!"); - + // We only lower SRA, SRL of 1 here, all others use generic lowering. if (!isa(N->getOperand(1)) || cast(N->getOperand(1))->getZExtValue() != 1) - return 0; + return SDValue(); // If we are in thumb mode, we don't have RRX. - if (ST->isThumb()) return 0; + if (ST->isThumb()) return SDValue(); // Okay, we have a 64-bit SRA or SRL of 1. Lower this to an RRX expr. SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, N->getOperand(0), @@ -1391,7 +1391,7 @@ Lo = DAG.getNode(ARMISD::RRX, MVT::i32, Lo, Hi.getValue(1)); // Merge the pieces into a single i64 value. - return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi).getNode(); + return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi); } @@ -1419,22 +1419,34 @@ case ISD::FRAMEADDR: break; case ISD::GLOBAL_OFFSET_TABLE: return LowerGLOBAL_OFFSET_TABLE(Op, DAG); case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG); - case ISD::BIT_CONVERT: return SDValue(ExpandBIT_CONVERT(Op.getNode(), DAG), 0); + case ISD::BIT_CONVERT: return ExpandBIT_CONVERT(Op.getNode(), DAG); case ISD::SRL: - case ISD::SRA: return SDValue(ExpandSRx(Op.getNode(), DAG,Subtarget),0); + case ISD::SRA: return ExpandSRx(Op.getNode(), DAG,Subtarget); } return SDValue(); } -/// ReplaceNodeResults - Provide custom lowering hooks for nodes with illegal -/// result types. -SDNode *ARMTargetLowering::ReplaceNodeResults(SDNode *N, SelectionDAG &DAG) { +/// ReplaceNodeResults - Replace the results of node with an illegal result +/// type with new values built out of custom code. +/// +void ARMTargetLowering::ReplaceNodeResults(SDNode *N, + SmallVectorImpl&Results, + SelectionDAG &DAG) { switch (N->getOpcode()) { - default: assert(0 && "Don't know how to custom expand this!"); abort(); - case ISD::BIT_CONVERT: return ExpandBIT_CONVERT(N, DAG); + default: + assert(0 && "Don't know how to custom expand this!"); + return; + case ISD::BIT_CONVERT: + Results.push_back(ExpandBIT_CONVERT(N, DAG)); + return; case ISD::SRL: - case ISD::SRA: return ExpandSRx(N, DAG, Subtarget); + case ISD::SRA: { + SDValue Res = ExpandSRx(N, DAG, Subtarget); + if (Res.getNode()) + Results.push_back(Res); + return; + } } } Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=60348&r1=60347&r2=60348&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Mon Dec 1 05:39:25 2008 @@ -76,8 +76,13 @@ explicit ARMTargetLowering(TargetMachine &TM); virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG); - virtual SDNode *ReplaceNodeResults(SDNode *N, SelectionDAG &DAG); - + + /// ReplaceNodeResults - Replace the results of node with an illegal result + /// type with new values built out of custom code. + /// + virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl&Results, + SelectionDAG &DAG); + virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; virtual const char *getTargetNodeName(unsigned Opcode) const; Modified: llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp?rev=60348&r1=60347&r2=60348&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp Mon Dec 1 05:39:25 2008 @@ -612,15 +612,18 @@ return SDValue(); } -SDNode *AlphaTargetLowering::ReplaceNodeResults(SDNode *N, - SelectionDAG &DAG) { +void AlphaTargetLowering::ReplaceNodeResults(SDNode *N, + SmallVectorImpl&Results, + SelectionDAG &DAG) { assert(N->getValueType(0) == MVT::i32 && N->getOpcode() == ISD::VAARG && "Unknown node to custom promote!"); SDValue Chain, DataPtr; LowerVAARG(N, Chain, DataPtr, DAG); - return DAG.getLoad(N->getValueType(0), Chain, DataPtr, NULL, 0).getNode(); + SDValue Res = DAG.getLoad(N->getValueType(0), Chain, DataPtr, NULL, 0); + Results.push_back(Res); + Results.push_back(SDValue(Res.getNode(), 1)); } Modified: llvm/trunk/lib/Target/Alpha/AlphaISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaISelLowering.h?rev=60348&r1=60347&r2=60348&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/AlphaISelLowering.h (original) +++ llvm/trunk/lib/Target/Alpha/AlphaISelLowering.h Mon Dec 1 05:39:25 2008 @@ -72,7 +72,12 @@ /// LowerOperation - Provide custom lowering hooks for some operations. /// virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG); - virtual SDNode *ReplaceNodeResults(SDNode *N, SelectionDAG &DAG); + + /// ReplaceNodeResults - Replace the results of node with an illegal result + /// type with new values built out of custom code. + /// + virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl&Results, + SelectionDAG &DAG); // Friendly names for dumps const char *getTargetNodeName(unsigned Opcode) const; Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=60348&r1=60347&r2=60348&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Mon Dec 1 05:39:25 2008 @@ -2866,7 +2866,9 @@ return SDValue(); } -SDNode *SPUTargetLowering::ReplaceNodeResults(SDNode *N, SelectionDAG &DAG) +void SPUTargetLowering::ReplaceNodeResults(SDNode *N, + SmallVectorImpl&Results, + SelectionDAG &DAG) { #if 0 unsigned Opc = (unsigned) N->getOpcode(); @@ -2885,7 +2887,6 @@ #endif /* Otherwise, return unchanged */ - return 0; } //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h?rev=60348&r1=60347&r2=60348&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h Mon Dec 1 05:39:25 2008 @@ -113,9 +113,10 @@ //! Custom lowering hooks virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG); - //! Provide custom lowering hooks for nodes with illegal result types. - SDNode *ReplaceNodeResults(SDNode *N, SelectionDAG &DAG); - + //! Custom lowering hook for nodes with illegal result types. + virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl&Results, + SelectionDAG &DAG); + virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; virtual void computeMaskedBitsForTargetNode(const SDValue Op, Modified: llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp?rev=60348&r1=60347&r2=60348&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp Mon Dec 1 05:39:25 2008 @@ -90,24 +90,35 @@ } } -SDNode *PIC16TargetLowering::ReplaceNodeResults(SDNode *N, SelectionDAG &DAG) { +void PIC16TargetLowering::ReplaceNodeResults(SDNode *N, + SmallVectorImpl&Results, + SelectionDAG &DAG) { switch (N->getOpcode()) { case ISD::GlobalAddress: - return ExpandGlobalAddress(N, DAG); + Results.push_back(ExpandGlobalAddress(N, DAG)); + return; case ISD::STORE: - return ExpandStore(N, DAG); + Results.push_back(ExpandStore(N, DAG)); + return; case ISD::LOAD: - return ExpandLoad(N, DAG); + Results.push_back(ExpandLoad(N, DAG)); + return; case ISD::ADD: - return ExpandAdd(N, DAG); - case ISD::SHL: - return ExpandShift(N, DAG); +// return ExpandAdd(N, DAG); + return; + case ISD::SHL: { + SDValue Res = ExpandShift(N, DAG); + if (Res.getNode()) + Results.push_back(Res); + return; + } default: assert (0 && "not implemented"); + return; } } -SDNode *PIC16TargetLowering::ExpandStore(SDNode *N, SelectionDAG &DAG) { +SDValue PIC16TargetLowering::ExpandStore(SDNode *N, SelectionDAG &DAG) { StoreSDNode *St = cast(N); SDValue Chain = St->getChain(); SDValue Src = St->getValue(); @@ -119,9 +130,8 @@ LegalizeAddress(Ptr, DAG, PtrLo, PtrHi, StoreOffset); if (ValueType == MVT::i8) { - SDValue Store = DAG.getNode (PIC16ISD::PIC16Store, MVT::Other, Chain, Src, - PtrLo, PtrHi, DAG.getConstant (0, MVT::i8)); - return Store.getNode(); + return DAG.getNode (PIC16ISD::PIC16Store, MVT::Other, Chain, Src, + PtrLo, PtrHi, DAG.getConstant (0, MVT::i8)); } else if (ValueType == MVT::i16) { // Get the Lo and Hi parts from MERGE_VALUE or BUILD_PAIR. @@ -142,7 +152,7 @@ DAG.getConstant (1 + StoreOffset, MVT::i8)); return DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store1), - getChain(Store2)).getNode(); + getChain(Store2)); } else if (ValueType == MVT::i32) { // Get the Lo and Hi parts from MERGE_VALUE or BUILD_PAIR. @@ -190,16 +200,16 @@ getChain(Store2)); SDValue RetHi = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store3), getChain(Store4)); - return DAG.getNode(ISD::TokenFactor, MVT::Other, RetLo, RetHi).getNode(); - + return DAG.getNode(ISD::TokenFactor, MVT::Other, RetLo, RetHi); } else { assert (0 && "value type not supported"); + return SDValue(); } } // ExpandGlobalAddress - -SDNode *PIC16TargetLowering::ExpandGlobalAddress(SDNode *N, SelectionDAG &DAG) { +SDValue PIC16TargetLowering::ExpandGlobalAddress(SDNode *N, SelectionDAG &DAG) { GlobalAddressSDNode *G = dyn_cast(SDValue(N, 0)); SDValue TGA = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i8, @@ -209,7 +219,7 @@ SDValue Hi = DAG.getNode(PIC16ISD::Hi, MVT::i8, TGA); SDValue BP = DAG.getNode(ISD::BUILD_PAIR, MVT::i16, Lo, Hi); - return BP.getNode(); + return BP; } bool PIC16TargetLowering::isDirectAddress(const SDValue &Op) { @@ -351,20 +361,20 @@ return; } -SDNode *PIC16TargetLowering::ExpandAdd(SDNode *N, SelectionDAG &DAG) { - SDValue OperLeft = N->getOperand(0); - SDValue OperRight = N->getOperand(1); - - if((OperLeft.getOpcode() == ISD::Constant) || - (OperRight.getOpcode() == ISD::Constant)) { - return NULL; - } +//SDNode *PIC16TargetLowering::ExpandAdd(SDNode *N, SelectionDAG &DAG) { +// SDValue OperLeft = N->getOperand(0); +// SDValue OperRight = N->getOperand(1); +// +// if((OperLeft.getOpcode() == ISD::Constant) || +// (OperRight.getOpcode() == ISD::Constant)) { +// return NULL; +// } +// +// // These case are yet to be handled +// return NULL; +//} - // These case are yet to be handled - return NULL; -} - -SDNode *PIC16TargetLowering::ExpandLoad(SDNode *N, SelectionDAG &DAG) { +SDValue PIC16TargetLowering::ExpandLoad(SDNode *N, SelectionDAG &DAG) { LoadSDNode *LD = dyn_cast(SDValue(N, 0)); SDValue Chain = LD->getChain(); SDValue Ptr = LD->getBasePtr(); @@ -438,7 +448,7 @@ if (VT == MVT::i8) { // Operand of Load is illegal -- Load itself is legal - return PICLoads[0].getNode(); + return PICLoads[0]; } else if (VT == MVT::i16) { BP = DAG.getNode(ISD::BUILD_PAIR, VT, PICLoads[0], PICLoads[1]); @@ -467,12 +477,10 @@ } } Tys = DAG.getVTList(VT, MVT::Other); - SDValue MergeV = DAG.getNode(ISD::MERGE_VALUES, Tys, BP, Chain); - return MergeV.getNode(); - + return DAG.getNode(ISD::MERGE_VALUES, Tys, BP, Chain); } -SDNode *PIC16TargetLowering::ExpandShift(SDNode *N, SelectionDAG &DAG) { +SDValue PIC16TargetLowering::ExpandShift(SDNode *N, SelectionDAG &DAG) { SDValue Value = N->getOperand(0); SDValue Amt = N->getOperand(1); SDValue BCF, BCFInput; @@ -483,11 +491,11 @@ // Currently handling Constant shift only if (Amt.getOpcode() != ISD::Constant) - return NULL; + return SDValue(); // Following code considers 16 bit left-shift only if (N->getValueType(0) != MVT::i16) - return NULL; + return SDValue(); if (N->getOpcode() == ISD::SHL) { ShfNode = PIC16ISD::LSLF; @@ -515,8 +523,7 @@ BCFInput = RotCom.getValue(1); } - SDValue BP = DAG.getNode(ISD::BUILD_PAIR, N->getValueType(0), ShfCom, RotCom); - return BP.getNode(); + return DAG.getNode(ISD::BUILD_PAIR, N->getValueType(0), ShfCom, RotCom); } SDValue PIC16TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { @@ -532,11 +539,11 @@ case ISD::SUBC: return LowerSUBC(Op, DAG); case ISD::LOAD: - return SDValue(ExpandLoad(Op.getNode(), DAG), Op.getResNo()); + return ExpandLoad(Op.getNode(), DAG); case ISD::STORE: - return SDValue(ExpandStore(Op.getNode(), DAG), Op.getResNo()); + return ExpandStore(Op.getNode(), DAG); case ISD::SHL: - return SDValue(ExpandShift(Op.getNode(), DAG), Op.getResNo()); + return ExpandShift(Op.getNode(), DAG); case ISD::OR: case ISD::AND: case ISD::XOR: Modified: llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h?rev=60348&r1=60347&r2=60348&view=diff ============================================================================== --- llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h (original) +++ llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h Mon Dec 1 05:39:25 2008 @@ -66,12 +66,17 @@ SDValue LowerSUBC(SDValue Op, SelectionDAG &DAG); SDValue LowerBinOp(SDValue Op, SelectionDAG &DAG); - SDNode *ReplaceNodeResults(SDNode *N, SelectionDAG &DAG); - SDNode *ExpandStore(SDNode *N, SelectionDAG &DAG); - SDNode *ExpandLoad(SDNode *N, SelectionDAG &DAG); - SDNode *ExpandAdd(SDNode *N, SelectionDAG &DAG); - SDNode *ExpandGlobalAddress(SDNode *N, SelectionDAG &DAG); - SDNode *ExpandShift(SDNode *N, SelectionDAG &DAG); + /// ReplaceNodeResults - Replace the results of node with an illegal result + /// type with new values built out of custom code. + /// + virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl&Results, + SelectionDAG &DAG); + + SDValue ExpandStore(SDNode *N, SelectionDAG &DAG); + SDValue ExpandLoad(SDNode *N, SelectionDAG &DAG); +// SDNode *ExpandAdd(SDNode *N, SelectionDAG &DAG); + SDValue ExpandGlobalAddress(SDNode *N, SelectionDAG &DAG); + SDValue ExpandShift(SDNode *N, SelectionDAG &DAG); SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; SDValue PerformPIC16LoadCombine(SDNode *N, DAGCombinerInfo &DCI) const; Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=60348&r1=60347&r2=60348&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Mon Dec 1 05:39:25 2008 @@ -2874,66 +2874,6 @@ return DAG.getLoad(Op.getValueType(), Chain, FIPtr, NULL, 0); } -SDValue PPCTargetLowering::LowerFP_ROUND_INREG(SDValue Op, - SelectionDAG &DAG) { - assert(Op.getValueType() == MVT::ppcf128); - SDNode *Node = Op.getNode(); - assert(Node->getOperand(0).getValueType() == MVT::ppcf128); - SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::f64, Node->getOperand(0), - DAG.getIntPtrConstant(0)); - SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::f64, Node->getOperand(0), - DAG.getIntPtrConstant(1)); - - // This sequence changes FPSCR to do round-to-zero, adds the two halves - // of the long double, and puts FPSCR back the way it was. We do not - // actually model FPSCR. - std::vector NodeTys; - SDValue Ops[4], Result, MFFSreg, InFlag, FPreg; - - NodeTys.push_back(MVT::f64); // Return register - NodeTys.push_back(MVT::Flag); // Returns a flag for later insns - Result = DAG.getNode(PPCISD::MFFS, NodeTys, &InFlag, 0); - MFFSreg = Result.getValue(0); - InFlag = Result.getValue(1); - - NodeTys.clear(); - NodeTys.push_back(MVT::Flag); // Returns a flag - Ops[0] = DAG.getConstant(31, MVT::i32); - Ops[1] = InFlag; - Result = DAG.getNode(PPCISD::MTFSB1, NodeTys, Ops, 2); - InFlag = Result.getValue(0); - - NodeTys.clear(); - NodeTys.push_back(MVT::Flag); // Returns a flag - Ops[0] = DAG.getConstant(30, MVT::i32); - Ops[1] = InFlag; - Result = DAG.getNode(PPCISD::MTFSB0, NodeTys, Ops, 2); - InFlag = Result.getValue(0); - - NodeTys.clear(); - NodeTys.push_back(MVT::f64); // result of add - NodeTys.push_back(MVT::Flag); // Returns a flag - Ops[0] = Lo; - Ops[1] = Hi; - Ops[2] = InFlag; - Result = DAG.getNode(PPCISD::FADDRTZ, NodeTys, Ops, 3); - FPreg = Result.getValue(0); - InFlag = Result.getValue(1); - - NodeTys.clear(); - NodeTys.push_back(MVT::f64); - Ops[0] = DAG.getConstant(1, MVT::i32); - Ops[1] = MFFSreg; - Ops[2] = FPreg; - Ops[3] = InFlag; - Result = DAG.getNode(PPCISD::MTFSF, NodeTys, Ops, 4); - FPreg = Result.getValue(0); - - // We know the low half is about to be thrown away, so just use something - // convenient. - return DAG.getNode(ISD::BUILD_PAIR, MVT::ppcf128, FPreg, FPreg); -} - SDValue PPCTargetLowering::LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) { // Don't handle ppc_fp128 here; let it be lowered to a libcall. if (Op.getValueType() != MVT::f32 && Op.getValueType() != MVT::f64) @@ -3874,7 +3814,6 @@ case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); case ISD::FP_TO_SINT: return LowerFP_TO_SINT(Op, DAG); case ISD::SINT_TO_FP: return LowerSINT_TO_FP(Op, DAG); - case ISD::FP_ROUND_INREG: return LowerFP_ROUND_INREG(Op, DAG); case ISD::FLT_ROUNDS_: return LowerFLT_ROUNDS_(Op, DAG); // Lower 64-bit shifts. @@ -3896,17 +3835,74 @@ return SDValue(); } -SDNode *PPCTargetLowering::ReplaceNodeResults(SDNode *N, SelectionDAG &DAG) { +void PPCTargetLowering::ReplaceNodeResults(SDNode *N, + SmallVectorImpl&Results, + SelectionDAG &DAG) { switch (N->getOpcode()) { default: - return PPCTargetLowering::LowerOperation(SDValue (N, 0), DAG).getNode(); - case ISD::FP_TO_SINT: { - SDValue Res = LowerFP_TO_SINT(SDValue(N, 0), DAG); - // Use MERGE_VALUES to drop the chain result value and get a node with one - // result. This requires turning off getMergeValues simplification, since - // otherwise it will give us Res back. - return DAG.getMergeValues(&Res, 1, false).getNode(); + assert(false && "Do not know how to custom type legalize this operation!"); + return; + case ISD::FP_ROUND_INREG: { + assert(N->getValueType(0) == MVT::ppcf128); + assert(N->getOperand(0).getValueType() == MVT::ppcf128); + SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::f64, N->getOperand(0), + DAG.getIntPtrConstant(0)); + SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::f64, N->getOperand(0), + DAG.getIntPtrConstant(1)); + + // This sequence changes FPSCR to do round-to-zero, adds the two halves + // of the long double, and puts FPSCR back the way it was. We do not + // actually model FPSCR. + std::vector NodeTys; + SDValue Ops[4], Result, MFFSreg, InFlag, FPreg; + + NodeTys.push_back(MVT::f64); // Return register + NodeTys.push_back(MVT::Flag); // Returns a flag for later insns + Result = DAG.getNode(PPCISD::MFFS, NodeTys, &InFlag, 0); + MFFSreg = Result.getValue(0); + InFlag = Result.getValue(1); + + NodeTys.clear(); + NodeTys.push_back(MVT::Flag); // Returns a flag + Ops[0] = DAG.getConstant(31, MVT::i32); + Ops[1] = InFlag; + Result = DAG.getNode(PPCISD::MTFSB1, NodeTys, Ops, 2); + InFlag = Result.getValue(0); + + NodeTys.clear(); + NodeTys.push_back(MVT::Flag); // Returns a flag + Ops[0] = DAG.getConstant(30, MVT::i32); + Ops[1] = InFlag; + Result = DAG.getNode(PPCISD::MTFSB0, NodeTys, Ops, 2); + InFlag = Result.getValue(0); + + NodeTys.clear(); + NodeTys.push_back(MVT::f64); // result of add + NodeTys.push_back(MVT::Flag); // Returns a flag + Ops[0] = Lo; + Ops[1] = Hi; + Ops[2] = InFlag; + Result = DAG.getNode(PPCISD::FADDRTZ, NodeTys, Ops, 3); + FPreg = Result.getValue(0); + InFlag = Result.getValue(1); + + NodeTys.clear(); + NodeTys.push_back(MVT::f64); + Ops[0] = DAG.getConstant(1, MVT::i32); + Ops[1] = MFFSreg; + Ops[2] = FPreg; + Ops[3] = InFlag; + Result = DAG.getNode(PPCISD::MTFSF, NodeTys, Ops, 4); + FPreg = Result.getValue(0); + + // We know the low half is about to be thrown away, so just use something + // convenient. + Results.push_back(DAG.getNode(ISD::BUILD_PAIR, MVT::ppcf128, FPreg, FPreg)); + return; } + case ISD::FP_TO_SINT: + Results.push_back(LowerFP_TO_SINT(SDValue(N, 0), DAG)); + return; } } Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h?rev=60348&r1=60347&r2=60348&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h Mon Dec 1 05:39:25 2008 @@ -269,8 +269,12 @@ /// virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG); - virtual SDNode *ReplaceNodeResults(SDNode *N, SelectionDAG &DAG); - + /// ReplaceNodeResults - Replace the results of node with an illegal result + /// type with new values built out of custom code. + /// + virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl&Results, + SelectionDAG &DAG); + virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; virtual void computeMaskedBitsForTargetNode(const SDValue Op, @@ -372,7 +376,6 @@ SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG); SDValue LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG); SDValue LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG); - SDValue LowerFP_ROUND_INREG(SDValue Op, SelectionDAG &DAG); SDValue LowerFLT_ROUNDS_(SDValue Op, SelectionDAG &DAG); SDValue LowerSHL_PARTS(SDValue Op, SelectionDAG &DAG); SDValue LowerSRL_PARTS(SDValue Op, SelectionDAG &DAG); Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=60348&r1=60347&r2=60348&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Dec 1 05:39:25 2008 @@ -4863,22 +4863,6 @@ return DAG.getLoad(Op.getValueType(), FIST, StackSlot, NULL, 0); } -SDNode *X86TargetLowering::ExpandFP_TO_SINT(SDNode *N, SelectionDAG &DAG) { - std::pair Vals = FP_TO_SINTHelper(SDValue(N, 0), DAG); - SDValue FIST = Vals.first, StackSlot = Vals.second; - if (FIST.getNode() == 0) return 0; - - MVT VT = N->getValueType(0); - - // Return a load from the stack slot. - SDValue Res = DAG.getLoad(VT, FIST, StackSlot, NULL, 0); - - // Use MERGE_VALUES to drop the chain result value and get a node with one - // result. This requires turning off getMergeValues simplification, since - // otherwise it will give us Res back. - return DAG.getMergeValues(&Res, 1, false).getNode(); -} - SDValue X86TargetLowering::LowerFABS(SDValue Op, SelectionDAG &DAG) { MVT VT = Op.getValueType(); MVT EltVT = VT; @@ -5550,36 +5534,6 @@ return DAG.getNode(ISD::TokenFactor, MVT::Other, &Results[0], Results.size()); } -/// Expand the result of: i64,outchain = READCYCLECOUNTER inchain -SDNode *X86TargetLowering::ExpandREADCYCLECOUNTER(SDNode *N, SelectionDAG &DAG){ - SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag); - SDValue TheChain = N->getOperand(0); - SDValue rd = DAG.getNode(X86ISD::RDTSC_DAG, Tys, &TheChain, 1); - if (Subtarget->is64Bit()) { - SDValue rax = DAG.getCopyFromReg(rd, X86::RAX, MVT::i64, rd.getValue(1)); - SDValue rdx = DAG.getCopyFromReg(rax.getValue(1), X86::RDX, - MVT::i64, rax.getValue(2)); - SDValue Tmp = DAG.getNode(ISD::SHL, MVT::i64, rdx, - DAG.getConstant(32, MVT::i8)); - SDValue Ops[] = { - DAG.getNode(ISD::OR, MVT::i64, rax, Tmp), rdx.getValue(1) - }; - - return DAG.getMergeValues(Ops, 2).getNode(); - } - - SDValue eax = DAG.getCopyFromReg(rd, X86::EAX, MVT::i32, rd.getValue(1)); - SDValue edx = DAG.getCopyFromReg(eax.getValue(1), X86::EDX, - MVT::i32, eax.getValue(2)); - // Use a buildpair to merge the two 32-bit values into a 64-bit one. - SDValue Ops[] = { eax, edx }; - Ops[0] = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Ops, 2); - - // Use a MERGE_VALUES to return the value and chain. - Ops[1] = edx.getValue(1); - return DAG.getMergeValues(Ops, 2).getNode(); -} - SDValue X86TargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) { const Value *SV = cast(Op.getOperand(2))->getValue(); @@ -6186,10 +6140,8 @@ case MVT::i16: Reg = X86::AX; size = 2; break; case MVT::i32: Reg = X86::EAX; size = 4; break; case MVT::i64: - if (Subtarget->is64Bit()) { - Reg = X86::RAX; size = 8; - } else //Should go away when LegalizeType stuff lands - return SDValue(ExpandATOMIC_CMP_SWAP(Op.getNode(), DAG), 0); + assert(Subtarget->is64Bit() && "Node not type legal!"); + Reg = X86::RAX; size = 8; break; }; SDValue cpIn = DAG.getCopyToReg(Op.getOperand(0), Reg, @@ -6206,66 +6158,22 @@ return cpOut; } -SDNode* X86TargetLowering::ExpandATOMIC_CMP_SWAP(SDNode* Op, +SDValue X86TargetLowering::LowerREADCYCLECOUNTER(SDValue Op, SelectionDAG &DAG) { - MVT T = Op->getValueType(0); - assert (T == MVT::i64 && "Only know how to expand i64 Cmp and Swap"); - SDValue cpInL, cpInH; - cpInL = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op->getOperand(2), - DAG.getConstant(0, MVT::i32)); - cpInH = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op->getOperand(2), - DAG.getConstant(1, MVT::i32)); - cpInL = DAG.getCopyToReg(Op->getOperand(0), X86::EAX, - cpInL, SDValue()); - cpInH = DAG.getCopyToReg(cpInL.getValue(0), X86::EDX, - cpInH, cpInL.getValue(1)); - SDValue swapInL, swapInH; - swapInL = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op->getOperand(3), - DAG.getConstant(0, MVT::i32)); - swapInH = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op->getOperand(3), - DAG.getConstant(1, MVT::i32)); - swapInL = DAG.getCopyToReg(cpInH.getValue(0), X86::EBX, - swapInL, cpInH.getValue(1)); - swapInH = DAG.getCopyToReg(swapInL.getValue(0), X86::ECX, - swapInH, swapInL.getValue(1)); - SDValue Ops[] = { swapInH.getValue(0), - Op->getOperand(1), - swapInH.getValue(1) }; + assert(Subtarget->is64Bit() && "Result not type legalized?"); SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag); - SDValue Result = DAG.getNode(X86ISD::LCMPXCHG8_DAG, Tys, Ops, 3); - SDValue cpOutL = DAG.getCopyFromReg(Result.getValue(0), X86::EAX, MVT::i32, - Result.getValue(1)); - SDValue cpOutH = DAG.getCopyFromReg(cpOutL.getValue(1), X86::EDX, MVT::i32, - cpOutL.getValue(2)); - SDValue OpsF[] = { cpOutL.getValue(0), cpOutH.getValue(0)}; - SDValue ResultVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OpsF, 2); - SDValue Vals[2] = { ResultVal, cpOutH.getValue(1) }; - return DAG.getMergeValues(Vals, 2).getNode(); -} - -SDValue X86TargetLowering::LowerATOMIC_BINARY_64(SDValue Op, - SelectionDAG &DAG, - unsigned NewOp) { - SDNode *Node = Op.getNode(); - MVT T = Node->getValueType(0); - assert (T == MVT::i64 && "Only know how to expand i64 atomics"); - - SDValue Chain = Node->getOperand(0); - SDValue In1 = Node->getOperand(1); - SDValue In2L = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, - Node->getOperand(2), DAG.getIntPtrConstant(0)); - SDValue In2H = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, - Node->getOperand(2), DAG.getIntPtrConstant(1)); - // This is a generalized SDNode, not an AtomicSDNode, so it doesn't - // have a MemOperand. Pass the info through as a normal operand. - SDValue LSI = DAG.getMemOperand(cast(Node)->getMemOperand()); - SDValue Ops[] = { Chain, In1, In2L, In2H, LSI }; - SDVTList Tys = DAG.getVTList(MVT::i32, MVT::i32, MVT::Other); - SDValue Result = DAG.getNode(NewOp, Tys, Ops, 5); - SDValue OpsF[] = { Result.getValue(0), Result.getValue(1)}; - SDValue ResultVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OpsF, 2); - SDValue Vals[2] = { ResultVal, Result.getValue(2) }; - return SDValue(DAG.getMergeValues(Vals, 2).getNode(), 0); + SDValue TheChain = Op.getOperand(0); + SDValue rd = DAG.getNode(X86ISD::RDTSC_DAG, Tys, &TheChain, 1); + SDValue rax = DAG.getCopyFromReg(rd, X86::RAX, MVT::i64, rd.getValue(1)); + SDValue rdx = DAG.getCopyFromReg(rax.getValue(1), X86::RDX, MVT::i64, + rax.getValue(2)); + SDValue Tmp = DAG.getNode(ISD::SHL, MVT::i64, rdx, + DAG.getConstant(32, MVT::i8)); + SDValue Ops[] = { + DAG.getNode(ISD::OR, MVT::i64, rax, Tmp), + rdx.getValue(1) + }; + return DAG.getMergeValues(Ops, 2); } SDValue X86TargetLowering::LowerLOAD_SUB(SDValue Op, SelectionDAG &DAG) { @@ -6298,22 +6206,7 @@ case ISD::ATOMIC_LOAD_SUB_8: case ISD::ATOMIC_LOAD_SUB_16: case ISD::ATOMIC_LOAD_SUB_32: return LowerLOAD_SUB(Op,DAG); - case ISD::ATOMIC_LOAD_SUB_64: return (Subtarget->is64Bit()) ? - LowerLOAD_SUB(Op,DAG) : - LowerATOMIC_BINARY_64(Op,DAG, - X86ISD::ATOMSUB64_DAG); - case ISD::ATOMIC_LOAD_AND_64: return LowerATOMIC_BINARY_64(Op,DAG, - X86ISD::ATOMAND64_DAG); - case ISD::ATOMIC_LOAD_OR_64: return LowerATOMIC_BINARY_64(Op, DAG, - X86ISD::ATOMOR64_DAG); - case ISD::ATOMIC_LOAD_XOR_64: return LowerATOMIC_BINARY_64(Op,DAG, - X86ISD::ATOMXOR64_DAG); - case ISD::ATOMIC_LOAD_NAND_64:return LowerATOMIC_BINARY_64(Op,DAG, - X86ISD::ATOMNAND64_DAG); - case ISD::ATOMIC_LOAD_ADD_64: return LowerATOMIC_BINARY_64(Op,DAG, - X86ISD::ATOMADD64_DAG); - case ISD::ATOMIC_SWAP_64: return LowerATOMIC_BINARY_64(Op,DAG, - X86ISD::ATOMSWAP64_DAG); + case ISD::ATOMIC_LOAD_SUB_64: return LowerLOAD_SUB(Op,DAG); case ISD::BUILD_VECTOR: return LowerBUILD_VECTOR(Op, DAG); case ISD::VECTOR_SHUFFLE: return LowerVECTOR_SHUFFLE(Op, DAG); case ISD::EXTRACT_VECTOR_ELT: return LowerEXTRACT_VECTOR_ELT(Op, DAG); @@ -6356,22 +6249,120 @@ case ISD::CTTZ: return LowerCTTZ(Op, DAG); case ISD::SADDO: return LowerXADDO(Op, DAG, ISD::SADDO); case ISD::UADDO: return LowerXADDO(Op, DAG, ISD::UADDO); - - // FIXME: REMOVE THIS WHEN LegalizeDAGTypes lands. - case ISD::READCYCLECOUNTER: - return SDValue(ExpandREADCYCLECOUNTER(Op.getNode(), DAG), 0); + case ISD::READCYCLECOUNTER: return LowerREADCYCLECOUNTER(Op, DAG); } } +void X86TargetLowering:: +ReplaceATOMIC_BINARY_64(SDNode *Node, SmallVectorImpl&Results, + SelectionDAG &DAG, unsigned NewOp) { + MVT T = Node->getValueType(0); + assert (T == MVT::i64 && "Only know how to expand i64 atomics"); + + SDValue Chain = Node->getOperand(0); + SDValue In1 = Node->getOperand(1); + SDValue In2L = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, + Node->getOperand(2), DAG.getIntPtrConstant(0)); + SDValue In2H = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, + Node->getOperand(2), DAG.getIntPtrConstant(1)); + // This is a generalized SDNode, not an AtomicSDNode, so it doesn't + // have a MemOperand. Pass the info through as a normal operand. + SDValue LSI = DAG.getMemOperand(cast(Node)->getMemOperand()); + SDValue Ops[] = { Chain, In1, In2L, In2H, LSI }; + SDVTList Tys = DAG.getVTList(MVT::i32, MVT::i32, MVT::Other); + SDValue Result = DAG.getNode(NewOp, Tys, Ops, 5); + SDValue OpsF[] = { Result.getValue(0), Result.getValue(1)}; + Results.push_back(DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OpsF, 2)); + Results.push_back(Result.getValue(2)); +} + /// ReplaceNodeResults - Replace a node with an illegal result type /// with a new node built out of custom code. -SDNode *X86TargetLowering::ReplaceNodeResults(SDNode *N, SelectionDAG &DAG) { +void X86TargetLowering::ReplaceNodeResults(SDNode *N, + SmallVectorImpl&Results, + SelectionDAG &DAG) { switch (N->getOpcode()) { default: - return X86TargetLowering::LowerOperation(SDValue (N, 0), DAG).getNode(); - case ISD::FP_TO_SINT: return ExpandFP_TO_SINT(N, DAG); - case ISD::READCYCLECOUNTER: return ExpandREADCYCLECOUNTER(N, DAG); - case ISD::ATOMIC_CMP_SWAP_64: return ExpandATOMIC_CMP_SWAP(N, DAG); + assert(false && "Do not know how to custom type legalize this operation!"); + return; + case ISD::FP_TO_SINT: { + std::pair Vals = FP_TO_SINTHelper(SDValue(N, 0), DAG); + SDValue FIST = Vals.first, StackSlot = Vals.second; + if (FIST.getNode() != 0) { + MVT VT = N->getValueType(0); + // Return a load from the stack slot. + Results.push_back(DAG.getLoad(VT, FIST, StackSlot, NULL, 0)); + } + return; + } + case ISD::READCYCLECOUNTER: { + SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag); + SDValue TheChain = N->getOperand(0); + SDValue rd = DAG.getNode(X86ISD::RDTSC_DAG, Tys, &TheChain, 1); + SDValue eax = DAG.getCopyFromReg(rd, X86::EAX, MVT::i32, rd.getValue(1)); + SDValue edx = DAG.getCopyFromReg(eax.getValue(1), X86::EDX, MVT::i32, + eax.getValue(2)); + // Use a buildpair to merge the two 32-bit values into a 64-bit one. + SDValue Ops[] = { eax, edx }; + Results.push_back(DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Ops, 2)); + Results.push_back(edx.getValue(1)); + return; + } + case ISD::ATOMIC_CMP_SWAP_64: { + MVT T = N->getValueType(0); + assert (T == MVT::i64 && "Only know how to expand i64 Cmp and Swap"); + SDValue cpInL, cpInH; + cpInL = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, N->getOperand(2), + DAG.getConstant(0, MVT::i32)); + cpInH = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, N->getOperand(2), + DAG.getConstant(1, MVT::i32)); + cpInL = DAG.getCopyToReg(N->getOperand(0), X86::EAX, cpInL, SDValue()); + cpInH = DAG.getCopyToReg(cpInL.getValue(0), X86::EDX, cpInH, + cpInL.getValue(1)); + SDValue swapInL, swapInH; + swapInL = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, N->getOperand(3), + DAG.getConstant(0, MVT::i32)); + swapInH = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, N->getOperand(3), + DAG.getConstant(1, MVT::i32)); + swapInL = DAG.getCopyToReg(cpInH.getValue(0), X86::EBX, swapInL, + cpInH.getValue(1)); + swapInH = DAG.getCopyToReg(swapInL.getValue(0), X86::ECX, swapInH, + swapInL.getValue(1)); + SDValue Ops[] = { swapInH.getValue(0), + N->getOperand(1), + swapInH.getValue(1) }; + SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag); + SDValue Result = DAG.getNode(X86ISD::LCMPXCHG8_DAG, Tys, Ops, 3); + SDValue cpOutL = DAG.getCopyFromReg(Result.getValue(0), X86::EAX, MVT::i32, + Result.getValue(1)); + SDValue cpOutH = DAG.getCopyFromReg(cpOutL.getValue(1), X86::EDX, MVT::i32, + cpOutL.getValue(2)); + SDValue OpsF[] = { cpOutL.getValue(0), cpOutH.getValue(0)}; + Results.push_back(DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OpsF, 2)); + Results.push_back(cpOutH.getValue(1)); + return; + } + case ISD::ATOMIC_LOAD_ADD_64: + ReplaceATOMIC_BINARY_64(N, Results, DAG, X86ISD::ATOMADD64_DAG); + return; + case ISD::ATOMIC_LOAD_AND_64: + ReplaceATOMIC_BINARY_64(N, Results, DAG, X86ISD::ATOMAND64_DAG); + return; + case ISD::ATOMIC_LOAD_NAND_64: + ReplaceATOMIC_BINARY_64(N, Results, DAG, X86ISD::ATOMNAND64_DAG); + return; + case ISD::ATOMIC_LOAD_OR_64: + ReplaceATOMIC_BINARY_64(N, Results, DAG, X86ISD::ATOMOR64_DAG); + return; + case ISD::ATOMIC_LOAD_SUB_64: + ReplaceATOMIC_BINARY_64(N, Results, DAG, X86ISD::ATOMSUB64_DAG); + return; + case ISD::ATOMIC_LOAD_XOR_64: + ReplaceATOMIC_BINARY_64(N, Results, DAG, X86ISD::ATOMXOR64_DAG); + return; + case ISD::ATOMIC_SWAP_64: + ReplaceATOMIC_BINARY_64(N, Results, DAG, X86ISD::ATOMSWAP64_DAG); + return; } } Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=60348&r1=60347&r2=60348&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Mon Dec 1 05:39:25 2008 @@ -375,10 +375,11 @@ /// virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG); - /// ReplaceNodeResults - Replace a node with an illegal result type - /// with a new node built out of custom code. + /// ReplaceNodeResults - Replace the results of node with an illegal result + /// type with new values built out of custom code. /// - virtual SDNode *ReplaceNodeResults(SDNode *N, SelectionDAG &DAG); + virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl&Results, + SelectionDAG &DAG); virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; @@ -596,12 +597,11 @@ SDValue LowerCMP_SWAP(SDValue Op, SelectionDAG &DAG); SDValue LowerLOAD_SUB(SDValue Op, SelectionDAG &DAG); - SDValue LowerATOMIC_BINARY_64(SDValue Op, SelectionDAG &DAG, - unsigned NewOp); - SDNode *ExpandFP_TO_SINT(SDNode *N, SelectionDAG &DAG); - SDNode *ExpandREADCYCLECOUNTER(SDNode *N, SelectionDAG &DAG); - SDNode *ExpandATOMIC_CMP_SWAP(SDNode *N, SelectionDAG &DAG); - + SDValue LowerREADCYCLECOUNTER(SDValue Op, SelectionDAG &DAG); + + void ReplaceATOMIC_BINARY_64(SDNode *N, SmallVectorImpl &Results, + SelectionDAG &DAG, unsigned NewOp); + SDValue EmitTargetCodeForMemset(SelectionDAG &DAG, SDValue Chain, SDValue Dst, SDValue Src, Modified: llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp?rev=60348&r1=60347&r2=60348&view=diff ============================================================================== --- llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp (original) +++ llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp Mon Dec 1 05:39:25 2008 @@ -161,7 +161,7 @@ case ISD::VASTART: return LowerVASTART(Op, DAG); // FIXME: Remove these when LegalizeDAGTypes lands. case ISD::ADD: - case ISD::SUB: return SDValue(ExpandADDSUB(Op.getNode(), DAG),0); + case ISD::SUB: return ExpandADDSUB(Op.getNode(), DAG); case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); default: assert(0 && "unimplemented operand"); @@ -169,16 +169,19 @@ } } -/// ReplaceNodeResults - Provide custom lowering hooks for nodes with illegal -/// result types. -SDNode *XCoreTargetLowering:: -ReplaceNodeResults(SDNode *N, SelectionDAG &DAG) { +/// ReplaceNodeResults - Replace the results of node with an illegal result +/// type with new values built out of custom code. +void XCoreTargetLowering::ReplaceNodeResults(SDNode *N, + SmallVectorImpl&Results, + SelectionDAG &DAG) { switch (N->getOpcode()) { default: assert(0 && "Don't know how to custom expand this!"); - return NULL; + return; case ISD::ADD: - case ISD::SUB: return ExpandADDSUB(N, DAG); + case ISD::SUB: + Results.push_back(ExpandADDSUB(N, DAG)); + return; } } @@ -296,7 +299,7 @@ return DAG.getNode(XCoreISD::DPRelativeWrapper, MVT::i32, JTI); } -SDNode *XCoreTargetLowering:: +SDValue XCoreTargetLowering:: ExpandADDSUB(SDNode *N, SelectionDAG &DAG) { assert(N->getValueType(0) == MVT::i64 && @@ -326,7 +329,7 @@ LHSH, RHSH, Carry); SDValue Hi(Ignored.getNode(), 1); // Merge the pieces - return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi).getNode(); + return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi); } SDValue XCoreTargetLowering:: Modified: llvm/trunk/lib/Target/XCore/XCoreISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreISelLowering.h?rev=60348&r1=60347&r2=60348&view=diff ============================================================================== --- llvm/trunk/lib/Target/XCore/XCoreISelLowering.h (original) +++ llvm/trunk/lib/Target/XCore/XCoreISelLowering.h Mon Dec 1 05:39:25 2008 @@ -68,7 +68,11 @@ /// LowerOperation - Provide custom lowering hooks for some operations. virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG); - virtual SDNode *ReplaceNodeResults(SDNode *N, SelectionDAG &DAG); + /// ReplaceNodeResults - Replace the results of node with an illegal result + /// type with new values built out of custom code. + /// + virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl&Results, + SelectionDAG &DAG); /// getTargetNodeName - This method returns the name of a target specific // DAG node. @@ -112,7 +116,7 @@ MVT VT) const; // Expand specifics - SDNode *ExpandADDSUB(SDNode *Op, SelectionDAG &DAG); + SDValue ExpandADDSUB(SDNode *Op, SelectionDAG &DAG); }; } From baldrick at free.fr Mon Dec 1 05:41:33 2008 From: baldrick at free.fr (Duncan Sands) Date: Mon, 01 Dec 2008 11:41:33 -0000 Subject: [llvm-commits] [llvm] r60349 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAG.h lib/CodeGen/SelectionDAG/LegalizeDAG.cpp lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp lib/Target/ARM/ARMISelLowering.cpp lib/Target/Alpha/AlphaISelLowering.cpp lib/Target/CellSPU/SPUISelLowering.cpp lib/Target/Mips/MipsISelLowering.cpp lib/Target/PowerPC/PPCISelLowering.cpp lib/Target/Sparc/SparcISelLowering.cpp lib/Target/X86/X86ISelLowering.cpp Message-ID: <200812011141.mB1BfYpq029914@zion.cs.uiuc.edu> Author: baldrick Date: Mon Dec 1 05:41:29 2008 New Revision: 60349 URL: http://llvm.org/viewvc/llvm-project?rev=60349&view=rev Log: There are no longer any places that require a MERGE_VALUES node with only one operand, so get rid of special code that only existed to handle that possibility. Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAG.h?rev=60349&r1=60348&r2=60349&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Mon Dec 1 05:41:29 2008 @@ -486,19 +486,7 @@ bool ReadMem = true, bool WriteMem = true); /// getMergeValues - Create a MERGE_VALUES node from the given operands. - /// Allowed to return something different (and simpler) if Simplify is true. - SDValue getMergeValues(const SDValue *Ops, unsigned NumOps, - bool Simplify = true); - - /// getMergeValues - Create a MERGE_VALUES node from the given types and ops. - /// Allowed to return something different (and simpler) if Simplify is true. - /// May be faster than the above version if VTs is known and NumOps is large. - SDValue getMergeValues(SDVTList VTs, const SDValue *Ops, unsigned NumOps, - bool Simplify = true) { - if (Simplify && NumOps == 1) - return Ops[0]; - return getNode(ISD::MERGE_VALUES, VTs, Ops, NumOps); - } + SDValue getMergeValues(const SDValue *Ops, unsigned NumOps); /// getCall - Create a CALL node from the given information. /// Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=60349&r1=60348&r2=60349&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon Dec 1 05:41:29 2008 @@ -4235,7 +4235,8 @@ MVT ValueVTs[] = { LHS.getValueType(), OType }; SDValue Ops[] = { Sum, Cmp }; - Result = DAG.getMergeValues(DAG.getVTList(&ValueVTs[0], 2), &Ops[0], 2); + Result = DAG.getNode(ISD::MERGE_VALUES, DAG.getVTList(&ValueVTs[0], 2), + &Ops[0], 2); SDNode *RNode = Result.getNode(); DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 0), SDValue(RNode, 0)); DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 1), SDValue(RNode, 1)); @@ -4264,7 +4265,8 @@ MVT ValueVTs[] = { LHS.getValueType(), OType }; SDValue Ops[] = { Sum, Cmp }; - Result = DAG.getMergeValues(DAG.getVTList(&ValueVTs[0], 2), &Ops[0], 2); + Result = DAG.getNode(ISD::MERGE_VALUES, DAG.getVTList(&ValueVTs[0], 2), + &Ops[0], 2); SDNode *RNode = Result.getNode(); DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 0), SDValue(RNode, 0)); DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 1), SDValue(RNode, 1)); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=60349&r1=60348&r2=60349&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Mon Dec 1 05:41:29 2008 @@ -2187,8 +2187,9 @@ unsigned OpOpcode = Operand.getNode()->getOpcode(); switch (Opcode) { case ISD::TokenFactor: + case ISD::MERGE_VALUES: case ISD::CONCAT_VECTORS: - return Operand; // Factor or concat of one node? No need. + return Operand; // Factor, merge or concat of one node? No need. case ISD::FP_ROUND: assert(0 && "Invalid method to make FP_ROUND node"); case ISD::FP_EXTEND: assert(VT.isFloatingPoint() && @@ -3355,9 +3356,8 @@ /// getMergeValues - Create a MERGE_VALUES node from the given operands. /// Allowed to return something different (and simpler) if Simplify is true. -SDValue SelectionDAG::getMergeValues(const SDValue *Ops, unsigned NumOps, - bool Simplify) { - if (Simplify && NumOps == 1) +SDValue SelectionDAG::getMergeValues(const SDValue *Ops, unsigned NumOps) { + if (NumOps == 1) return Ops[0]; SmallVector VTs; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=60349&r1=60348&r2=60349&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Mon Dec 1 05:41:29 2008 @@ -2158,8 +2158,9 @@ SDValue(TrueVal.getNode(), TrueVal.getResNo() + i), SDValue(FalseVal.getNode(), FalseVal.getResNo() + i)); - setValue(&I, DAG.getMergeValues(DAG.getVTList(&ValueVTs[0], NumValues), - &Values[0], NumValues)); + setValue(&I, DAG.getNode(ISD::MERGE_VALUES, + DAG.getVTList(&ValueVTs[0], NumValues), + &Values[0], NumValues)); } } @@ -2528,8 +2529,9 @@ Values[i] = IntoUndef ? DAG.getNode(ISD::UNDEF, AggValueVTs[i]) : SDValue(Agg.getNode(), Agg.getResNo() + i); - setValue(&I, DAG.getMergeValues(DAG.getVTList(&AggValueVTs[0], NumAggValues), - &Values[0], NumAggValues)); + setValue(&I, DAG.getNode(ISD::MERGE_VALUES, + DAG.getVTList(&AggValueVTs[0], NumAggValues), + &Values[0], NumAggValues)); } void SelectionDAGLowering::visitExtractValue(ExtractValueInst &I) { @@ -2556,8 +2558,9 @@ Agg.getNode()->getValueType(Agg.getResNo() + i)) : SDValue(Agg.getNode(), Agg.getResNo() + i); - setValue(&I, DAG.getMergeValues(DAG.getVTList(&ValValueVTs[0], NumValValues), - &Values[0], NumValValues)); + setValue(&I, DAG.getNode(ISD::MERGE_VALUES, + DAG.getVTList(&ValValueVTs[0], NumValValues), + &Values[0], NumValValues)); } @@ -2721,8 +2724,9 @@ PendingLoads.push_back(Chain); } - setValue(&I, DAG.getMergeValues(DAG.getVTList(&ValueVTs[0], NumValues), - &Values[0], NumValues)); + setValue(&I, DAG.getNode(ISD::MERGE_VALUES, + DAG.getVTList(&ValueVTs[0], NumValues), + &Values[0], NumValues)); } @@ -4544,8 +4548,9 @@ Parts.clear(); } - return DAG.getMergeValues(DAG.getVTList(&ValueVTs[0], ValueVTs.size()), - &Values[0], ValueVTs.size()); + return DAG.getNode(ISD::MERGE_VALUES, + DAG.getVTList(&ValueVTs[0], ValueVTs.size()), + &Values[0], ValueVTs.size()); } /// getCopyToRegs - Emit a series of CopyToReg nodes that copies the @@ -5680,8 +5685,9 @@ AssertOp); ReturnValues.push_back(ReturnValue); } - Res = DAG.getMergeValues(DAG.getVTList(&RetTys[0], RetTys.size()), - &ReturnValues[0], ReturnValues.size()); + Res = DAG.getNode(ISD::MERGE_VALUES, + DAG.getVTList(&RetTys[0], RetTys.size()), + &ReturnValues[0], ReturnValues.size()); } return std::make_pair(Res, Chain); Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=60349&r1=60348&r2=60349&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Mon Dec 1 05:41:29 2008 @@ -1021,8 +1021,8 @@ ArgValues.push_back(Root); // Return the new list of results. - return DAG.getMergeValues(Op.getNode()->getVTList(), &ArgValues[0], - ArgValues.size()); + return DAG.getNode(ISD::MERGE_VALUES, Op.getNode()->getVTList(), + &ArgValues[0], ArgValues.size()); } /// isFloatingPointZero - Return true if this is +0.0. Modified: llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp?rev=60349&r1=60348&r2=60349&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp Mon Dec 1 05:41:29 2008 @@ -294,8 +294,8 @@ ArgValues.push_back(Root); // Return the new list of results. - return DAG.getMergeValues(Op.getNode()->getVTList(), &ArgValues[0], - ArgValues.size()); + return DAG.getNode(ISD::MERGE_VALUES, Op.getNode()->getVTList(), + &ArgValues[0], ArgValues.size()); } static SDValue LowerRET(SDValue Op, SelectionDAG &DAG) { Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=60349&r1=60348&r2=60349&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Mon Dec 1 05:41:29 2008 @@ -1047,8 +1047,8 @@ ArgValues.push_back(Root); // Return the new list of results. - return DAG.getMergeValues(Op.getNode()->getVTList(), &ArgValues[0], - ArgValues.size()); + return DAG.getNode(ISD::MERGE_VALUES, Op.getNode()->getVTList(), + &ArgValues[0], ArgValues.size()); } /// isLSAAddress - Return the immediate to use if the specified Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=60349&r1=60348&r2=60349&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Mon Dec 1 05:41:29 2008 @@ -778,8 +778,8 @@ ResultVals.push_back(Chain); // Merge everything together with a MERGE_VALUES node. - return DAG.getMergeValues(TheCall->getVTList(), &ResultVals[0], - ResultVals.size()).getNode(); + return DAG.getNode(ISD::MERGE_VALUES, TheCall->getVTList(), + &ResultVals[0], ResultVals.size()).getNode(); } //===----------------------------------------------------------------------===// @@ -921,8 +921,8 @@ ArgValues.push_back(Root); // Return the new list of results. - return DAG.getMergeValues(Op.getNode()->getVTList(), &ArgValues[0], - ArgValues.size()).getValue(Op.getResNo()); + return DAG.getNode(ISD::MERGE_VALUES, Op.getNode()->getVTList(), + &ArgValues[0], ArgValues.size()).getValue(Op.getResNo()); } //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=60349&r1=60348&r2=60349&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Mon Dec 1 05:41:29 2008 @@ -1261,7 +1261,7 @@ SDValue Ops[] = { CallResult.first, CallResult.second }; - return DAG.getMergeValues(Ops, 2, false); + return DAG.getMergeValues(Ops, 2); } SDValue PPCTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG, @@ -1825,8 +1825,8 @@ ArgValues.push_back(Root); // Return the new list of results. - return DAG.getMergeValues(Op.getNode()->getVTList(), &ArgValues[0], - ArgValues.size()); + return DAG.getNode(ISD::MERGE_VALUES, Op.getNode()->getVTList(), + &ArgValues[0], ArgValues.size()); } /// CalculateParameterAndLinkageAreaSize - Get the size of the paramter plus @@ -2605,8 +2605,8 @@ // Otherwise, merge everything together with a MERGE_VALUES node. ResultVals.push_back(Chain); - SDValue Res = DAG.getMergeValues(TheCall->getVTList(), &ResultVals[0], - ResultVals.size()); + SDValue Res = DAG.getNode(ISD::MERGE_VALUES, TheCall->getVTList(), + &ResultVals[0], ResultVals.size()); return Res.getValue(Op.getResNo()); } Modified: llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp?rev=60349&r1=60348&r2=60349&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp Mon Dec 1 05:41:29 2008 @@ -449,8 +449,8 @@ ResultVals.push_back(Chain); // Merge everything together with a MERGE_VALUES node. - return DAG.getMergeValues(TheCall->getVTList(), &ResultVals[0], - ResultVals.size()); + return DAG.getNode(ISD::MERGE_VALUES, TheCall->getVTList(), &ResultVals[0], + ResultVals.size()); } Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=60349&r1=60348&r2=60349&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Dec 1 05:41:29 2008 @@ -1048,8 +1048,8 @@ // Merge everything together with a MERGE_VALUES node. ResultVals.push_back(Chain); - return DAG.getMergeValues(TheCall->getVTList(), &ResultVals[0], - ResultVals.size()).getNode(); + return DAG.getNode(ISD::MERGE_VALUES, TheCall->getVTList(), &ResultVals[0], + ResultVals.size()).getNode(); } @@ -1431,8 +1431,8 @@ FuncInfo->setBytesToPopOnReturn(BytesToPopOnReturn); // Return the new list of results. - return DAG.getMergeValues(Op.getNode()->getVTList(), &ArgValues[0], - ArgValues.size()).getValue(Op.getResNo()); + return DAG.getNode(ISD::MERGE_VALUES, Op.getNode()->getVTList(), + &ArgValues[0], ArgValues.size()).getValue(Op.getResNo()); } SDValue From clattner at apple.com Mon Dec 1 10:48:37 2008 From: clattner at apple.com (Chris Lattner) Date: Mon, 1 Dec 2008 08:48:37 -0800 Subject: [llvm-commits] [llvm] r60275 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/apint-sub.ll test/Transforms/InstCombine/sdiv-1.ll test/Transforms/InstCombine/sub.ll In-Reply-To: <34480359-8CB1-4609-B68F-372D5233E7F0@gmail.com> References: <200811300342.mAU3gD0i009322@zion.cs.uiuc.edu> <34480359-8CB1-4609-B68F-372D5233E7F0@gmail.com> Message-ID: <177E9E63-5786-4CE2-9243-B5748623714F@apple.com> On Nov 30, 2008, at 11:59 PM, Bill Wendling wrote: >>> + // -X/C -> X/-C, if and only if negation doesn't overflow. >>> + if ((RHS->getSExtValue() < 0 && >>> + RHS->getSExtValue() < RHSNeg->getSExtValue()) || >>> + (RHS->getSExtValue() > 0 && >>> + RHS->getSExtValue() > RHSNeg->getSExtValue())) { >> >> How about checking: "RHSNext != RHS" ? >> > I've since changed this. It's now: > > if ((RHS->getValue().isNegative() && > RHSNegAPI.slt(TwoToExp - 1)) || > (RHS->getValue().isNonNegative() && > RHSNegAPI.sgt(TwoToExp * NegOne))) { > > This is what Hacker's Delight gave me (for -1*y). I can change it to > RHSNeg != RHS if you think that this will always hold in this case > (the non-negative part seems to be not necessary). What do you think? I'd strongly prefer that you replace all that logic with a simple pointer test, if it is safe. Is it safe? -Chris From sabre at nondot.org Mon Dec 1 10:50:11 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 01 Dec 2008 16:50:11 -0000 Subject: [llvm-commits] [llvm] r60352 - /llvm/trunk/include/llvm/ADT/STLExtras.h Message-ID: <200812011650.mB1GoEuT007899@zion.cs.uiuc.edu> Author: lattner Date: Mon Dec 1 10:50:01 2008 New Revision: 60352 URL: http://llvm.org/viewvc/llvm-project?rev=60352&view=rev Log: define array_pod_sort in terms of operator< instead of my brain damaged approximation. This should fix it on big endian platforms and on 64-bit. Modified: llvm/trunk/include/llvm/ADT/STLExtras.h Modified: llvm/trunk/include/llvm/ADT/STLExtras.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/STLExtras.h?rev=60352&r1=60351&r2=60352&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/STLExtras.h (original) +++ llvm/trunk/include/llvm/ADT/STLExtras.h Mon Dec 1 10:50:01 2008 @@ -222,18 +222,14 @@ } /// array_pod_sort_comparator - This is helper function for array_pod_sort, -/// which does a memcmp of a specific size. -template +/// which just uses operator< on T. +template static inline int array_pod_sort_comparator(const void *P1, const void *P2) { - if (Size == sizeof(char)) - return *(const char*)P1 - *(const char*)P2; - if (Size == sizeof(int)) - return *(const int*)P1 - *(const int*)P2; - if (Size == sizeof(long long)) - return *(const long long*)P1 - *(const long long*)P2; - if (Size == sizeof(intptr_t)) - return *(intptr_t*)P1 - *(intptr_t*)P2; - return memcmp(P1, P2, Size); + if (*reinterpret_cast(P1) < *reinterpret_cast(P2)) + return -1; + if (*reinterpret_cast(P2) < *reinterpret_cast(P1)) + return 1; + return 0; } /// array_pod_sort - This sorts an array with the specified start and end @@ -245,8 +241,8 @@ /// possible. /// /// This function assumes that you have simple POD-like types that can be -/// compared with memcmp and can be moved with memcpy. If this isn't true, you -/// should use std::sort. +/// compared with operator< and can be moved with memcpy. If this isn't true, +/// you should use std::sort. /// /// NOTE: If qsort_r were portable, we could allow a custom comparator and /// default to std::less. From sabre at nondot.org Mon Dec 1 10:55:38 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 01 Dec 2008 16:55:38 -0000 Subject: [llvm-commits] [llvm] r60353 - /llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Message-ID: <200812011655.mB1Gtf5Y008109@zion.cs.uiuc.edu> Author: lattner Date: Mon Dec 1 10:55:19 2008 New Revision: 60353 URL: http://llvm.org/viewvc/llvm-project?rev=60353&view=rev Log: cleanups suggested by duncan, thanks! Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60353&r1=60352&r2=60353&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Mon Dec 1 10:55:19 2008 @@ -35,6 +35,7 @@ enum DepType { /// Invalid - Clients of MemDep never see this. Invalid = 0, + /// Normal - This is a normal instruction dependence. The pointer member /// of the MemDepResult pair holds the instruction. Normal, @@ -216,7 +217,7 @@ void verifyRemoved(Instruction *Inst) const; MemDepResult getCallSiteDependency(CallSite C, BasicBlock::iterator ScanIt, - BasicBlock *BB); + BasicBlock *BB); }; } // End llvm namespace From sabre at nondot.org Mon Dec 1 11:00:22 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 01 Dec 2008 17:00:22 -0000 Subject: [llvm-commits] [llvm] r60354 - /llvm/trunk/include/llvm/ADT/STLExtras.h Message-ID: <200812011700.mB1H0PQL008241@zion.cs.uiuc.edu> Author: lattner Date: Mon Dec 1 11:00:08 2008 New Revision: 60354 URL: http://llvm.org/viewvc/llvm-project?rev=60354&view=rev Log: switch to std::sort until I have time to sort this out. Modified: llvm/trunk/include/llvm/ADT/STLExtras.h Modified: llvm/trunk/include/llvm/ADT/STLExtras.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/STLExtras.h?rev=60354&r1=60353&r2=60354&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/STLExtras.h (original) +++ llvm/trunk/include/llvm/ADT/STLExtras.h Mon Dec 1 11:00:08 2008 @@ -246,12 +246,16 @@ /// /// NOTE: If qsort_r were portable, we could allow a custom comparator and /// default to std::less. +#include + template static inline void array_pod_sort(IteratorTy Start, IteratorTy End) { + std::sort(Start, End); + // Don't dereference start iterator of empty sequence. - if (Start == End) return; - qsort(&*Start, End-Start, sizeof(*Start), - array_pod_sort_comparator); + //if (Start == End) return; + //qsort(&*Start, End-Start, sizeof(*Start), + // array_pod_sort_comparator<*Start>); } } // End llvm namespace From criswell at uiuc.edu Mon Dec 1 11:26:03 2008 From: criswell at uiuc.edu (John Criswell) Date: Mon, 01 Dec 2008 17:26:03 -0000 Subject: [llvm-commits] [poolalloc] r60356 - /poolalloc/trunk/lib/DSA/Local.cpp Message-ID: <200812011726.mB1HQEeB009101@zion.cs.uiuc.edu> Author: criswell Date: Mon Dec 1 11:25:29 2008 New Revision: 60356 URL: http://llvm.org/viewvc/llvm-project?rev=60356&view=rev Log: Switched to the new LLVM memcpy()/memset()/memmove() intrinsic names. Modified: poolalloc/trunk/lib/DSA/Local.cpp Modified: poolalloc/trunk/lib/DSA/Local.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Local.cpp?rev=60356&r1=60355&r2=60356&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/Local.cpp (original) +++ poolalloc/trunk/lib/DSA/Local.cpp Mon Dec 1 11:25:29 2008 @@ -575,10 +575,8 @@ case Intrinsic::dbg_region_start: case Intrinsic::dbg_declare: return true; // noop - case Intrinsic::memcpy_i32: - case Intrinsic::memcpy_i64: - case Intrinsic::memmove_i32: - case Intrinsic::memmove_i64: { + case Intrinsic::memcpy: + case Intrinsic::memmove: { // Merge the first & second arguments, and mark the memory read and // modified. DSNodeHandle RetNH = getValueDest(**CS.arg_begin()); @@ -587,8 +585,7 @@ N->setModifiedMarker()->setReadMarker(); return true; } - case Intrinsic::memset_i32: - case Intrinsic::memset_i64: + case Intrinsic::memset: // Mark the memory modified. if (DSNode *N = getValueDest(**CS.arg_begin()).getNode()) N->setModifiedMarker(); From scottm at aero.org Mon Dec 1 11:56:14 2008 From: scottm at aero.org (Scott Michel) Date: Mon, 01 Dec 2008 17:56:14 -0000 Subject: [llvm-commits] [llvm] r60358 - in /llvm/trunk: lib/Target/CellSPU/SPUISelDAGToDAG.cpp lib/Target/CellSPU/SPUISelLowering.cpp lib/Target/CellSPU/SPUInstrInfo.td test/CodeGen/CellSPU/vecinsert.ll Message-ID: <200812011756.mB1HuGQG010134@zion.cs.uiuc.edu> Author: pingbak Date: Mon Dec 1 11:56:02 2008 New Revision: 60358 URL: http://llvm.org/viewvc/llvm-project?rev=60358&view=rev Log: CellSPU: - Fix v2[if]64 vector insertion code before IBM files a bug report. - Ensure that zero (0) offsets relative to $sp don't trip an assert (add $sp, 0 gets legalized to $sp alone, tripping an assert) - Shuffle masks passed to SPUISD::SHUFB are now v16i8 or v4i32 Modified: llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td llvm/trunk/test/CodeGen/CellSPU/vecinsert.ll Modified: llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp?rev=60358&r1=60357&r2=60358&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp Mon Dec 1 11:56:02 2008 @@ -593,8 +593,8 @@ && !SelectDFormAddr(Op, N, Base, Index)) { // If the address is neither A-form or D-form, punt and use an X-form // address: - Base = N.getOperand(0); - Index = N.getOperand(1); + Base = N.getOperand(1); + Index = N.getOperand(0); return true; } Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=60358&r1=60357&r2=60358&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Mon Dec 1 11:56:02 2008 @@ -759,12 +759,13 @@ } SDValue insertEltOp = - DAG.getNode(SPUISD::SHUFFLE_MASK, stVecVT, insertEltPtr); + DAG.getNode(SPUISD::SHUFFLE_MASK, vecVT, insertEltPtr); SDValue vectorizeOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, vecVT, theValue); - result = DAG.getNode(SPUISD::SHUFB, vecVT, vectorizeOp, alignLoadVec, - DAG.getNode(ISD::BIT_CONVERT, vecVT, insertEltOp)); + result = DAG.getNode(SPUISD::SHUFB, vecVT, + vectorizeOp, alignLoadVec, + DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, insertEltOp)); result = DAG.getStore(the_chain, result, basePtr, LN->getSrcValue(), LN->getSrcValueOffset(), @@ -885,10 +886,10 @@ static SDValue LowerConstant(SDValue Op, SelectionDAG &DAG) { MVT VT = Op.getValueType(); - ConstantSDNode *CN = cast(Op.getNode()); if (VT == MVT::i64) { - SDValue T = DAG.getConstant(CN->getZExtValue(), MVT::i64); + ConstantSDNode *CN = cast(Op.getNode()); + SDValue T = DAG.getConstant(CN->getZExtValue(), VT); return DAG.getNode(SPUISD::VEC2PREFSLOT, VT, DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T)); } else { @@ -906,15 +907,18 @@ static SDValue LowerConstantFP(SDValue Op, SelectionDAG &DAG) { MVT VT = Op.getValueType(); - ConstantFPSDNode *FP = cast(Op.getNode()); - - assert((FP != 0) && - "LowerConstantFP: Node is not ConstantFPSDNode"); if (VT == MVT::f64) { + ConstantFPSDNode *FP = cast(Op.getNode()); + + assert((FP != 0) && + "LowerConstantFP: Node is not ConstantFPSDNode"); + uint64_t dbits = DoubleToBits(FP->getValueAPF().convertToDouble()); - return DAG.getNode(ISD::BIT_CONVERT, VT, - LowerConstant(DAG.getConstant(dbits, MVT::i64), DAG)); + SDValue T = DAG.getConstant(dbits, MVT::i64); + SDValue Tvec = DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T); + return DAG.getNode(SPUISD::VEC2PREFSLOT, VT, + DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64, Tvec)); } return SDValue(); @@ -1793,7 +1797,7 @@ DAG.getCopyToReg(DAG.getEntryNode(), VReg, DAG.getConstant(0, PtrVT)); // Copy register's contents as index in SHUFFLE_MASK: SDValue ShufMaskOp = - DAG.getNode(SPUISD::SHUFFLE_MASK, V1.getValueType(), + DAG.getNode(SPUISD::SHUFFLE_MASK, MVT::v4i32, DAG.getTargetConstant(V2Elt, MVT::i32), DAG.getCopyFromReg(InitTempReg, VReg, PtrVT)); // Use shuffle mask in SHUFB synthetic instruction: @@ -1818,7 +1822,7 @@ } SDValue VPermMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8, - &ResultMask[0], ResultMask.size()); + &ResultMask[0], ResultMask.size()); return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V1, V2, VPermMask); } } @@ -2165,7 +2169,7 @@ if (scaleShift > 0) { // Scale the shift factor: Elt = DAG.getNode(ISD::SHL, MVT::i32, Elt, - DAG.getConstant(scaleShift, MVT::i32)); + DAG.getConstant(scaleShift, MVT::i32)); } vecShift = DAG.getNode(SPUISD::SHLQUAD_L_BYTES, VecVT, N, Elt); @@ -2209,7 +2213,8 @@ } retval = DAG.getNode(SPUISD::VEC2PREFSLOT, VT, - DAG.getNode(SPUISD::SHUFB, VecVT, vecShift, vecShift, replicate)); + DAG.getNode(SPUISD::SHUFB, VecVT, + vecShift, vecShift, replicate)); } return retval; @@ -2225,18 +2230,17 @@ assert(CN != 0 && "LowerINSERT_VECTOR_ELT: Index is not constant!"); MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); - // Use $2 because it's always 16-byte aligned and it's available: - SDValue PtrBase = DAG.getRegister(SPU::R2, PtrVT); + // Use $sp ($1) because it's always 16-byte aligned and it's available: + SDValue Pointer = DAG.getNode(SPUISD::IndirectAddr, PtrVT, + DAG.getRegister(SPU::R1, PtrVT), + DAG.getConstant(CN->getSExtValue(), PtrVT)); + SDValue ShufMask = DAG.getNode(SPUISD::SHUFFLE_MASK, VT, Pointer); SDValue result = DAG.getNode(SPUISD::SHUFB, VT, DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, ValOp), - VecOp, - DAG.getNode(SPUISD::SHUFFLE_MASK, VT, - DAG.getNode(ISD::ADD, PtrVT, - PtrBase, - DAG.getConstant(CN->getZExtValue(), - PtrVT)))); + VecOp, + DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, ShufMask)); return result; } @@ -2901,8 +2905,10 @@ #endif const SPUSubtarget *ST = SPUTM.getSubtargetImpl(); SelectionDAG &DAG = DCI.DAG; - SDValue Op0 = N->getOperand(0); // everything has at least one operand - SDValue Result; // Initially, NULL result + SDValue Op0 = N->getOperand(0); // everything has at least one operand + MVT NodeVT = N->getValueType(0); // The node's value type + MVT Op0VT = Op0.getValueType(); // The first operand's result + SDValue Result; // Initially, empty result switch (N->getOpcode()) { default: break; @@ -2918,14 +2924,13 @@ ConstantSDNode *CN0 = cast(Op1); ConstantSDNode *CN1 = cast(Op01); SDValue combinedConst = - DAG.getConstant(CN0->getZExtValue() + CN1->getZExtValue(), - Op0.getValueType()); + DAG.getConstant(CN0->getZExtValue() + CN1->getZExtValue(), Op0VT); DEBUG(cerr << "Replace: (add " << CN0->getZExtValue() << ", " << "(SPUindirect , " << CN1->getZExtValue() << "))\n"); DEBUG(cerr << "With: (SPUindirect , " << CN0->getZExtValue() + CN1->getZExtValue() << ")\n"); - return DAG.getNode(SPUISD::IndirectAddr, Op0.getValueType(), + return DAG.getNode(SPUISD::IndirectAddr, Op0VT, Op0.getOperand(0), combinedConst); } } else if (isa(Op0) @@ -2938,8 +2943,7 @@ ConstantSDNode *CN0 = cast(Op0); ConstantSDNode *CN1 = cast(Op11); SDValue combinedConst = - DAG.getConstant(CN0->getZExtValue() + CN1->getZExtValue(), - Op0.getValueType()); + DAG.getConstant(CN0->getZExtValue() + CN1->getZExtValue(), Op0VT); DEBUG(cerr << "Replace: (add " << CN0->getZExtValue() << ", " << "(SPUindirect , " << CN1->getZExtValue() << "))\n"); @@ -2955,8 +2959,7 @@ case ISD::SIGN_EXTEND: case ISD::ZERO_EXTEND: case ISD::ANY_EXTEND: { - if (Op0.getOpcode() == SPUISD::VEC2PREFSLOT && - N->getValueType(0) == Op0.getValueType()) { + if (Op0.getOpcode() == SPUISD::VEC2PREFSLOT && NodeVT == Op0VT) { // (any_extend (SPUextract_elt0 )) -> // (SPUextract_elt0 ) // Types must match, however... @@ -3000,7 +3003,6 @@ if (isa(Op1)) { // Kill degenerate vector shifts: ConstantSDNode *CN = cast(Op1); - if (CN->getZExtValue() == 0) { Result = Op0; } @@ -3014,20 +3016,20 @@ case ISD::ANY_EXTEND: case ISD::ZERO_EXTEND: case ISD::SIGN_EXTEND: { - // (SPUpromote_scalar (any|sign|zero_extend (SPUextract_elt0 ))) -> + // (SPUpromote_scalar (any|zero|sign_extend (SPUvec2prefslot ))) -> // // but only if the SPUpromote_scalar and types match. SDValue Op00 = Op0.getOperand(0); if (Op00.getOpcode() == SPUISD::VEC2PREFSLOT) { SDValue Op000 = Op00.getOperand(0); - if (Op000.getValueType() == N->getValueType(0)) { + if (Op000.getValueType() == NodeVT) { Result = Op000; } } break; } case SPUISD::VEC2PREFSLOT: { - // (SPUpromote_scalar (SPUextract_elt0 )) -> + // (SPUpromote_scalar (SPUvec2prefslot )) -> // Result = Op0.getOperand(0); break; @@ -3037,7 +3039,7 @@ } } // Otherwise, return unchanged. -#ifdef NDEBUG +#ifndef NDEBUG if (Result.getNode()) { DEBUG(cerr << "\nReplace.SPU: "); DEBUG(N->dump(&DAG)); Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td?rev=60358&r1=60357&r2=60358&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td (original) +++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td Mon Dec 1 11:56:02 2008 @@ -269,52 +269,51 @@ // Generate Controls for Insertion: //===----------------------------------------------------------------------===// -def CBD : - RI7Form<0b10101111100, (outs VECREG:$rT), (ins memri7:$src), - "cbd\t$rT, $src", ShuffleOp, - [(set (v16i8 VECREG:$rT), (SPUshufmask dform2_addr:$src))]>; +def CBD: RI7Form<0b10101111100, (outs VECREG:$rT), (ins memri7:$src), + "cbd\t$rT, $src", ShuffleOp, + [(set (v16i8 VECREG:$rT), (SPUshufmask dform2_addr:$src))]>; -def CBX : RRForm<0b00101011100, (outs VECREG:$rT), (ins memrr:$src), +def CBX: RRForm<0b00101011100, (outs VECREG:$rT), (ins memrr:$src), "cbx\t$rT, $src", ShuffleOp, [(set (v16i8 VECREG:$rT), (SPUshufmask xform_addr:$src))]>; -def CHD : RI7Form<0b10101111100, (outs VECREG:$rT), (ins memri7:$src), +def CHD: RI7Form<0b10101111100, (outs VECREG:$rT), (ins memri7:$src), "chd\t$rT, $src", ShuffleOp, [(set (v8i16 VECREG:$rT), (SPUshufmask dform2_addr:$src))]>; -def CHX : RRForm<0b10101011100, (outs VECREG:$rT), (ins memrr:$src), +def CHX: RRForm<0b10101011100, (outs VECREG:$rT), (ins memrr:$src), "chx\t$rT, $src", ShuffleOp, [(set (v8i16 VECREG:$rT), (SPUshufmask xform_addr:$src))]>; -def CWD : RI7Form<0b01101111100, (outs VECREG:$rT), (ins memri7:$src), +def CWD: RI7Form<0b01101111100, (outs VECREG:$rT), (ins memri7:$src), "cwd\t$rT, $src", ShuffleOp, [(set (v4i32 VECREG:$rT), (SPUshufmask dform2_addr:$src))]>; -def CWDf32 : RI7Form<0b01101111100, (outs VECREG:$rT), (ins memri7:$src), - "cwd\t$rT, $src", ShuffleOp, - [(set (v4f32 VECREG:$rT), (SPUshufmask dform2_addr:$src))]>; - -def CWX : RRForm<0b01101011100, (outs VECREG:$rT), (ins memrr:$src), +def CWX: RRForm<0b01101011100, (outs VECREG:$rT), (ins memrr:$src), "cwx\t$rT, $src", ShuffleOp, [(set (v4i32 VECREG:$rT), (SPUshufmask xform_addr:$src))]>; -def CWXf32 : RRForm<0b01101011100, (outs VECREG:$rT), (ins memrr:$src), +def CWDf32: RI7Form<0b01101111100, (outs VECREG:$rT), (ins memri7:$src), + "cwd\t$rT, $src", ShuffleOp, + [(set (v4f32 VECREG:$rT), (SPUshufmask dform2_addr:$src))]>; + +def CWXf32: RRForm<0b01101011100, (outs VECREG:$rT), (ins memrr:$src), "cwx\t$rT, $src", ShuffleOp, [(set (v4f32 VECREG:$rT), (SPUshufmask xform_addr:$src))]>; -def CDD : RI7Form<0b11101111100, (outs VECREG:$rT), (ins memri7:$src), +def CDD: RI7Form<0b11101111100, (outs VECREG:$rT), (ins memri7:$src), "cdd\t$rT, $src", ShuffleOp, [(set (v2i64 VECREG:$rT), (SPUshufmask dform2_addr:$src))]>; -def CDDf64 : RI7Form<0b11101111100, (outs VECREG:$rT), (ins memri7:$src), - "cdd\t$rT, $src", ShuffleOp, - [(set (v2f64 VECREG:$rT), (SPUshufmask dform2_addr:$src))]>; - -def CDX : RRForm<0b11101011100, (outs VECREG:$rT), (ins memrr:$src), +def CDX: RRForm<0b11101011100, (outs VECREG:$rT), (ins memrr:$src), "cdx\t$rT, $src", ShuffleOp, [(set (v2i64 VECREG:$rT), (SPUshufmask xform_addr:$src))]>; -def CDXf64 : RRForm<0b11101011100, (outs VECREG:$rT), (ins memrr:$src), +def CDDf64: RI7Form<0b11101111100, (outs VECREG:$rT), (ins memri7:$src), + "cdd\t$rT, $src", ShuffleOp, + [(set (v2f64 VECREG:$rT), (SPUshufmask dform2_addr:$src))]>; + +def CDXf64: RRForm<0b11101011100, (outs VECREG:$rT), (ins memrr:$src), "cdx\t$rT, $src", ShuffleOp, [(set (v2f64 VECREG:$rT), (SPUshufmask xform_addr:$src))]>; @@ -1786,46 +1785,33 @@ RRRForm<0b1000, OOL, IOL, "shufb\t$rT, $rA, $rB, $rC", IntegerOp, pattern>; -class SHUFBVecInst: +class SHUFBVecInst: SHUFBInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), - [(set (vectype VECREG:$rT), (SPUshuffle (vectype VECREG:$rA), - (vectype VECREG:$rB), - (vectype VECREG:$rC)))]>; - -// It's this pattern that's probably the most useful, since SPUISelLowering -// methods create a v16i8 vector for $rC: -class SHUFBVecPat1: - Pat<(SPUshuffle (vectype VECREG:$rA), (vectype VECREG:$rB), - (masktype VECREG:$rC)), - (inst VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + [(set (resultvec VECREG:$rT), + (SPUshuffle (resultvec VECREG:$rA), + (resultvec VECREG:$rB), + (maskvec VECREG:$rC)))]>; multiclass ShuffleBytes { - def v16i8 : SHUFBVecInst; - def v8i16 : SHUFBVecInst; - def v4i32 : SHUFBVecInst; - def v2i64 : SHUFBVecInst; + def v16i8 : SHUFBVecInst; + def v16i8_m32 : SHUFBVecInst; + def v8i16 : SHUFBVecInst; + def v8i16_m32 : SHUFBVecInst; + def v4i32 : SHUFBVecInst; + def v4i32_m32 : SHUFBVecInst; + def v2i64 : SHUFBVecInst; + def v2i64_m32 : SHUFBVecInst; + + def v4f32 : SHUFBVecInst; + def v4f32_m32 : SHUFBVecInst; - def v4f32 : SHUFBVecInst; - def v2f64 : SHUFBVecInst; + def v2f64 : SHUFBVecInst; + def v2f64_m32 : SHUFBVecInst; } defm SHUFB : ShuffleBytes; -// Shuffle mask is a v16i8 vector -def : SHUFBVecPat1; -def : SHUFBVecPat1; -def : SHUFBVecPat1; -def : SHUFBVecPat1; -def : SHUFBVecPat1; - -// Shuffle mask is a v4i32 vector: -def : SHUFBVecPat1; -def : SHUFBVecPat1; -def : SHUFBVecPat1; -def : SHUFBVecPat1; -def : SHUFBVecPat1; - //===----------------------------------------------------------------------===// // Shift and rotate group: //===----------------------------------------------------------------------===// Modified: llvm/trunk/test/CodeGen/CellSPU/vecinsert.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/vecinsert.ll?rev=60358&r1=60357&r2=60358&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/vecinsert.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/vecinsert.ll Mon Dec 1 11:56:02 2008 @@ -1,12 +1,12 @@ ; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s -; RUN: grep cbd %t1.s | count 3 -; RUN: grep chd %t1.s | count 3 -; RUN: grep cwd %t1.s | count 6 -; RUN: grep il %t1.s | count 4 -; RUN: grep ilh %t1.s | count 3 +; RUN: grep cbd %t1.s | count 5 +; RUN: grep chd %t1.s | count 5 +; RUN: grep cwd %t1.s | count 10 +; RUN: grep il %t1.s | count 15 +; RUN: grep ilh %t1.s | count 10 ; RUN: grep iohl %t1.s | count 1 -; RUN: grep ilhu %t1.s | count 1 -; RUN: grep shufb %t1.s | count 12 +; RUN: grep ilhu %t1.s | count 4 +; RUN: grep shufb %t1.s | count 26 ; RUN: grep 17219 %t1.s | count 1 ; RUN: grep 22598 %t1.s | count 1 ; RUN: grep -- -39 %t1.s | count 1 @@ -51,3 +51,70 @@ %tmp1.2 = insertelement <4 x i32> %tmp1.1, i32 %x, i32 3 ret <4 x i32> %tmp1.2 } + +define void @variable_v16i8_1(<16 x i8>* %a, i32 %i) nounwind { +entry: + %arrayidx = getelementptr <16 x i8>* %a, i32 %i + %tmp2 = load <16 x i8>* %arrayidx + %tmp3 = insertelement <16 x i8> %tmp2, i8 1, i32 1 + %tmp8 = insertelement <16 x i8> %tmp3, i8 2, i32 11 + store <16 x i8> %tmp8, <16 x i8>* %arrayidx + ret void +} + +define void @variable_v8i16_1(<8 x i16>* %a, i32 %i) nounwind { +entry: + %arrayidx = getelementptr <8 x i16>* %a, i32 %i + %tmp2 = load <8 x i16>* %arrayidx + %tmp3 = insertelement <8 x i16> %tmp2, i16 1, i32 1 + %tmp8 = insertelement <8 x i16> %tmp3, i16 2, i32 6 + store <8 x i16> %tmp8, <8 x i16>* %arrayidx + ret void +} + +define void @variable_v4i32_1(<4 x i32>* %a, i32 %i) nounwind { +entry: + %arrayidx = getelementptr <4 x i32>* %a, i32 %i + %tmp2 = load <4 x i32>* %arrayidx + %tmp3 = insertelement <4 x i32> %tmp2, i32 1, i32 1 + %tmp8 = insertelement <4 x i32> %tmp3, i32 2, i32 2 + store <4 x i32> %tmp8, <4 x i32>* %arrayidx + ret void +} + +define void @variable_v4f32_1(<4 x float>* %a, i32 %i) nounwind { +entry: + %arrayidx = getelementptr <4 x float>* %a, i32 %i + %tmp2 = load <4 x float>* %arrayidx + %tmp3 = insertelement <4 x float> %tmp2, float 1.000000e+00, i32 1 + %tmp8 = insertelement <4 x float> %tmp3, float 2.000000e+00, i32 2 + store <4 x float> %tmp8, <4 x float>* %arrayidx + ret void +} + +define void @variable_v2i64_1(<2 x i64>* %a, i32 %i) nounwind { +entry: + %arrayidx = getelementptr <2 x i64>* %a, i32 %i + %tmp2 = load <2 x i64>* %arrayidx + %tmp3 = insertelement <2 x i64> %tmp2, i64 615, i32 0 + store <2 x i64> %tmp3, <2 x i64>* %arrayidx + ret void +} + +define void @variable_v2i64_2(<2 x i64>* %a, i32 %i) nounwind { +entry: + %arrayidx = getelementptr <2 x i64>* %a, i32 %i + %tmp2 = load <2 x i64>* %arrayidx + %tmp3 = insertelement <2 x i64> %tmp2, i64 615, i32 1 + store <2 x i64> %tmp3, <2 x i64>* %arrayidx + ret void +} + +define void @variable_v2f64_1(<2 x double>* %a, i32 %i) nounwind { +entry: + %arrayidx = getelementptr <2 x double>* %a, i32 %i + %tmp2 = load <2 x double>* %arrayidx + %tmp3 = insertelement <2 x double> %tmp2, double 1.000000e+00, i32 1 + store <2 x double> %tmp3, <2 x double>* %arrayidx + ret void +} From evan.cheng at apple.com Mon Dec 1 12:35:56 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 1 Dec 2008 10:35:56 -0800 Subject: [llvm-commits] [Patch] Custom Lowering for TRUNCATE In-Reply-To: References: Message-ID: <4F419882-73CC-407C-800B-2C33CAB09DF7@apple.com> The code to custom lower TRUNCATE should be inside the getTypeAction Legal case, right? switch (getTypeAction(Node->getOperand(0).getValueType())) { case Legal: Evan On Nov 28, 2008, at 9:03 AM, Tilmann Scheller wrote: > Hi, > > the attached patch enables custom lowering for TRUNCATE (needed in > order to custom lower TRUNCATE on CellSPU) > > Greetings, > > Tilmann > < > customLowerTruncate > .patch>_______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From evan.cheng at apple.com Mon Dec 1 12:44:32 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 1 Dec 2008 10:44:32 -0800 Subject: [llvm-commits] Patch: small fix to bit convert and shifts In-Reply-To: References: Message-ID: On Nov 30, 2008, at 8:32 PM, Mon Ping Wang wrote: > Hi, > > This is a small patch that fixes two problems in SelectionDAG.cpp > > 1) in getShuffleScalarElt, the code assumes that if the input to > the shuffle is a BIT_CONVERT, the input to the bit convert is also a > vector. This is not necessarily true as it is legal to bit convert a You didn't finish your sentence? :-) > > > 2) In getNode, the code assumes that for shifts, the shift amount > is always a scalar. Since shifts can operate also on vectors, this > assumption is not correct. The shift amount can be a vector as well? I thought operand 1 can be, but not the shift amount. Evan > > > -- Mon Ping > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From espindola at google.com Mon Dec 1 13:12:11 2008 From: espindola at google.com (Rafael Espindola) Date: Mon, 1 Dec 2008 19:12:11 +0000 Subject: [llvm-commits] [patch] print ".file" directives In-Reply-To: <38a0d8450811280731r5ab0fcdn787e06fdfebf0b6d@mail.gmail.com> References: <38a0d8450811280731r5ab0fcdn787e06fdfebf0b6d@mail.gmail.com> Message-ID: <38a0d8450812011112j476a41e1i7233ae906dde4377@mail.gmail.com> > The only thing I am not sure about is if it is always safe to add the > .file directive. I have tried on linux (GNU assembler version 2.18.0), > and darwin ppc (cctools-622.9~2, GNU assembler version 1.38). Can > someone with another assembler check if it is OK? I have updated the patch to print .file only on ELF targets. Tested on Linux x86-64 and darwin ppc. Cheers, -- Rafael Avila de Espindola Google | Gordon House | Barrow Street | Dublin 4 | Ireland Registered in Dublin, Ireland | Registration Number: 368047 -------------- next part -------------- A non-text attachment was scrubbed... Name: file.patch Type: text/x-diff Size: 4571 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081201/83dd8402/attachment.bin From isanbard at gmail.com Mon Dec 1 13:30:26 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 1 Dec 2008 11:30:26 -0800 Subject: [llvm-commits] [llvm] r60275 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/apint-sub.ll test/Transforms/InstCombine/sdiv-1.ll test/Transforms/InstCombine/sub.ll In-Reply-To: <177E9E63-5786-4CE2-9243-B5748623714F@apple.com> References: <200811300342.mAU3gD0i009322@zion.cs.uiuc.edu> <34480359-8CB1-4609-B68F-372D5233E7F0@gmail.com> <177E9E63-5786-4CE2-9243-B5748623714F@apple.com> Message-ID: <16e5fdf90812011130j4905a7adgc3f225b3980c1f1c@mail.gmail.com> On Mon, Dec 1, 2008 at 8:48 AM, Chris Lattner wrote: > On Nov 30, 2008, at 11:59 PM, Bill Wendling wrote: >>>> + // -X/C -> X/-C, if and only if negation doesn't overflow. >>>> + if ((RHS->getSExtValue() < 0 && >>>> + RHS->getSExtValue() < RHSNeg->getSExtValue()) || >>>> + (RHS->getSExtValue() > 0 && >>>> + RHS->getSExtValue() > RHSNeg->getSExtValue())) { >>> >>> How about checking: "RHSNext != RHS" ? >>> >> I've since changed this. It's now: >> >> if ((RHS->getValue().isNegative() && >> RHSNegAPI.slt(TwoToExp - 1)) || >> (RHS->getValue().isNonNegative() && >> RHSNegAPI.sgt(TwoToExp * NegOne))) { >> >> This is what Hacker's Delight gave me (for -1*y). I can change it to >> RHSNeg != RHS if you think that this will always hold in this case >> (the non-negative part seems to be not necessary). What do you think? > > I'd strongly prefer that you replace all that logic with a simple > pointer test, if it is safe. Is it safe? > I was looking at the logic last night and couldn't see anything obviously wrong with doing the simple pointer test. I'll go ahead and make the changes. -bw From evan.cheng at apple.com Mon Dec 1 13:39:25 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 1 Dec 2008 11:39:25 -0800 Subject: [llvm-commits] [patch] print ".file" directives In-Reply-To: <38a0d8450811280731r5ab0fcdn787e06fdfebf0b6d@mail.gmail.com> References: <38a0d8450811280731r5ab0fcdn787e06fdfebf0b6d@mail.gmail.com> Message-ID: <23C4696E-E675-4BD2-84A8-BEDF2BF52B5D@apple.com> Ok if the .file directive is universally accepted by all assemblers. I suspect not though since TargetAsmInfo has a HasDotLocAndDotFile field. Evan On Nov 28, 2008, at 7:31 AM, Rafael Espindola wrote: > The attached patch fixes bug 3140 by printing the module name in the > .file directive. This adds very minimal debug info for the simple case > of a C (or C++) file compile one at a time. > > The only thing I am not sure about is if it is always safe to add the > .file directive. I have tried on linux (GNU assembler version 2.18.0), > and darwin ppc (cctools-622.9~2, GNU assembler version 1.38). Can > someone with another assembler check if it is OK? > > Thanks, > -- > Rafael Avila de Espindola > > Google | Gordon House | Barrow Street | Dublin 4 | Ireland > Registered in Dublin, Ireland | Registration Number: 368047 > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Mon Dec 1 13:45:45 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 01 Dec 2008 19:45:45 -0000 Subject: [llvm-commits] [llvm] r60365 - /llvm/trunk/include/llvm/ADT/STLExtras.h Message-ID: <200812011945.mB1Jjj2U013914@zion.cs.uiuc.edu> Author: lattner Date: Mon Dec 1 13:45:45 2008 New Revision: 60365 URL: http://llvm.org/viewvc/llvm-project?rev=60365&view=rev Log: don't #include into the llvm namespace. Modified: llvm/trunk/include/llvm/ADT/STLExtras.h Modified: llvm/trunk/include/llvm/ADT/STLExtras.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/STLExtras.h?rev=60365&r1=60364&r2=60365&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/STLExtras.h (original) +++ llvm/trunk/include/llvm/ADT/STLExtras.h Mon Dec 1 13:45:45 2008 @@ -246,7 +246,9 @@ /// /// NOTE: If qsort_r were portable, we could allow a custom comparator and /// default to std::less. +} #include +namespace llvm { template static inline void array_pod_sort(IteratorTy Start, IteratorTy End) { From isanbard at gmail.com Mon Dec 1 13:46:27 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 01 Dec 2008 19:46:27 -0000 Subject: [llvm-commits] [llvm] r60366 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200812011946.mB1JkSs4013946@zion.cs.uiuc.edu> Author: void Date: Mon Dec 1 13:46:27 2008 New Revision: 60366 URL: http://llvm.org/viewvc/llvm-project?rev=60366&view=rev Log: Use a simple comparison. Overflow on integer negation can only occur when the integer is "minint". Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60366&r1=60365&r2=60366&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Mon Dec 1 13:46:27 2008 @@ -2934,20 +2934,9 @@ if (Value *LHSNeg = dyn_castNegVal(Op0)) { if (ConstantInt *CI = dyn_cast(LHSNeg)) { ConstantInt *RHSNeg = cast(ConstantExpr::getNeg(RHS)); - APInt RHSNegAPI(RHSNeg->getValue()); - - APInt NegOne = -APInt(RHSNeg->getBitWidth(), 1, true); - APInt TwoToExp(RHSNeg->getBitWidth(), 1 << (RHSNeg->getBitWidth() - 1)); - - if ((RHS->getValue().isNegative() && - RHSNegAPI.slt(TwoToExp - 1)) || - (RHS->getValue().isNonNegative() && - RHSNegAPI.sgt(TwoToExp * NegOne))) { + if (RHS != RHSNeg) { ConstantInt *CINeg = cast(ConstantExpr::getNeg(CI)); - APInt CINegAPI(CINeg->getValue()); - - if ((CI->getValue().isNegative() && CINegAPI.slt(TwoToExp - 1)) || - (CI->getValue().isNonNegative() && CINegAPI.sgt(TwoToExp*NegOne))) + if (CI != CINeg) return BinaryOperator::CreateSDiv(LHSNeg, ConstantExpr::getNeg(RHS)); } From clattner at apple.com Mon Dec 1 14:58:14 2008 From: clattner at apple.com (Chris Lattner) Date: Mon, 1 Dec 2008 12:58:14 -0800 Subject: [llvm-commits] [llvm] r60275 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/apint-sub.ll test/Transforms/InstCombine/sdiv-1.ll test/Transforms/InstCombine/sub.ll In-Reply-To: <16e5fdf90812011130j4905a7adgc3f225b3980c1f1c@mail.gmail.com> References: <200811300342.mAU3gD0i009322@zion.cs.uiuc.edu> <34480359-8CB1-4609-B68F-372D5233E7F0@gmail.com> <177E9E63-5786-4CE2-9243-B5748623714F@apple.com> <16e5fdf90812011130j4905a7adgc3f225b3980c1f1c@mail.gmail.com> Message-ID: >> I'd strongly prefer that you replace all that logic with a simple >> pointer test, if it is safe. Is it safe? >> > I was looking at the logic last night and couldn't see anything > obviously wrong with doing the simple pointer test. I'll go ahead and > make the changes. Thanks Bill! -Chris From tilmann.scheller at googlemail.com Mon Dec 1 14:59:09 2008 From: tilmann.scheller at googlemail.com (Tilmann Scheller) Date: Mon, 1 Dec 2008 21:59:09 +0100 Subject: [llvm-commits] [Patch] Custom Lowering for TRUNCATE In-Reply-To: <4F419882-73CC-407C-800B-2C33CAB09DF7@apple.com> References: <4F419882-73CC-407C-800B-2C33CAB09DF7@apple.com> Message-ID: On Mon, Dec 1, 2008 at 7:35 PM, Evan Cheng wrote: > The code to custom lower TRUNCATE should be inside the getTypeAction > Legal case, right? > > switch (getTypeAction(Node->getOperand(0).getValueType())) { > case Legal: > > Evan Yes, my bad. I've attached a new patch. Greetings, Tilmann -------------- next part -------------- A non-text attachment was scrubbed... Name: customLowerTruncate2.patch Type: text/x-patch Size: 678 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081201/87ce62c3/attachment.bin From isanbard at gmail.com Mon Dec 1 15:03:43 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 01 Dec 2008 21:03:43 -0000 Subject: [llvm-commits] [llvm] r60369 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200812012103.mB1L3iYG017254@zion.cs.uiuc.edu> Author: void Date: Mon Dec 1 15:03:43 2008 New Revision: 60369 URL: http://llvm.org/viewvc/llvm-project?rev=60369&view=rev Log: Document what this check is doing. Also, no need to cast to ConstantInt. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60369&r1=60368&r2=60369&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Mon Dec 1 15:03:43 2008 @@ -2933,10 +2933,10 @@ // -X/C -> X/-C, if and only if negation doesn't overflow. if (Value *LHSNeg = dyn_castNegVal(Op0)) { if (ConstantInt *CI = dyn_cast(LHSNeg)) { - ConstantInt *RHSNeg = cast(ConstantExpr::getNeg(RHS)); - if (RHS != RHSNeg) { - ConstantInt *CINeg = cast(ConstantExpr::getNeg(CI)); - if (CI != CINeg) + Constant *RHSNeg = ConstantExpr::getNeg(RHS); + if (RHS != RHSNeg) { // Check that there is no overflow. + Constant *CINeg = ConstantExpr::getNeg(CI); + if (CI != CINeg) // Check that there is no overflow. return BinaryOperator::CreateSDiv(LHSNeg, ConstantExpr::getNeg(RHS)); } From isanbard at gmail.com Mon Dec 1 15:06:30 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 01 Dec 2008 21:06:30 -0000 Subject: [llvm-commits] [llvm] r60370 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200812012106.mB1L6VTE017344@zion.cs.uiuc.edu> Author: void Date: Mon Dec 1 15:06:30 2008 New Revision: 60370 URL: http://llvm.org/viewvc/llvm-project?rev=60370&view=rev Log: Don't rebuild RHSNeg. Just use the one that's already there. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60370&r1=60369&r2=60370&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Mon Dec 1 15:06:30 2008 @@ -2937,8 +2937,7 @@ if (RHS != RHSNeg) { // Check that there is no overflow. Constant *CINeg = ConstantExpr::getNeg(CI); if (CI != CINeg) // Check that there is no overflow. - return BinaryOperator::CreateSDiv(LHSNeg, - ConstantExpr::getNeg(RHS)); + return BinaryOperator::CreateSDiv(LHSNeg, RHSNeg); } } } From sabre at nondot.org Mon Dec 1 15:11:25 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 01 Dec 2008 21:11:25 -0000 Subject: [llvm-commits] [llvm] r60371 - /llvm/trunk/include/llvm/ADT/STLExtras.h Message-ID: <200812012111.mB1LBPW9017500@zion.cs.uiuc.edu> Author: lattner Date: Mon Dec 1 15:11:25 2008 New Revision: 60371 URL: http://llvm.org/viewvc/llvm-project?rev=60371&view=rev Log: reenable array_pod_sort, this time hopefully happy on 64-bit and big endian systems. Modified: llvm/trunk/include/llvm/ADT/STLExtras.h Modified: llvm/trunk/include/llvm/ADT/STLExtras.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/STLExtras.h?rev=60371&r1=60370&r2=60371&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/STLExtras.h (original) +++ llvm/trunk/include/llvm/ADT/STLExtras.h Mon Dec 1 15:11:25 2008 @@ -231,6 +231,15 @@ return 1; return 0; } + +/// get_array_pad_sort_comparator - This is an internal helper function used to +/// get type deduction of T right. +template +static int (*get_array_pad_sort_comparator(const T &X)) + (const void*, const void*) { + return array_pod_sort_comparator; +} + /// array_pod_sort - This sorts an array with the specified start and end /// extent. This is just like std::sort, except that it calls qsort instead of @@ -246,18 +255,12 @@ /// /// NOTE: If qsort_r were portable, we could allow a custom comparator and /// default to std::less. -} -#include -namespace llvm { - template static inline void array_pod_sort(IteratorTy Start, IteratorTy End) { - std::sort(Start, End); - // Don't dereference start iterator of empty sequence. - //if (Start == End) return; - //qsort(&*Start, End-Start, sizeof(*Start), - // array_pod_sort_comparator<*Start>); + if (Start == End) return; + qsort(&*Start, End-Start, sizeof(*Start), + get_array_pad_sort_comparator(*Start)); } } // End llvm namespace From dalej at apple.com Mon Dec 1 16:00:02 2008 From: dalej at apple.com (Dale Johannesen) Date: Mon, 01 Dec 2008 22:00:02 -0000 Subject: [llvm-commits] [llvm] r60374 - in /llvm/trunk: lib/Transforms/Scalar/LoopStrengthReduce.cpp test/CodeGen/X86/2008-12-01-loop-iv-used-outside-loop.ll Message-ID: <200812012200.mB1M02ID019041@zion.cs.uiuc.edu> Author: johannes Date: Mon Dec 1 16:00:01 2008 New Revision: 60374 URL: http://llvm.org/viewvc/llvm-project?rev=60374&view=rev Log: Consider only references to an IV within the loop when figuring out the base of the IV. This produces better code in the example. (Addresses use (IV) instead of (BASE,IV) - a significant improvement on low-register machines like x86). Added: llvm/trunk/test/CodeGen/X86/2008-12-01-loop-iv-used-outside-loop.ll Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=60374&r1=60373&r2=60374&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Mon Dec 1 16:00:01 2008 @@ -643,7 +643,9 @@ // cases (e.g. use of a post-incremented induction variable) the NewBase // value will be pinned to live somewhere after the original computation. // In this case, we have to back off. - if (!isUseOfPostIncrementedValue) { + // However, do not insert new code inside the loop when the reference + // is outside. + if (!isUseOfPostIncrementedValue && L->contains(Inst->getParent())) { if (NewBasePt && isa(OperandValToReplace)) { InsertPt = NewBasePt; ++InsertPt; @@ -921,14 +923,16 @@ /// (a+c+d) -> (a+c). The common expression is *removed* from the Bases. static SCEVHandle RemoveCommonExpressionsFromUseBases(std::vector &Uses, - ScalarEvolution *SE) { + ScalarEvolution *SE, Loop *L) { unsigned NumUses = Uses.size(); - // Only one use? Use its base, regardless of what it is! + // Only one use? If inside the loop, use its base, regardless of what it is; + // if outside, use 0. SCEVHandle Zero = SE->getIntegerSCEV(0, Uses[0].Base->getType()); SCEVHandle Result = Zero; if (NumUses == 1) { - std::swap(Result, Uses[0].Base); + if (L->contains(Uses[0].Inst->getParent())) + std::swap(Result, Uses[0].Base); return Result; } @@ -941,7 +945,13 @@ std::vector UniqueSubExprs; std::vector SubExprs; + uint64_t NumUsesInsideLoop = 0; for (unsigned i = 0; i != NumUses; ++i) { + // For this purpose, consider only uses that are inside the loop. + if (!L->contains(Uses[i].Inst->getParent())) + continue; + NumUsesInsideLoop++; + // If the base is zero (which is common), return zero now, there are no // CSEs we can find. if (Uses[i].Base == Zero) return Zero; @@ -961,7 +971,7 @@ std::map::iterator I = SubExpressionUseCounts.find(UniqueSubExprs[i]); assert(I != SubExpressionUseCounts.end() && "Entry not found?"); - if (I->second == NumUses) { // Found CSE! + if (I->second == NumUsesInsideLoop) { // Found CSE! Result = SE->getAddExpr(Result, I->first); } else { // Remove non-cse's from SubExpressionUseCounts. @@ -974,6 +984,10 @@ // Otherwise, remove all of the CSE's we found from each of the base values. for (unsigned i = 0; i != NumUses; ++i) { + // For this purpose, consider only uses that are inside the loop. + if (!L->contains(Uses[i].Inst->getParent())) + continue; + // Split the expression into subexprs. SeparateSubExprs(SubExprs, Uses[i].Base, SE); @@ -1166,7 +1180,7 @@ // "A+B"), emit it to the preheader, then remove the expression from the // UsersToProcess base values. SCEVHandle CommonExprs = - RemoveCommonExpressionsFromUseBases(UsersToProcess, SE); + RemoveCommonExpressionsFromUseBases(UsersToProcess, SE, L); // Next, figure out what we can represent in the immediate fields of // instructions. If we can represent anything there, move it to the imm @@ -1450,6 +1464,12 @@ // Add BaseV to the PHI value if needed. RewriteExpr = SE->getAddExpr(RewriteExpr, SE->getUnknown(BaseV)); + // If this reference is not in the loop and we have a Common base, + // that has been added into the induction variable and must be + // subtracted off here. + if (HaveCommonExprs && !L->contains(User.Inst->getParent())) + RewriteExpr = SE->getMinusSCEV(RewriteExpr, CommonExprs); + User.RewriteInstructionToUseNewBase(RewriteExpr, NewBasePt, Rewriter, L, this, DeadInsts); Added: llvm/trunk/test/CodeGen/X86/2008-12-01-loop-iv-used-outside-loop.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2008-12-01-loop-iv-used-outside-loop.ll?rev=60374&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2008-12-01-loop-iv-used-outside-loop.ll (added) +++ llvm/trunk/test/CodeGen/X86/2008-12-01-loop-iv-used-outside-loop.ll Mon Dec 1 16:00:01 2008 @@ -0,0 +1,28 @@ +; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin | grep -v lea +; ModuleID = '' +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin9.5" + +define i8* @test(i8* %Q, i32* %L) nounwind { +entry: + br label %bb1 + +bb: ; preds = %bb1, %bb1 + %indvar.next = add i32 %P.0.rec, 1 ; [#uses=1] + br label %bb1 + +bb1: ; preds = %bb, %entry + %P.0.rec = phi i32 [ 0, %entry ], [ %indvar.next, %bb ] ; [#uses=3] + %P.0 = getelementptr i8* %Q, i32 %P.0.rec ; [#uses=2] + %0 = load i8* %P.0, align 1 ; [#uses=1] + switch i8 %0, label %bb3 [ + i8 12, label %bb + i8 42, label %bb + ] + +bb3: ; preds = %bb1 + %P.0.sum = add i32 %P.0.rec, 2 ; [#uses=1] + %1 = getelementptr i8* %Q, i32 %P.0.sum ; [#uses=1] + store i8 4, i8* %1, align 1 + ret i8* %P.0 +} From sabre at nondot.org Mon Dec 1 16:23:39 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 01 Dec 2008 22:23:39 -0000 Subject: [llvm-commits] [test-suite] r60375 - /test-suite/trunk/SingleSource/Benchmarks/Misc-C++/llloops.cpp Message-ID: <200812012223.mB1MNhux020136@zion.cs.uiuc.edu> Author: lattner Date: Mon Dec 1 16:23:16 2008 New Revision: 60375 URL: http://llvm.org/viewvc/llvm-project?rev=60375&view=rev Log: Remove this benchmark, it is using undefined behavior (accessing at least the 'u' array beyond its bounds in 'init') and is too brain twisting to fix. Owen, if you really really really want this benchmark, feel free to fix it and recommit. Removed: test-suite/trunk/SingleSource/Benchmarks/Misc-C++/llloops.cpp Removed: test-suite/trunk/SingleSource/Benchmarks/Misc-C++/llloops.cpp URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/Benchmarks/Misc-C%2B%2B/llloops.cpp?rev=60374&view=auto ============================================================================== --- test-suite/trunk/SingleSource/Benchmarks/Misc-C++/llloops.cpp (original) +++ test-suite/trunk/SingleSource/Benchmarks/Misc-C++/llloops.cpp (removed) @@ -1,2217 +0,0 @@ -/************************************************************************ - * * - * L. L. N. L. " C " K E R N E L S: M F L O P S P C V E R S I O N * - * * - * These kernels measure " C " numerical computation * - * rates for a spectrum of cpu-limited computational * - * structures or benchmarks. Mathematical through-put * - * is measured in units of millions of floating-point * - * operations executed per second, called Megaflops/sec. * - * * - ************************************************************************ - * Originally from Greg Astfalk, AT&T, P.O.Box 900, Princeton, * - * NJ. 08540. by way of Frank McMahon (LLNL). * - * * - * Modifications by Tim Peters, Kendall Square Res. Corp. Oct 92. * - * * - * This version by Roy Longbottom (retired, ex-CCTA UK) * - * Roy_Longbottom 101323.2241 at compuserve.com * - * March 1996 * - * * - * REFERENCE * - * * - * F.H.McMahon, The Livermore Fortran Kernels: * - * A Computer Test Of The Numerical Performance Range, * - * Lawrence Livermore National Laboratory, * - * Livermore, California, UCRL-53745, December 1986. * - * * - * from: National Technical Information Service * - * U.S. Department of Commerce * - * 5285 Port Royal Road * - * Springfield, VA. 22161 * - * * - ************************************************************************ - * The standard "C" code accesses the FORTRAN version for data * - * generation and result analysis. These features have been merged * - * to produce a program more suitable to run on PCs. FORTRAN features * - * for detailed statistical analysis of the results have been omitted. * - * * - * Changes to "C" code to produce correct results: * - * * - * Kernel 2 change i = ipntp - 1; to i = ipntp; * - * Kernel 7 third line of inner loop change r to q * - ************************************************************************ - * - * The kernels are executed as follows: - * - * parameters(x); - * do - * { - * execute kernel code - * - * endloop(x); - * } - * while (count < loop); - * - * Function parameters obtains the loop parameters, generates all the data - * and makes a copy of it for use with extra loops. Timing is started at - * the end of the function. - * - * The variable loop has a defined number of passes (e.g. 7 for kernel 1, - * long span - see Passes in table). This is multiplied by a further - * constant for which checksums are defined - 200/400/1600 for long/medium - * /short spans was chosen. The overhead of executing function endloop is - * calculated as below. This is deducted from the total time but probably - * could be ignored on PCs. - * - * The running time for each loop is set to a minimum of five seconds via - * repeating all loops until each has recorded at least 0.07 seconds (see - * calibration below). The extra loops required are shown under E in the - * tables. The data used in the loops is re-initialised from the copy in - * function endloop for each of the extra loops. The worst case overhead - * of this has been measured as less than 1% and is ignored. Note, the - * alternative of summing the time for each set of count passes cannot - * be relied upon when the time for one set is of the same order of - * magnitude as the clock resolution (0.05 to 0.06 seconds). Calibration - * also gives an indication of the linearity of timing. In the example - * shown, the overhead of 24 occurrences of data generation, which is - * excluded from the main timing, is about 0.6 seconds. - * - * The total floating point operations for the first kernel 1 results are - * 200 x 7 x 15 x 5 x 1001. For some other kernels, the total is not - * proportional to the span. - * - * The OK column in the tables indicates the number of correct significant - * digits out of 16 compared with the defined checksums. - * - * - * Example of Results - * - * L.L.N.L. 'C' KERNELS: MFLOPS P.C. VERSION - * - * Calculating outer loop overhead - * 1000 times 0.00 seconds - * 10000 times 0.00 seconds - * 100000 times 0.06 seconds - * 1000000 times 0.33 seconds - * 2000000 times 0.88 seconds - * 4000000 times 1.59 seconds - * 8000000 times 3.30 seconds - * 16000000 times 6.64 seconds - * Overhead for each loop 4.1500e-007 seconds - * - * Calibrating part 1 of 3 - * - * Loop count 4 0.94 seconds - * Loop count 16 2.08 seconds - * Loop count 32 3.52 seconds - * Loop count 64 6.42 seconds - * Loop count 128 12.31 seconds - * - * Loops 200 x 1 x Passes - * - * Kernel Floating Pt ops - * No Passes E No Total Secs. MFLOPS Span Checksums OK - * ------------ -- ------------- ----- ------- ---- ---------------------- -- - * 1 7 x 15 5 1.051050e+008 5.10 20.60 1001 5.114652693224671e+004 16 - * 2 67 x 21 4 1.091832e+008 5.20 20.98 101 1.539721811668384e+003 15 - * 3 9 x 15 2 5.405400e+007 4.17 12.97 1001 1.000742883066364e+001 15 - * 4 14 x 30 2 1.008000e+008 5.52 18.28 1001 5.999250595473891e-001 16 - * 5 10 x 12 2 4.800000e+007 5.43 8.84 1001 4.548871642387267e+003 16 - * 6 3 x 19 2 4.523520e+007 4.34 10.43 64 4.375116344729986e+003 16 - * 7 4 x 10 16 1.273600e+008 4.45 28.64 995 6.104251075174761e+004 16 - * 8 10 x 7 36 9.979200e+007 5.15 19.36 100 1.501268005625795e+005 15 - * 9 36 x 6 17 7.417440e+007 5.20 14.26 101 1.189443609974981e+005 16 - * 10 34 x 5 9 3.090600e+007 5.48 5.64 101 7.310369784325296e+004 16 - * 11 11 x 15 1 3.300000e+007 5.65 5.84 1001 3.342910972650109e+007 16 - * 12 12 x 30 1 7.200000e+007 6.50 11.08 1000 2.907141294167248e-005 16 - * 13 36 x 4 7 1.290240e+007 6.41 2.01 64 1.202533961842804e+011 15 - * 14 2 x 4 11 1.761760e+007 5.61 3.14 1001 3.165553044000335e+009 15 - * 15 1 x 15 33 4.950000e+007 5.66 8.75 101 3.943816690352044e+004 15 - * 16 25 x 30 10 7.950000e+007 6.14 12.95 75 5.650760000000000e+005 16 - * 17 35 x 9 9 5.726700e+007 5.03 11.38 101 1.114641772902486e+003 16 - * 18 2 x 11 44 9.583200e+007 5.76 16.64 100 1.015727037502299e+005 15 - * 19 39 x 21 6 9.926280e+007 6.14 16.16 101 5.421816960147207e+002 16 - * 20 1 x 15 26 7.800000e+007 5.93 13.16 1000 3.040644339351238e+007 16 - * 21 1 x 1 2 2.525000e+007 6.37 3.96 101 1.597308280710200e+008 15 - * 22 11 x 12 17 4.532880e+007 5.43 8.35 101 2.938604376566698e+002 15 - * 23 8 x 12 11 1.045440e+008 5.10 20.49 100 3.549900501563624e+004 15 - * 24 5 x 30 1 3.000000e+007 4.93 6.09 1001 5.000000000000000e+002 16 - * - * Maximum Rate 28.64 - * Average Rate 12.50 - * Geometric Mean 10.50 - * Harmonic Mean 8.25 - * Minimum Rate 2.01 - * - * Do Span 471 - * - * Calibrating part 2 of 3 - * - * Loop count 8 0.88 seconds - * Loop count 32 1.86 seconds - * Loop count 64 3.19 seconds - * Loop count 128 5.77 seconds - * Loop count 256 10.93 seconds - * - * Loops 200 x 2 x Passes - * - * Kernel Floating Pt ops - * No Passes E No Total Secs. MFLOPS Span Checksums OK - * ------------ -- ------------- ----- ------- ---- ---------------------- -- - * 1 40 x 15 5 1.212000e+008 4.84 25.04 101 5.253344778937972e+002 16 - * 2 40 x 20 4 1.241600e+008 5.91 21.02 101 1.539721811668384e+003 15 - * 3 53 x 20 2 8.564800e+007 5.10 16.78 101 1.009741436578952e+000 16 - * 4 70 x 32 2 1.075200e+008 4.29 25.07 101 5.999250595473891e-001 16 - * 5 55 x 13 2 5.720000e+007 4.99 11.46 101 4.589031939600982e+001 16 - * 6 7 x 19 2 5.107200e+007 4.70 10.87 32 8.631675645333210e+001 16 - * 7 22 x 12 16 1.706496e+008 5.56 30.71 101 6.345586315784055e+002 16 - * 8 6 x 6 36 1.026432e+008 5.26 19.50 100 1.501268005625795e+005 15 - * 9 21 x 5 17 7.211400e+007 5.03 14.33 101 1.189443609974981e+005 16 - * 10 19 x 5 9 3.454200e+007 6.13 5.63 101 7.310369784325296e+004 16 - * 11 64 x 20 1 5.120000e+007 4.95 10.35 101 3.433560407475758e+004 16 - * 12 68 x 20 1 5.440000e+007 5.16 10.53 100 7.127569130821465e-006 16 - * 13 41 x 3 7 1.102080e+007 5.47 2.01 32 9.816387810944356e+010 15 - * 14 10 x 4 11 1.777600e+007 5.49 3.24 101 3.039983465145392e+007 15 - * 15 1 x 7 33 4.620000e+007 5.32 8.69 101 3.943816690352044e+004 15 - * 16 27 x 21 10 6.350400e+007 5.02 12.66 40 6.480410000000000e+005 16 - * 17 20 x 9 9 6.544800e+007 5.74 11.40 101 1.114641772902486e+003 16 - * 18 1 x 10 44 8.712000e+007 5.22 16.69 100 1.015727037502299e+005 15 - * 19 23 x 15 6 8.362800e+007 5.11 16.36 101 5.421816960147207e+002 16 - * 20 8 x 9 26 7.488000e+007 5.43 13.80 100 3.126205178815432e+004 16 - * 21 1 x 2 2 5.000000e+007 5.55 9.01 50 7.824524877232093e+007 16 - * 22 7 x 9 17 4.326840e+007 5.21 8.31 101 2.938604376566698e+002 15 - * 23 5 x 9 11 9.801000e+007 4.77 20.54 100 3.549900501563624e+004 15 - * 24 31 x 30 1 3.720000e+007 6.06 6.14 101 5.000000000000000e+001 16 - * - * Maximum Rate 30.71 - * Average Rate 13.76 - * Geometric Mean 11.69 - * Harmonic Mean 9.19 - * Minimum Rate 2.01 - * - * Do Span 90 - * - * Calibrating part 3 of 3 - * - * Loop count 32 0.77 seconds - * Loop count 128 1.54 seconds - * Loop count 256 2.47 seconds - * Loop count 512 4.34 seconds - * Loop count 1024 8.13 seconds - * - * Loops 200 x 8 x Passes - * - * Kernel Floating Pt ops - * No Passes E No Total Secs. MFLOPS Span Checksums OK - * ------------ -- ------------- ----- ------- ---- ---------------------- -- - * 1 28 x 22 5 1.330560e+008 5.31 25.05 27 3.855104502494961e+001 16 - * 2 46 x 22 4 7.124480e+007 4.38 16.27 15 3.953296986903060e+001 16 - * 3 37 x 23 2 7.352640e+007 4.26 17.24 27 2.699309089320672e-001 16 - * 4 38 x 35 2 6.384000e+007 3.79 16.86 27 5.999250595473891e-001 16 - * 5 40 x 23 2 7.654400e+007 4.45 17.20 27 3.182615248447483e+000 16 - * 6 21 x 32 2 5.160960e+007 4.82 10.70 8 1.120309393467088e+000 15 - * 7 20 x 12 16 1.290240e+008 4.24 30.43 21 2.845720217644024e+001 16 - * 8 9 x 8 36 1.078272e+008 5.17 20.85 14 2.960543667875005e+003 15 - * 9 26 x 16 17 1.697280e+008 5.33 31.82 15 2.623968460874250e+003 16 - * 10 25 x 11 9 5.940000e+007 5.42 10.96 15 1.651291227698265e+003 16 - * 11 46 x 22 1 4.209920e+007 3.67 11.48 27 6.551161335845770e+002 16 - * 12 48 x 23 1 4.592640e+007 5.04 9.12 26 1.943435981130448e-006 16 - * 13 31 x 4 7 1.111040e+007 5.57 2.00 8 3.847124199949431e+010 15 - * 14 8 x 6 11 2.280960e+007 5.19 4.40 27 2.923540598672009e+006 15 - * 15 1 x 15 33 5.544000e+007 6.14 9.03 15 1.108997288134785e+003 16 - * 16 14 x 31 10 7.638400e+007 5.80 13.17 15 5.152160000000000e+005 16 - * 17 26 x 11 9 6.177600e+007 5.14 12.02 15 2.947368618589360e+001 16 - * 18 2 x 12 44 1.098240e+008 5.36 20.47 14 9.700646212337040e+002 16 - * 19 28 x 21 6 8.467200e+007 5.38 15.74 15 1.268230698051004e+001 15 - * 20 7 x 10 26 7.571200e+007 5.27 14.36 26 5.987713249475302e+002 16 - * 21 1 x 2 2 8.000000e+007 5.50 14.55 20 5.009945671204667e+007 16 - * 22 8 x 13 17 4.243200e+007 5.04 8.42 15 6.109968728263973e+000 16 - * 23 7 x 15 11 1.201200e+008 4.38 27.42 14 4.850340602749970e+002 16 - * 24 23 x 32 1 3.061760e+007 5.01 6.11 27 1.300000000000000e+001 16 - * - * Maximum Rate 31.82 - * Average Rate 15.24 - * Geometric Mean 13.06 - * Harmonic Mean 10.26 - * Minimum Rate 2.00 - * - * Do Span 19 - * - * Overall - * - * Part 1 weight 1 - * Part 2 weight 2 - * Part 3 weight 1 - * - * Maximum Rate 31.82 - * Average Rate 13.81 - * Geometric Mean 11.70 - * Harmonic Mean 9.17 - * Minimum Rate 2.00 - * - * Do Span 167 - * - * Enter the following data which will be filed with the results - * - * Month run 9/1996 - * PC model Escom - * CPU Pentium - * Clock MHz 100 - * Cache 256K - * Options Neptune chipset - * OS/DOS Windows 95 - * Compiler Watcom C/C++ Version 10.5 - * OptLevel Win386 -zp4 -otexan -om -fp5 -zc -5r - * Run by Roy Longbottom - * From UK - * Mail 101323.2241 at compuserve.com - * - * Note: the date, compiler and opt level are inserted by the program. - * - * The tables of results and running details are appended to file - * LLloops.txt. - * - * When a single MFLOPS rating is claimed for this benchmark it is - * usually the overall geometric mean result. - * - ********************************************************************** - * - * Pre-compiled codes were produced via a Watcom C/C++ 10.5 compiler. - * Versions are available for DOS, Windows 3/95 and NT/Win 95. Both - * non-optimised and optimised programs are available. The latter have - * options as in the above example. - * - * In this source code, function prototypes are declared and function - * headers have embedded parameter types to produce code for C and C++ - * at least suitable for compiling as such with the Watcom compiler. - * - *********************************************************************** - */ - -#include -#include -#include - - - struct Arrays - { - double U[1001]; - double V[1001]; - double W[1001]; - double X[1001]; - double Y[1001]; - double Z[1001]; - double G[1001]; - double Du1[101]; - double Du2[101]; - double Du3[101]; - double Grd[1001]; - double Dex[1001]; - double Xi[1001]; - double Ex[1001]; - double Ex1[1001]; - double Dex1[1001]; - double Vx[1001]; - double Xx[1001]; - double Rx[1001]; - double Rh[2048]; - double Vsp[101]; - double Vstp[101]; - double Vxne[101]; - double Vxnd[101]; - double Ve3[101]; - double Vlr[101]; - double Vlin[101]; - double B5[101]; - double Plan[300]; - double D[300]; - double Sa[101]; - double Sb[101]; - double P[512][4]; - double Px[101][25]; - double Cx[101][25]; - double Vy[25][101]; - double Vh[7][101]; - double Vf[7][101]; - double Vg[7][101]; - double Vs[7][101]; - double Za[7][101]; - double Zp[7][101]; - double Zq[7][101]; - double Zr[7][101]; - double Zm[7][101]; - double Zb[7][101]; - double Zu[7][101]; - double Zv[7][101]; - double Zz[7][101]; - double B[64][64]; - double C[64][64]; - double H[64][64]; - double U1[2][101][5]; - double U2[2][101][5]; - double U3[2][101][5]; - double Xtra[40]; - long E[96]; - long F[96]; - long Ix[1001]; - long Ir[1001]; - long Zone[301]; - double X0[1001]; - double W0[1001]; - double Px0[101][25]; - double P0[512][4]; - double H0[64][64]; - double Rh0[2048]; - double Vxne0[101]; - double Zr0[7][101]; - double Zu0[7][101]; - double Zv0[7][101]; - double Zz0[7][101]; - double Za0[101][25]; - double Stb50; - double Xx0; - - - }as1; - #define u as1.U - #define v as1.V - #define w as1.W - #define x as1.X - #define y as1.Y - #define z as1.Z - #define g as1.G - #define du1 as1.Du1 - #define du2 as1.Du2 - #define du3 as1.Du3 - #define grd as1.Grd - #define dex as1.Dex - #define xi as1.Xi - #define ex as1.Ex - #define ex1 as1.Ex1 - #define dex1 as1.Dex1 - #define vx as1.Vx - #define xx as1.Xx - #define rx as1.Rx - #define rh as1.Rh - #define vsp as1.Vsp - #define vstp as1.Vstp - #define vxne as1.Vxne - #define vxnd as1.Vxnd - #define ve3 as1.Ve3 - #define vlr as1.Vlr - #define vlin as1.Vlin - #define b5 as1.B5 - #define plan as1.Plan - #define d as1.D - #define sa as1.Sa - #define sb as1.Sb - #define p as1.P - #define px as1.Px - #define cx as1.Cx - #define vy as1.Vy - #define vh as1.Vh - #define vf as1.Vf - #define vg as1.Vg - #define vs as1.Vs - #define za as1.Za - #define zb as1.Zb - #define zp as1.Zp - #define zq as1.Zq - #define zr as1.Zr - #define zm as1.Zm - #define zz as1.Zz - #define zu as1.Zu - #define zv as1.Zv - #define b as1.B - #define c as1.C - #define h as1.H - #define u1 as1.U1 - #define u2 as1.U2 - #define u3 as1.U3 - #define xtra as1.Xtra - #define a11 as1.Xtra[1] - #define a12 as1.Xtra[2] - #define a13 as1.Xtra[3] - #define a21 as1.Xtra[4] - #define a22 as1.Xtra[5] - #define a23 as1.Xtra[6] - #define a31 as1.Xtra[7] - #define a32 as1.Xtra[8] - #define a33 as1.Xtra[9] - #define c0 as1.Xtra[12] - #define dk as1.Xtra[15] - #define dm22 as1.Xtra[16] - #define dm23 as1.Xtra[17] - #define dm24 as1.Xtra[18] - #define dm25 as1.Xtra[19] - #define dm26 as1.Xtra[20] - #define dm27 as1.Xtra[21] - #define dm28 as1.Xtra[22] - #define expmax as1.Xtra[26] - #define flx as1.Xtra[27] - #define q as1.Xtra[28] - #define r as1.Xtra[30] - #define s as1.Xtra[32] - #define sig as1.Xtra[34] - #define stb5 as1.Xtra[35] - #define t as1.Xtra[36] - #define xnm as1.Xtra[39] - #define e as1.E - #define f as1.F - #define ix as1.Ix - #define ir as1.Ir - #define zone as1.Zone - #define x0 as1.X0 - #define w0 as1.W0 - #define px0 as1.Px0 - #define p0 as1.P0 - #define h0 as1.H0 - #define rh0 as1.Rh0 - #define vxne0 as1.Vxne0 - #define zr0 as1.Zr0 - #define zu0 as1.Zu0 - #define zv0 as1.Zv0 - #define zz0 as1.Zz0 - #define za0 as1.Za0 - #define stb50 as1.Stb50 - #define xx0 as1.Xx0 - - - struct Parameters - { - long Inner_loops; - long Outer_loops; - long Loop_mult; - double Flops_per_loop; - double Sumcheck[3][25]; - long Accuracy[3][25]; - double LoopTime[3][25]; - double LoopSpeed[3][25]; - double LoopFlos[3][25]; - long Xflops[25]; - long Xloops[3][25]; - long Nspan[3][25]; - double TimeStart; - double TimeEnd; - double Loopohead; - long Count; - long Count2; - long Pass; - long Extra_loops[3][25]; - long K2; - long K3; - long M16; - long J5; - long Section; - long N16; - double Mastersum; - long M24; - - - }as2; - - #define n as2.Inner_loops - #define loop as2.Outer_loops - #define mult as2.Loop_mult - #define nflops as2.Flops_per_loop - #define Checksum as2.Sumcheck - #define accuracy as2.Accuracy - #define RunTime as2.LoopTime - #define Mflops as2.LoopSpeed - #define FPops as2.LoopFlos - #define nspan as2.Nspan - #define xflops as2.Xflops - #define xloops as2.Xloops - #define StartTime as2.TimeStart - #define EndTime as2.TimeEnd - #define overhead_l as2.Loopohead - #define count as2.Count - #define count2 as2.Count2 - #define pass as2.Pass - #define extra_loops as2.Extra_loops - #define k2 as2.K2 - #define k3 as2.K3 - #define m16 as2.M16 - #define j5 as2.J5 - #define section as2.Section - #define n16 as2.N16 - #define MasterSum as2.Mastersum - #define m24 as2.M24 - - - void init(long which); - - /* Initialises arrays and variables */ - - long endloop(long which); - - /* Controls outer loops and stores results */ - - long parameters(long which); - - /* Gets loop parameters and variables, starts timer */ - - void kernels(); - - /* The 24 kernels */ - - void check(long which); - - /* Calculates checksum accuracy */ - - void iqranf(); - - /* Random number generator for Kernel 14 */ - -main(int argc, char *argv[]) -{ - double pass_time, least, lmult, now = 1.0, wt; - double time1, time2; - long i, k, loop_passes; - long mul[3] = {1, 2, 8}; - double weight[3] = {1.0, 2.0, 1.0}; - long Endit, which; - double maximum[4]; - double minimum[4]; - double average[4]; - double harmonic[4]; - double geometric[4]; - long xspan[4]; - char general[9][80] = {" "}; - FILE *outfile; - int getinput = 1; - - if (argc > 1) - { - switch (argv[1][0]) - { - case 'N': - getinput = 0; - break; - case 'n': - getinput = 0; - break; - } - } - - - printf ("L.L.N.L. 'C' KERNELS: MFLOPS P.C. VERSION 4.0\n\n"); - - if (getinput == 0) - { - printf ("***** No run time input data *****\n\n"); - } - else - { - printf ("*** With run time input data ***\n\n"); - } - -/************************************************************************ - * Execute the kernels three times at different Do Spans * - ************************************************************************/ - - for ( section=0 ; section<3 ; section++ ) - { - loop_passes = 200 * mul[section]; - pass = -20; - mult = 2 * mul[section]; - - for ( i=1; i<25; i++) - { - extra_loops[section][i] = 500; - } - -/************************************************************************ - * Execute the kernels * - ************************************************************************/ - - kernels(); - - maximum[section] = 0.0; - minimum[section] = Mflops[section][1]; - average[section] = 0.0; - harmonic[section] = 0.0; - geometric[section] = 0.0; - xspan[section] = 0.0; - } - -/************************************************************************ - * End of executing the kernels three times at different Do Spans * - ************************************************************************/ -} - -/************************************************************************ - * The Kernels * - ************************************************************************/ - -void kernels() - { - - long lw; - long ipnt, ipntp, ii; - double temp; - long nl1, nl2; - long kx, ky; - double ar, br, cr; - long i, j, k, m; - long ip, i1, i2, j1, j2, j4, lb; - long ng, nz; - double tmp; - double scale, xnei, xnc, e3,e6; - long ink, jn, kn, kb5i; - double di, dn; - double qa; - - for ( k=0 ; k<25; k++) - { - Checksum[section][k] = 0.0; - } - - - - /* - ******************************************************************* - * Kernel 1 -- hydro fragment - ******************************************************************* - */ - - parameters (1); - - do - { - for ( k=0 ; k0 ); - - endloop (2); - } - while (count < loop); - - /* - ******************************************************************* - * Kernel 3 -- inner product - ******************************************************************* - */ - - parameters (3); - - do - { - q = 0.0; - for ( k=0 ; k= ng ) - { - vy[j][k] = 0.0; - continue; - } - if ( vh[j+1][k] > vh[j][k] ) - { - t = ar; - } - else - { - t = br; - } - if ( vf[j][k] < vf[j][k-1] ) - { - if ( vh[j][k-1] > vh[j+1][k-1] ) - r = vh[j][k-1]; - else - r = vh[j+1][k-1]; - s = vf[j][k-1]; - } - else - { - if ( vh[j][k] > vh[j+1][k] ) - r = vh[j][k]; - else - r = vh[j+1][k]; - s = vf[j][k]; - } - vy[j][k] = sqrt( vg[j][k]*vg[j][k] + r*r )* t/s; - if ( (k+1) >= nz ) - { - vs[j][k] = 0.0; - continue; - } - if ( vf[j][k] < vf[j-1][k] ) - { - if ( vg[j-1][k] > vg[j-1][k+1] ) - r = vg[j-1][k]; - else - r = vg[j-1][k+1]; - s = vf[j-1][k]; - t = br; - } - else - { - if ( vg[j][k] > vg[j][k+1] ) - r = vg[j][k]; - else - r = vg[j][k+1]; - s = vf[j][k]; - t = ar; - } - vs[j][k] = sqrt( vh[j][k]*vh[j][k] + r*r )* t / s; - } - } - endloop (15); - } - while (count < loop); - - /* - ******************************************************************* - * Kernel 16 -- Monte Carlo search loop - ******************************************************************* - */ - - parameters (16); - - - ii = n / 3; - lb = ii + ii; - k3 = k2 = 0; - do - { - i1 = m16 = 1; - label410: - j2 = ( n + n )*( m16 - 1 ) + 1; - for ( k=1 ; k<=n ; k++ ) - { - k2++; - j4 = j2 + k + k; - j5 = zone[j4-1]; - if ( j5 < n ) - { - if ( j5+lb < n ) - { /* 420 */ - tmp = plan[j5-1] - t; /* 435 */ - } - else - { - if ( j5+ii < n ) - { /* 415 */ - tmp = plan[j5-1] - s; /* 430 */ - } - else - { - tmp = plan[j5-1] - r; /* 425 */ - } - } - } - else if( j5 == n ) - { - break; /* 475 */ - } - else - { - k3++; /* 450 */ - tmp=(d[j5-1]-(d[j5-2]*(t-d[j5-3])*(t-d[j5-3])+(s-d[j5-4])* - (s-d[j5-4])+(r-d[j5-5])*(r-d[j5-5]))); - } - if ( tmp < 0.0 ) - { - if ( zone[j4-2] < 0 ) /* 445 */ - continue; /* 470 */ - else if ( !zone[j4-2] ) - break; /* 480 */ - } - else if ( tmp ) - { - if ( zone[j4-2] > 0 ) /* 440 */ - continue; /* 470 */ - else if ( !zone[j4-2] ) - break; /* 480 */ - } - else break; /* 485 */ - m16++; /* 455 */ - if ( m16 > zone[0] ) - m16 = 1; /* 460 */ - if ( i1-m16 ) /* 465 */ - goto label410; - else - break; - } - endloop (16); - } - while (count < loop); - - /* - ******************************************************************* - * Kernel 17 -- implicit, conditional computation - ******************************************************************* - */ - - parameters (17); - - do - { - i = n-1; - j = 0; - ink = -1; - scale = 5.0 / 3.0; - xnm = 1.0 / 3.0; - e6 = 1.03 / 3.07; - goto l61; -l60: e6 = xnm*vsp[i] + vstp[i]; - vxne[i] = e6; - xnm = e6; - ve3[i] = e6; - i += ink; - if ( i==j ) goto l62; -l61: e3 = xnm*vlr[i] + vlin[i]; - xnei = vxne[i]; - vxnd[i] = e6; - xnc = scale*e3; - if ( xnm > xnc ) goto l60; - if ( xnei > xnc ) goto l60; - ve3[i] = e3; - e6 = e3 + e3 - xnm; - vxne[i] = e3 + e3 - xnei; - xnm = e6; - i += ink; - if ( i != j ) goto l61; -l62:; - endloop (17); - } - while (count < loop); - - /* - ******************************************************************* - * Kernel 18 - 2-D explicit hydrodynamics fragment - ******************************************************************* - */ - - parameters (18); - - do - { - t = 0.0037; - s = 0.0041; - kn = 6; - jn = n; - for ( k=1 ; k dn ) dn = s; - } - x[k] = ( ( w[k] + v[k]*dn )* xx[k] + u[k] ) / ( vx[k] + v[k]*dn ); - xx[k+1] = ( x[k] - xx[k] )* dn + xx[k]; - } - endloop (20); - } - while (count < loop); - - /* - ******************************************************************* - * Kernel 21 -- matrix*matrix product - ******************************************************************* - */ - - parameters (21); - - do - { - for ( k=0 ; k<25 ; k++ ) - { - for ( i=0 ; i<25 ; i++ ) - { - for ( j=0 ; j= loop) /* else return */ - { - -/************************************************************************ - * End of standard set of loops for one kernel * - ************************************************************************/ - - count2 = count2 + 1; - if (count2 == extra_loops[section][which]) - /* else re-initialise parameters if required */ - { - -/************************************************************************ - * End of extra loops for 5 seconds execution time * - ************************************************************************/ - - count2 = 0; - if (which == 1) - { - for ( k=0 ; k Mmax) - { - ix[i] = inset + i + 1 * qq; - } - } - - return; - } - From sabre at nondot.org Mon Dec 1 16:35:33 2008 From: sabre at nondot.org (Chris Lattner) Date: Mon, 01 Dec 2008 22:35:33 -0000 Subject: [llvm-commits] [llvm] r60376 - /llvm/trunk/test/CodeGen/X86/2008-12-01-loop-iv-used-outside-loop.ll Message-ID: <200812012235.mB1MZYAL020537@zion.cs.uiuc.edu> Author: lattner Date: Mon Dec 1 16:35:31 2008 New Revision: 60376 URL: http://llvm.org/viewvc/llvm-project?rev=60376&view=rev Log: Add rdar reference, make this actually fail when the patch isn't applied. Modified: llvm/trunk/test/CodeGen/X86/2008-12-01-loop-iv-used-outside-loop.ll Modified: llvm/trunk/test/CodeGen/X86/2008-12-01-loop-iv-used-outside-loop.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2008-12-01-loop-iv-used-outside-loop.ll?rev=60376&r1=60375&r2=60376&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2008-12-01-loop-iv-used-outside-loop.ll (original) +++ llvm/trunk/test/CodeGen/X86/2008-12-01-loop-iv-used-outside-loop.ll Mon Dec 1 16:35:31 2008 @@ -1,5 +1,7 @@ -; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin | grep -v lea -; ModuleID = '' +; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin | not grep lea +; The inner loop should use [reg] addressing, not [reg+reg] addressing. +; rdar://6403965 + target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" target triple = "i386-apple-darwin9.5" From dalej at apple.com Mon Dec 1 16:37:55 2008 From: dalej at apple.com (Dale Johannesen) Date: Mon, 1 Dec 2008 14:37:55 -0800 Subject: [llvm-commits] [test-suite] r60375 - /test-suite/trunk/SingleSource/Benchmarks/Misc-C++/llloops.cpp In-Reply-To: <200812012223.mB1MNhux020136@zion.cs.uiuc.edu> References: <200812012223.mB1MNhux020136@zion.cs.uiuc.edu> Message-ID: <6315BAB5-2B40-469F-90B6-7100A3954AEB@apple.com> On Dec 1, 2008, at 2:23 PMPST, Chris Lattner wrote: > Author: lattner > Date: Mon Dec 1 16:23:16 2008 > New Revision: 60375 > > URL: http://llvm.org/viewvc/llvm-project?rev=60375&view=rev > Log: > Remove this benchmark, it is using undefined behavior (accessing > at least the 'u' array beyond its bounds in 'init') and is too > brain twisting to fix. Owen, if you really really really want this > benchmark, feel free to fix it and recommit. Livermore Loops is an old but well-known benchmark, well worth fixing. It is brain twisting partly because it was translated from Fortran, and partly because the Fortran was.:) It appears the code in "init" is trying to initialize the entire Arrays struct, so bolting on a union with double[totalsize] ought to work. > Removed: > test-suite/trunk/SingleSource/Benchmarks/Misc-C++/llloops.cpp > > Removed: test-suite/trunk/SingleSource/Benchmarks/Misc-C++/llloops.cpp > URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/Benchmarks/Misc-C%2B%2B/llloops.cpp?rev=60374&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- test-suite/trunk/SingleSource/Benchmarks/Misc-C++/llloops.cpp > (original) > +++ test-suite/trunk/SingleSource/Benchmarks/Misc-C++/llloops.cpp > (removed) > @@ -1,2217 +0,0 @@ > -/ > ************************************************************************ > - > * * > - * L. L. N. L. " C " K E R N E L S: M F L O P S P C V E R S I > O N * > - > * * > - * These kernels measure " C " numerical > computation * > - * rates for a spectrum of cpu-limited > computational * > - * structures or benchmarks. Mathematical through- > put * > - * is measured in units of millions of floating- > point * > - * operations executed per second, called Megaflops/ > sec. * > - > * * > - > ************************************************************************ > - * Originally from Greg Astfalk, AT&T, P.O.Box 900, > Princeton, * > - * NJ. 08540. by way of Frank McMahon > (LLNL). * > - > * * > - * Modifications by Tim Peters, Kendall Square Res. Corp. Oct > 92. * > - > * * > - * This version by Roy Longbottom (retired, ex-CCTA > UK) * > - * Roy_Longbottom > 101323.2241 at compuserve.com * > - * March > 1996 * > - > * * > - * > REFERENCE * > - > * * > - * F.H.McMahon, The Livermore Fortran > Kernels: * > - * A Computer Test Of The Numerical Performance > Range, * > - * Lawrence Livermore National > Laboratory, * > - * Livermore, California, UCRL-53745, December > 1986. * > - > * * > - * from: National Technical Information > Service * > - * U.S. Department of > Commerce * > - * 5285 Port Royal > Road * > - * Springfield, VA. > 22161 * > - > * * > - > ************************************************************************ > - * The standard "C" code accesses the FORTRAN version for > data * > - * generation and result analysis. These features have been > merged * > - * to produce a program more suitable to run on PCs. FORTRAN > features * > - * for detailed statistical analysis of the results have been > omitted. * > - > * * > - * Changes to "C" code to produce correct > results: * > - > * * > - * Kernel 2 change i = ipntp - 1; to i = > ipntp; * > - * Kernel 7 third line of inner loop change r to > q * > - > ************************************************************************ > - * > - * The kernels are executed as follows: > - * > - * parameters(x); > - * do > - * { > - * execute kernel code > - * > - * endloop(x); > - * } > - * while (count < loop); > - * > - * Function parameters obtains the loop parameters, generates all > the data > - * and makes a copy of it for use with extra loops. Timing is > started at > - * the end of the function. > - * > - * The variable loop has a defined number of passes (e.g. 7 for > kernel 1, > - * long span - see Passes in table). This is multiplied by a further > - * constant for which checksums are defined - 200/400/1600 for > long/medium > - * /short spans was chosen. The overhead of executing function > endloop is > - * calculated as below. This is deducted from the total time but > probably > - * could be ignored on PCs. > - * > - * The running time for each loop is set to a minimum of five > seconds via > - * repeating all loops until each has recorded at least 0.07 > seconds (see > - * calibration below). The extra loops required are shown under E > in the > - * tables. The data used in the loops is re-initialised from the > copy in > - * function endloop for each of the extra loops. The worst case > overhead > - * of this has been measured as less than 1% and is ignored. Note, > the > - * alternative of summing the time for each set of count passes > cannot > - * be relied upon when the time for one set is of the same order of > - * magnitude as the clock resolution (0.05 to 0.06 seconds). > Calibration > - * also gives an indication of the linearity of timing. In the > example > - * shown, the overhead of 24 occurrences of data generation, which > is > - * excluded from the main timing, is about 0.6 seconds. > - * > - * The total floating point operations for the first kernel 1 > results are > - * 200 x 7 x 15 x 5 x 1001. For some other kernels, the total is not > - * proportional to the span. > - * > - * The OK column in the tables indicates the number of correct > significant > - * digits out of 16 compared with the defined checksums. > - * > - * > - * Example of Results > - * > - * L.L.N.L. 'C' KERNELS: MFLOPS P.C. VERSION > - * > - * Calculating outer loop overhead > - * 1000 times 0.00 seconds > - * 10000 times 0.00 seconds > - * 100000 times 0.06 seconds > - * 1000000 times 0.33 seconds > - * 2000000 times 0.88 seconds > - * 4000000 times 1.59 seconds > - * 8000000 times 3.30 seconds > - * 16000000 times 6.64 seconds > - * Overhead for each loop 4.1500e-007 seconds > - * > - * Calibrating part 1 of 3 > - * > - * Loop count 4 0.94 seconds > - * Loop count 16 2.08 seconds > - * Loop count 32 3.52 seconds > - * Loop count 64 6.42 seconds > - * Loop count 128 12.31 seconds > - * > - * Loops 200 x 1 x Passes > - * > - * Kernel Floating Pt ops > - * No Passes E No Total Secs. MFLOPS Span > Checksums OK > - * ------------ -- ------------- ----- ------- ---- > ---------------------- -- > - * 1 7 x 15 5 1.051050e+008 5.10 20.60 1001 > 5.114652693224671e+004 16 > - * 2 67 x 21 4 1.091832e+008 5.20 20.98 101 > 1.539721811668384e+003 15 > - * 3 9 x 15 2 5.405400e+007 4.17 12.97 1001 > 1.000742883066364e+001 15 > - * 4 14 x 30 2 1.008000e+008 5.52 18.28 1001 > 5.999250595473891e-001 16 > - * 5 10 x 12 2 4.800000e+007 5.43 8.84 1001 > 4.548871642387267e+003 16 > - * 6 3 x 19 2 4.523520e+007 4.34 10.43 64 > 4.375116344729986e+003 16 > - * 7 4 x 10 16 1.273600e+008 4.45 28.64 995 > 6.104251075174761e+004 16 > - * 8 10 x 7 36 9.979200e+007 5.15 19.36 100 > 1.501268005625795e+005 15 > - * 9 36 x 6 17 7.417440e+007 5.20 14.26 101 > 1.189443609974981e+005 16 > - * 10 34 x 5 9 3.090600e+007 5.48 5.64 101 > 7.310369784325296e+004 16 > - * 11 11 x 15 1 3.300000e+007 5.65 5.84 1001 > 3.342910972650109e+007 16 > - * 12 12 x 30 1 7.200000e+007 6.50 11.08 1000 > 2.907141294167248e-005 16 > - * 13 36 x 4 7 1.290240e+007 6.41 2.01 64 > 1.202533961842804e+011 15 > - * 14 2 x 4 11 1.761760e+007 5.61 3.14 1001 > 3.165553044000335e+009 15 > - * 15 1 x 15 33 4.950000e+007 5.66 8.75 101 > 3.943816690352044e+004 15 > - * 16 25 x 30 10 7.950000e+007 6.14 12.95 75 > 5.650760000000000e+005 16 > - * 17 35 x 9 9 5.726700e+007 5.03 11.38 101 > 1.114641772902486e+003 16 > - * 18 2 x 11 44 9.583200e+007 5.76 16.64 100 > 1.015727037502299e+005 15 > - * 19 39 x 21 6 9.926280e+007 6.14 16.16 101 > 5.421816960147207e+002 16 > - * 20 1 x 15 26 7.800000e+007 5.93 13.16 1000 > 3.040644339351238e+007 16 > - * 21 1 x 1 2 2.525000e+007 6.37 3.96 101 > 1.597308280710200e+008 15 > - * 22 11 x 12 17 4.532880e+007 5.43 8.35 101 > 2.938604376566698e+002 15 > - * 23 8 x 12 11 1.045440e+008 5.10 20.49 100 > 3.549900501563624e+004 15 > - * 24 5 x 30 1 3.000000e+007 4.93 6.09 1001 > 5.000000000000000e+002 16 > - * > - * Maximum Rate 28.64 > - * Average Rate 12.50 > - * Geometric Mean 10.50 > - * Harmonic Mean 8.25 > - * Minimum Rate 2.01 > - * > - * Do Span 471 > - * > - * Calibrating part 2 of 3 > - * > - * Loop count 8 0.88 seconds > - * Loop count 32 1.86 seconds > - * Loop count 64 3.19 seconds > - * Loop count 128 5.77 seconds > - * Loop count 256 10.93 seconds > - * > - * Loops 200 x 2 x Passes > - * > - * Kernel Floating Pt ops > - * No Passes E No Total Secs. MFLOPS Span > Checksums OK > - * ------------ -- ------------- ----- ------- ---- > ---------------------- -- > - * 1 40 x 15 5 1.212000e+008 4.84 25.04 101 > 5.253344778937972e+002 16 > - * 2 40 x 20 4 1.241600e+008 5.91 21.02 101 > 1.539721811668384e+003 15 > - * 3 53 x 20 2 8.564800e+007 5.10 16.78 101 > 1.009741436578952e+000 16 > - * 4 70 x 32 2 1.075200e+008 4.29 25.07 101 > 5.999250595473891e-001 16 > - * 5 55 x 13 2 5.720000e+007 4.99 11.46 101 > 4.589031939600982e+001 16 > - * 6 7 x 19 2 5.107200e+007 4.70 10.87 32 > 8.631675645333210e+001 16 > - * 7 22 x 12 16 1.706496e+008 5.56 30.71 101 > 6.345586315784055e+002 16 > - * 8 6 x 6 36 1.026432e+008 5.26 19.50 100 > 1.501268005625795e+005 15 > - * 9 21 x 5 17 7.211400e+007 5.03 14.33 101 > 1.189443609974981e+005 16 > - * 10 19 x 5 9 3.454200e+007 6.13 5.63 101 > 7.310369784325296e+004 16 > - * 11 64 x 20 1 5.120000e+007 4.95 10.35 101 > 3.433560407475758e+004 16 > - * 12 68 x 20 1 5.440000e+007 5.16 10.53 100 > 7.127569130821465e-006 16 > - * 13 41 x 3 7 1.102080e+007 5.47 2.01 32 > 9.816387810944356e+010 15 > - * 14 10 x 4 11 1.777600e+007 5.49 3.24 101 > 3.039983465145392e+007 15 > - * 15 1 x 7 33 4.620000e+007 5.32 8.69 101 > 3.943816690352044e+004 15 > - * 16 27 x 21 10 6.350400e+007 5.02 12.66 40 > 6.480410000000000e+005 16 > - * 17 20 x 9 9 6.544800e+007 5.74 11.40 101 > 1.114641772902486e+003 16 > - * 18 1 x 10 44 8.712000e+007 5.22 16.69 100 > 1.015727037502299e+005 15 > - * 19 23 x 15 6 8.362800e+007 5.11 16.36 101 > 5.421816960147207e+002 16 > - * 20 8 x 9 26 7.488000e+007 5.43 13.80 100 > 3.126205178815432e+004 16 > - * 21 1 x 2 2 5.000000e+007 5.55 9.01 50 > 7.824524877232093e+007 16 > - * 22 7 x 9 17 4.326840e+007 5.21 8.31 101 > 2.938604376566698e+002 15 > - * 23 5 x 9 11 9.801000e+007 4.77 20.54 100 > 3.549900501563624e+004 15 > - * 24 31 x 30 1 3.720000e+007 6.06 6.14 101 > 5.000000000000000e+001 16 > - * > - * Maximum Rate 30.71 > - * Average Rate 13.76 > - * Geometric Mean 11.69 > - * Harmonic Mean 9.19 > - * Minimum Rate 2.01 > - * > - * Do Span 90 > - * > - * Calibrating part 3 of 3 > - * > - * Loop count 32 0.77 seconds > - * Loop count 128 1.54 seconds > - * Loop count 256 2.47 seconds > - * Loop count 512 4.34 seconds > - * Loop count 1024 8.13 seconds > - * > - * Loops 200 x 8 x Passes > - * > - * Kernel Floating Pt ops > - * No Passes E No Total Secs. MFLOPS Span > Checksums OK > - * ------------ -- ------------- ----- ------- ---- > ---------------------- -- > - * 1 28 x 22 5 1.330560e+008 5.31 25.05 27 > 3.855104502494961e+001 16 > - * 2 46 x 22 4 7.124480e+007 4.38 16.27 15 > 3.953296986903060e+001 16 > - * 3 37 x 23 2 7.352640e+007 4.26 17.24 27 > 2.699309089320672e-001 16 > - * 4 38 x 35 2 6.384000e+007 3.79 16.86 27 > 5.999250595473891e-001 16 > - * 5 40 x 23 2 7.654400e+007 4.45 17.20 27 > 3.182615248447483e+000 16 > - * 6 21 x 32 2 5.160960e+007 4.82 10.70 8 > 1.120309393467088e+000 15 > - * 7 20 x 12 16 1.290240e+008 4.24 30.43 21 > 2.845720217644024e+001 16 > - * 8 9 x 8 36 1.078272e+008 5.17 20.85 14 > 2.960543667875005e+003 15 > - * 9 26 x 16 17 1.697280e+008 5.33 31.82 15 > 2.623968460874250e+003 16 > - * 10 25 x 11 9 5.940000e+007 5.42 10.96 15 > 1.651291227698265e+003 16 > - * 11 46 x 22 1 4.209920e+007 3.67 11.48 27 > 6.551161335845770e+002 16 > - * 12 48 x 23 1 4.592640e+007 5.04 9.12 26 > 1.943435981130448e-006 16 > - * 13 31 x 4 7 1.111040e+007 5.57 2.00 8 > 3.847124199949431e+010 15 > - * 14 8 x 6 11 2.280960e+007 5.19 4.40 27 > 2.923540598672009e+006 15 > - * 15 1 x 15 33 5.544000e+007 6.14 9.03 15 > 1.108997288134785e+003 16 > - * 16 14 x 31 10 7.638400e+007 5.80 13.17 15 > 5.152160000000000e+005 16 > - * 17 26 x 11 9 6.177600e+007 5.14 12.02 15 > 2.947368618589360e+001 16 > - * 18 2 x 12 44 1.098240e+008 5.36 20.47 14 > 9.700646212337040e+002 16 > - * 19 28 x 21 6 8.467200e+007 5.38 15.74 15 > 1.268230698051004e+001 15 > - * 20 7 x 10 26 7.571200e+007 5.27 14.36 26 > 5.987713249475302e+002 16 > - * 21 1 x 2 2 8.000000e+007 5.50 14.55 20 > 5.009945671204667e+007 16 > - * 22 8 x 13 17 4.243200e+007 5.04 8.42 15 > 6.109968728263973e+000 16 > - * 23 7 x 15 11 1.201200e+008 4.38 27.42 14 > 4.850340602749970e+002 16 > - * 24 23 x 32 1 3.061760e+007 5.01 6.11 27 > 1.300000000000000e+001 16 > - * > - * Maximum Rate 31.82 > - * Average Rate 15.24 > - * Geometric Mean 13.06 > - * Harmonic Mean 10.26 > - * Minimum Rate 2.00 > - * > - * Do Span 19 > - * > - * Overall > - * > - * Part 1 weight 1 > - * Part 2 weight 2 > - * Part 3 weight 1 > - * > - * Maximum Rate 31.82 > - * Average Rate 13.81 > - * Geometric Mean 11.70 > - * Harmonic Mean 9.17 > - * Minimum Rate 2.00 > - * > - * Do Span 167 > - * > - * Enter the following data which will be filed with the results > - * > - * Month run 9/1996 > - * PC model Escom > - * CPU Pentium > - * Clock MHz 100 > - * Cache 256K > - * Options Neptune chipset > - * OS/DOS Windows 95 > - * Compiler Watcom C/C++ Version 10.5 > - * OptLevel Win386 -zp4 -otexan -om -fp5 -zc -5r > - * Run by Roy Longbottom > - * From UK > - * Mail 101323.2241 at compuserve.com > - * > - * Note: the date, compiler and opt level are inserted by the > program. > - * > - * The tables of results and running details are appended to file > - * LLloops.txt. > - * > - * When a single MFLOPS rating is claimed for this benchmark it is > - * usually the overall geometric mean result. > - * > - > ********************************************************************** > - * > - * Pre-compiled codes were produced via a Watcom C/C++ 10.5 > compiler. > - * Versions are available for DOS, Windows 3/95 and NT/Win 95. Both > - * non-optimised and optimised programs are available. The latter > have > - * options as in the above example. > - * > - * In this source code, function prototypes are declared and > function > - * headers have embedded parameter types to produce code for C and > C++ > - * at least suitable for compiling as such with the Watcom compiler. > - * > - > *********************************************************************** > - */ > - > -#include > -#include > -#include > - > - > - struct Arrays > - { > - double U[1001]; > - double V[1001]; > - double W[1001]; > - double X[1001]; > - double Y[1001]; > - double Z[1001]; > - double G[1001]; > - double Du1[101]; > - double Du2[101]; > - double Du3[101]; > - double Grd[1001]; > - double Dex[1001]; > - double Xi[1001]; > - double Ex[1001]; > - double Ex1[1001]; > - double Dex1[1001]; > - double Vx[1001]; > - double Xx[1001]; > - double Rx[1001]; > - double Rh[2048]; > - double Vsp[101]; > - double Vstp[101]; > - double Vxne[101]; > - double Vxnd[101]; > - double Ve3[101]; > - double Vlr[101]; > - double Vlin[101]; > - double B5[101]; > - double Plan[300]; > - double D[300]; > - double Sa[101]; > - double Sb[101]; > - double P[512][4]; > - double Px[101][25]; > - double Cx[101][25]; > - double Vy[25][101]; > - double Vh[7][101]; > - double Vf[7][101]; > - double Vg[7][101]; > - double Vs[7][101]; > - double Za[7][101]; > - double Zp[7][101]; > - double Zq[7][101]; > - double Zr[7][101]; > - double Zm[7][101]; > - double Zb[7][101]; > - double Zu[7][101]; > - double Zv[7][101]; > - double Zz[7][101]; > - double B[64][64]; > - double C[64][64]; > - double H[64][64]; > - double U1[2][101][5]; > - double U2[2][101][5]; > - double U3[2][101][5]; > - double Xtra[40]; > - long E[96]; > - long F[96]; > - long Ix[1001]; > - long Ir[1001]; > - long Zone[301]; > - double X0[1001]; > - double W0[1001]; > - double Px0[101][25]; > - double P0[512][4]; > - double H0[64][64]; > - double Rh0[2048]; > - double Vxne0[101]; > - double Zr0[7][101]; > - double Zu0[7][101]; > - double Zv0[7][101]; > - double Zz0[7][101]; > - double Za0[101][25]; > - double Stb50; > - double Xx0; > - > - > - }as1; > - #define u as1.U > - #define v as1.V > - #define w as1.W > - #define x as1.X > - #define y as1.Y > - #define z as1.Z > - #define g as1.G > - #define du1 as1.Du1 > - #define du2 as1.Du2 > - #define du3 as1.Du3 > - #define grd as1.Grd > - #define dex as1.Dex > - #define xi as1.Xi > - #define ex as1.Ex > - #define ex1 as1.Ex1 > - #define dex1 as1.Dex1 > - #define vx as1.Vx > - #define xx as1.Xx > - #define rx as1.Rx > - #define rh as1.Rh > - #define vsp as1.Vsp > - #define vstp as1.Vstp > - #define vxne as1.Vxne > - #define vxnd as1.Vxnd > - #define ve3 as1.Ve3 > - #define vlr as1.Vlr > - #define vlin as1.Vlin > - #define b5 as1.B5 > - #define plan as1.Plan > - #define d as1.D > - #define sa as1.Sa > - #define sb as1.Sb > - #define p as1.P > - #define px as1.Px > - #define cx as1.Cx > - #define vy as1.Vy > - #define vh as1.Vh > - #define vf as1.Vf > - #define vg as1.Vg > - #define vs as1.Vs > - #define za as1.Za > - #define zb as1.Zb > - #define zp as1.Zp > - #define zq as1.Zq > - #define zr as1.Zr > - #define zm as1.Zm > - #define zz as1.Zz > - #define zu as1.Zu > - #define zv as1.Zv > - #define b as1.B > - #define c as1.C > - #define h as1.H > - #define u1 as1.U1 > - #define u2 as1.U2 > - #define u3 as1.U3 > - #define xtra as1.Xtra > - #define a11 as1.Xtra[1] > - #define a12 as1.Xtra[2] > - #define a13 as1.Xtra[3] > - #define a21 as1.Xtra[4] > - #define a22 as1.Xtra[5] > - #define a23 as1.Xtra[6] > - #define a31 as1.Xtra[7] > - #define a32 as1.Xtra[8] > - #define a33 as1.Xtra[9] > - #define c0 as1.Xtra[12] > - #define dk as1.Xtra[15] > - #define dm22 as1.Xtra[16] > - #define dm23 as1.Xtra[17] > - #define dm24 as1.Xtra[18] > - #define dm25 as1.Xtra[19] > - #define dm26 as1.Xtra[20] > - #define dm27 as1.Xtra[21] > - #define dm28 as1.Xtra[22] > - #define expmax as1.Xtra[26] > - #define flx as1.Xtra[27] > - #define q as1.Xtra[28] > - #define r as1.Xtra[30] > - #define s as1.Xtra[32] > - #define sig as1.Xtra[34] > - #define stb5 as1.Xtra[35] > - #define t as1.Xtra[36] > - #define xnm as1.Xtra[39] > - #define e as1.E > - #define f as1.F > - #define ix as1.Ix > - #define ir as1.Ir > - #define zone as1.Zone > - #define x0 as1.X0 > - #define w0 as1.W0 > - #define px0 as1.Px0 > - #define p0 as1.P0 > - #define h0 as1.H0 > - #define rh0 as1.Rh0 > - #define vxne0 as1.Vxne0 > - #define zr0 as1.Zr0 > - #define zu0 as1.Zu0 > - #define zv0 as1.Zv0 > - #define zz0 as1.Zz0 > - #define za0 as1.Za0 > - #define stb50 as1.Stb50 > - #define xx0 as1.Xx0 > - > - > - struct Parameters > - { > - long Inner_loops; > - long Outer_loops; > - long Loop_mult; > - double Flops_per_loop; > - double Sumcheck[3][25]; > - long Accuracy[3][25]; > - double LoopTime[3][25]; > - double LoopSpeed[3][25]; > - double LoopFlos[3][25]; > - long Xflops[25]; > - long Xloops[3][25]; > - long Nspan[3][25]; > - double TimeStart; > - double TimeEnd; > - double Loopohead; > - long Count; > - long Count2; > - long Pass; > - long Extra_loops[3][25]; > - long K2; > - long K3; > - long M16; > - long J5; > - long Section; > - long N16; > - double Mastersum; > - long M24; > - > - > - }as2; > - > - #define n as2.Inner_loops > - #define loop as2.Outer_loops > - #define mult as2.Loop_mult > - #define nflops as2.Flops_per_loop > - #define Checksum as2.Sumcheck > - #define accuracy as2.Accuracy > - #define RunTime as2.LoopTime > - #define Mflops as2.LoopSpeed > - #define FPops as2.LoopFlos > - #define nspan as2.Nspan > - #define xflops as2.Xflops > - #define xloops as2.Xloops > - #define StartTime as2.TimeStart > - #define EndTime as2.TimeEnd > - #define overhead_l as2.Loopohead > - #define count as2.Count > - #define count2 as2.Count2 > - #define pass as2.Pass > - #define extra_loops as2.Extra_loops > - #define k2 as2.K2 > - #define k3 as2.K3 > - #define m16 as2.M16 > - #define j5 as2.J5 > - #define section as2.Section > - #define n16 as2.N16 > - #define MasterSum as2.Mastersum > - #define m24 as2.M24 > - > - > - void init(long which); > - > - /* Initialises arrays and variables */ > - > - long endloop(long which); > - > - /* Controls outer loops and stores results */ > - > - long parameters(long which); > - > - /* Gets loop parameters and variables, starts timer */ > - > - void kernels(); > - > - /* The 24 kernels */ > - > - void check(long which); > - > - /* Calculates checksum accuracy */ > - > - void iqranf(); > - > - /* Random number generator for Kernel 14 */ > - > -main(int argc, char *argv[]) > -{ > - double pass_time, least, lmult, now = 1.0, wt; > - double time1, time2; > - long i, k, loop_passes; > - long mul[3] = {1, 2, 8}; > - double weight[3] = {1.0, 2.0, 1.0}; > - long Endit, which; > - double maximum[4]; > - double minimum[4]; > - double average[4]; > - double harmonic[4]; > - double geometric[4]; > - long xspan[4]; > - char general[9][80] = {" "}; > - FILE *outfile; > - int getinput = 1; > - > - if (argc > 1) > - { > - switch (argv[1][0]) > - { > - case 'N': > - getinput = 0; > - break; > - case 'n': > - getinput = 0; > - break; > - } > - } > - > - > - printf ("L.L.N.L. 'C' KERNELS: MFLOPS P.C. VERSION 4.0\n\n"); > - > - if (getinput == 0) > - { > - printf ("***** No run time input data *****\n\n"); > - } > - else > - { > - printf ("*** With run time input data ***\n\n"); > - } > - > -/ > ************************************************************************ > - * Execute the kernels three times at different Do > Spans * > - > ************************************************************************/ > - > - for ( section=0 ; section<3 ; section++ ) > - { > - loop_passes = 200 * mul[section]; > - pass = -20; > - mult = 2 * mul[section]; > - > - for ( i=1; i<25; i++) > - { > - extra_loops[section][i] = 500; > - } > - > -/ > ************************************************************************ > - * Execute the > kernels * > - > ************************************************************************/ > - > - kernels(); > - > - maximum[section] = 0.0; > - minimum[section] = Mflops[section][1]; > - average[section] = 0.0; > - harmonic[section] = 0.0; > - geometric[section] = 0.0; > - xspan[section] = 0.0; > - } > - > -/ > ************************************************************************ > - * End of executing the kernels three times at different Do > Spans * > - > ************************************************************************/ > -} > - > -/ > ************************************************************************ > - * The > Kernels * > - > ************************************************************************/ > - > -void kernels() > - { > - > - long lw; > - long ipnt, ipntp, ii; > - double temp; > - long nl1, nl2; > - long kx, ky; > - double ar, br, cr; > - long i, j, k, m; > - long ip, i1, i2, j1, j2, j4, lb; > - long ng, nz; > - double tmp; > - double scale, xnei, xnc, e3,e6; > - long ink, jn, kn, kb5i; > - double di, dn; > - double qa; > - > - for ( k=0 ; k<25; k++) > - { > - Checksum[section][k] = 0.0; > - } > - > - > - > - /* > - > ******************************************************************* > - * Kernel 1 -- hydro fragment > - > ******************************************************************* > - */ > - > - parameters (1); > - > - do > - { > - for ( k=0 ; k - { > - x[k] = q + y[k]*( r*z[k+10] + t*z[k+11] ); > - } > - > - endloop (1); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 2 -- ICCG excerpt (Incomplete Cholesky Conjugate > Gradient) > - > ******************************************************************* > - */ > - > - parameters (2); > - > - do > - { > - ii = n; > - ipntp = 0; > - do > - { > - ipnt = ipntp; > - ipntp += ii; > - ii /= 2; > - i = ipntp; > - for ( k=ipnt+1 ; k - { > - i++; > - x[i] = x[k] - v[k]*x[k-1] - v[k+1]*x[k+1]; > - } > - } while ( ii>0 ); > - > - endloop (2); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 3 -- inner product > - > ******************************************************************* > - */ > - > - parameters (3); > - > - do > - { > - q = 0.0; > - for ( k=0 ; k - { > - q += z[k]*x[k]; > - } > - > - endloop (3); > - } > - while (count < loop); > - > - > - /* > - > ******************************************************************* > - * Kernel 4 -- banded linear equations > - > ******************************************************************* > - */ > - > - parameters (4); > - > - m = ( 1001-7 )/2; > - do > - { > - for ( k=6 ; k<1001 ; k=k+m ) > - { > - lw = k - 6; > - temp = x[k-1]; > - > - for ( j=4 ; j - { > - temp -= x[lw]*y[j]; > - lw++; > - } > - x[k-1] = y[4]*temp; > - } > - > - endloop (4); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 5 -- tri-diagonal elimination, below diagonal > - > ******************************************************************* > - */ > - > - parameters (5); > - > - do > - { > - for ( i=1 ; i - { > - x[i] = z[i]*( y[i] - x[i-1] ); > - } > - > - endloop (5); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 6 -- general linear recurrence equations > - > ******************************************************************* > - */ > - > - parameters (6); > - > - > - do > - { > - for ( i=1 ; i - { > - w[i] = 0.01; > - for ( k=0 ; k - { > - w[i] += b[k][i] * w[(i-k)-1]; > - } > - } > - > - endloop (6); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 7 -- equation of state fragment > - > ******************************************************************* > - */ > - > - parameters (7); > - > - do > - { > - > - for ( k=0 ; k - { > - x[k] = u[k] + r*( z[k] + r*y[k] ) + > - t*( u[k+3] + r*( u[k+2] + r*u[k+1] ) + > - t*( u[k+6] + q*( u[k+5] + q*u[k+4] ) ) ); > - } > - > - endloop (7); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 8 -- ADI integration > - > ******************************************************************* > - */ > - > - nl1 = 0; > - nl2 = 1; > - > - parameters (8); > - > - do > - { > - for ( kx=1 ; kx<3 ; kx++ ) > - { > - > - for ( ky=1 ; ky - { > - du1[ky] = u1[nl1][ky+1][kx] - u1[nl1][ky-1][kx]; > - du2[ky] = u2[nl1][ky+1][kx] - u2[nl1][ky-1][kx]; > - du3[ky] = u3[nl1][ky+1][kx] - u3[nl1][ky-1][kx]; > - u1[nl2][ky][kx]= > - u1[nl1][ky][kx]+a11*du1[ky]+a12*du2[ky] > +a13*du3[ky] + sig* > - (u1[nl1][ky][kx+1]-2.0*u1[nl1][ky][kx]+u1[nl1][ky] > [kx-1]); > - u2[nl2][ky][kx]= > - u2[nl1][ky][kx]+a21*du1[ky]+a22*du2[ky] > +a23*du3[ky] + sig* > - (u2[nl1][ky][kx+1]-2.0*u2[nl1][ky][kx]+u2[nl1][ky] > [kx-1]); > - u3[nl2][ky][kx]= > - u3[nl1][ky][kx]+a31*du1[ky]+a32*du2[ky] > +a33*du3[ky] + sig* > - (u3[nl1][ky][kx+1]-2.0*u3[nl1][ky][kx]+u3[nl1][ky] > [kx-1]); > - } > - } > - > - endloop (8); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 9 -- integrate predictors > - > ******************************************************************* > - */ > - > - parameters (9); > - > - do > - { > - for ( i=0 ; i - { > - px[i][0] = dm28*px[i][12] + dm27*px[i][11] + dm26*px[i] > [10] + > - dm25*px[i][ 9] + dm24*px[i][ 8] + dm23*px[i] > [ 7] + > - dm22*px[i][ 6] + c0*( px[i][ 4] + px[i][ 5]) > - + px[i][ 2]; > - } > - > - endloop (9); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 10 -- difference predictors > - > ******************************************************************* > - */ > - > - parameters (10); > - > - do > - { > - for ( i=0 ; i - { > - ar = cx[i][ 4]; > - br = ar - px[i][ 4]; > - px[i][ 4] = ar; > - cr = br - px[i][ 5]; > - px[i][ 5] = br; > - ar = cr - px[i][ 6]; > - px[i][ 6] = cr; > - br = ar - px[i][ 7]; > - px[i][ 7] = ar; > - cr = br - px[i][ 8]; > - px[i][ 8] = br; > - ar = cr - px[i][ 9]; > - px[i][ 9] = cr; > - br = ar - px[i][10]; > - px[i][10] = ar; > - cr = br - px[i][11]; > - px[i][11] = br; > - px[i][13] = cr - px[i][12]; > - px[i][12] = cr; > - } > - > - endloop (10); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 11 -- first sum > - > ******************************************************************* > - */ > - > - parameters (11); > - > - do > - { > - x[0] = y[0]; > - for ( k=1 ; k - { > - x[k] = x[k-1] + y[k]; > - } > - > - endloop (11); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 12 -- first difference > - > ******************************************************************* > - */ > - > - parameters (12); > - > - do > - { > - for ( k=0 ; k - { > - x[k] = y[k+1] - y[k]; > - } > - > - endloop (12); > - } > - while (count < loop); > - > - > - /* > - > ******************************************************************* > - * Kernel 13 -- 2-D PIC (Particle In Cell) > - > ******************************************************************* > - */ > - > - parameters (13); > - > - do > - { > - for ( ip=0; ip - { > - i1 = p[ip][0]; > - j1 = p[ip][1]; > - i1 &= 64-1; > - j1 &= 64-1; > - p[ip][2] += b[j1][i1]; > - p[ip][3] += c[j1][i1]; > - p[ip][0] += p[ip][2]; > - p[ip][1] += p[ip][3]; > - i2 = p[ip][0]; > - j2 = p[ip][1]; > - i2 = ( i2 & 64-1 ) - 1 ; > - j2 = ( j2 & 64-1 ) - 1 ; > - p[ip][0] += y[i2+32]; > - p[ip][1] += z[j2+32]; > - i2 += e[i2+32]; > - j2 += f[j2+32]; > - h[j2][i2] += 1.0; > - } > - endloop (13); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 14 -- 1-D PIC (Particle In Cell) > - > ******************************************************************* > - */ > - > - parameters (14); > - > - do > - { > - for ( k=0 ; k - { > - vx[k] = 0.0; > - xx[k] = 0.0; > - ix[k] = (long) grd[k]; > - xi[k] = (double) ix[k]; > - ex1[k] = ex[ ix[k] - 1 ]; > - dex1[k] = dex[ ix[k] - 1 ]; > - } > - for ( k=0 ; k - { > - vx[k] = vx[k] + ex1[k] + ( xx[k] - xi[k] )*dex1[k]; > - xx[k] = xx[k] + vx[k] + flx; > - ir[k] = xx[k]; > - rx[k] = xx[k] - ir[k]; > - ir[k] = ( ir[k] & 2048-1 ) + 1; > - xx[k] = rx[k] + ir[k]; > - } > - for ( k=0 ; k - { > - rh[ ir[k]-1 ] += 1.0 - rx[k]; > - rh[ ir[k] ] += rx[k]; > - } > - endloop (14); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 15 -- Casual Fortran. Development version > - > ******************************************************************* > - */ > - > - parameters (15); > - > - do > - { > - ng = 7; > - nz = n; > - ar = 0.053; > - br = 0.073; > - for ( j=1 ; j - { > - for ( k=1 ; k - { > - if ( (j+1) >= ng ) > - { > - vy[j][k] = 0.0; > - continue; > - } > - if ( vh[j+1][k] > vh[j][k] ) > - { > - t = ar; > - } > - else > - { > - t = br; > - } > - if ( vf[j][k] < vf[j][k-1] ) > - { > - if ( vh[j][k-1] > vh[j+1][k-1] ) > - r = vh[j][k-1]; > - else > - r = vh[j+1][k-1]; > - s = vf[j][k-1]; > - } > - else > - { > - if ( vh[j][k] > vh[j+1][k] ) > - r = vh[j][k]; > - else > - r = vh[j+1][k]; > - s = vf[j][k]; > - } > - vy[j][k] = sqrt( vg[j][k]*vg[j][k] + r*r )* t/s; > - if ( (k+1) >= nz ) > - { > - vs[j][k] = 0.0; > - continue; > - } > - if ( vf[j][k] < vf[j-1][k] ) > - { > - if ( vg[j-1][k] > vg[j-1][k+1] ) > - r = vg[j-1][k]; > - else > - r = vg[j-1][k+1]; > - s = vf[j-1][k]; > - t = br; > - } > - else > - { > - if ( vg[j][k] > vg[j][k+1] ) > - r = vg[j][k]; > - else > - r = vg[j][k+1]; > - s = vf[j][k]; > - t = ar; > - } > - vs[j][k] = sqrt( vh[j][k]*vh[j][k] + r*r )* t / s; > - } > - } > - endloop (15); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 16 -- Monte Carlo search loop > - > ******************************************************************* > - */ > - > - parameters (16); > - > - > - ii = n / 3; > - lb = ii + ii; > - k3 = k2 = 0; > - do > - { > - i1 = m16 = 1; > - label410: > - j2 = ( n + n )*( m16 - 1 ) + 1; > - for ( k=1 ; k<=n ; k++ ) > - { > - k2++; > - j4 = j2 + k + k; > - j5 = zone[j4-1]; > - if ( j5 < n ) > - { > - if ( j5+lb < n ) > - { /* 420 */ > - tmp = plan[j5-1] - t; /* 435 */ > - } > - else > - { > - if ( j5+ii < n ) > - { /* 415 */ > - tmp = plan[j5-1] - s; /* 430 */ > - } > - else > - { > - tmp = plan[j5-1] - r; /* 425 */ > - } > - } > - } > - else if( j5 == n ) > - { > - break; /* 475 */ > - } > - else > - { > - k3++; /* 450 */ > - tmp=(d[j5-1]-(d[j5-2]*(t-d[j5-3])*(t-d[j5-3])+(s- > d[j5-4])* > - (s-d[j5-4])+(r-d[j5-5])*(r-d[j5-5]))); > - } > - if ( tmp < 0.0 ) > - { > - if ( zone[j4-2] < 0 ) /* 445 */ > - continue; /* 470 */ > - else if ( !zone[j4-2] ) > - break; /* 480 */ > - } > - else if ( tmp ) > - { > - if ( zone[j4-2] > 0 ) /* 440 */ > - continue; /* 470 */ > - else if ( !zone[j4-2] ) > - break; /* 480 */ > - } > - else break; /* 485 */ > - m16++; /* 455 */ > - if ( m16 > zone[0] ) > - m16 = 1; /* 460 */ > - if ( i1-m16 ) /* 465 */ > - goto label410; > - else > - break; > - } > - endloop (16); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 17 -- implicit, conditional computation > - > ******************************************************************* > - */ > - > - parameters (17); > - > - do > - { > - i = n-1; > - j = 0; > - ink = -1; > - scale = 5.0 / 3.0; > - xnm = 1.0 / 3.0; > - e6 = 1.03 / 3.07; > - goto l61; > -l60: e6 = xnm*vsp[i] + vstp[i]; > - vxne[i] = e6; > - xnm = e6; > - ve3[i] = e6; > - i += ink; > - if ( i==j ) goto l62; > -l61: e3 = xnm*vlr[i] + vlin[i]; > - xnei = vxne[i]; > - vxnd[i] = e6; > - xnc = scale*e3; > - if ( xnm > xnc ) goto l60; > - if ( xnei > xnc ) goto l60; > - ve3[i] = e3; > - e6 = e3 + e3 - xnm; > - vxne[i] = e3 + e3 - xnei; > - xnm = e6; > - i += ink; > - if ( i != j ) goto l61; > -l62:; > - endloop (17); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 18 - 2-D explicit hydrodynamics fragment > - > ******************************************************************* > - */ > - > - parameters (18); > - > - do > - { > - t = 0.0037; > - s = 0.0041; > - kn = 6; > - jn = n; > - for ( k=1 ; k - { > - > - for ( j=1 ; j - { > - za[k][j] = ( zp[k+1][j-1] +zq[k+1][j-1] -zp[k][j-1] - > zq[k][j-1] )* > - ( zr[k][j] +zr[k][j-1] ) / ( zm[k][j-1] +zm[k > +1][j-1]); > - zb[k][j] = ( zp[k][j-1] +zq[k][j-1] -zp[k][j] -zq[k] > [j] ) * > - ( zr[k][j] +zr[k-1][j] ) / ( zm[k][j] +zm[k] > [j-1]); > - } > - } > - for ( k=1 ; k - { > - > - for ( j=1 ; j - { > - zu[k][j] += s*( za[k][j] *( zz[k][j] - zz[k][j > +1] ) - > - za[k][j-1] *( zz[k][j] - zz[k] > [j-1] ) - > - zb[k][j] *( zz[k][j] - zz[k-1] > [j] ) + > - zb[k+1][j] *( zz[k][j] - zz[k+1] > [j] ) ); > - zv[k][j] += s*( za[k][j] *( zr[k][j] - zr[k][j > +1] ) - > - za[k][j-1] *( zr[k][j] - zr[k] > [j-1] ) - > - zb[k][j] *( zr[k][j] - zr[k-1] > [j] ) + > - zb[k+1][j] *( zr[k][j] - zr[k+1] > [j] ) ); > - } > - } > - for ( k=1 ; k - { > - > - for ( j=1 ; j - { > - zr[k][j] = zr[k][j] + t*zu[k][j]; > - zz[k][j] = zz[k][j] + t*zv[k][j]; > - } > - } > - endloop (18); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 19 -- general linear recurrence equations > - > ******************************************************************* > - */ > - > - parameters (19); > - > - kb5i = 0; > - > - do > - { > - for ( k=0 ; k - { > - b5[k+kb5i] = sa[k] + stb5*sb[k]; > - stb5 = b5[k+kb5i] - stb5; > - } > - for ( i=1 ; i<=n ; i++ ) > - { > - k = n - i; > - b5[k+kb5i] = sa[k] + stb5*sb[k]; > - stb5 = b5[k+kb5i] - stb5; > - } > - endloop (19); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 20 - Discrete ordinates transport, conditional > recurrence on xx > - > ******************************************************************* > - */ > - > - parameters (20); > - > - do > - { > - for ( k=0 ; k - { > - di = y[k] - g[k] / ( xx[k] + dk ); > - dn = 0.2; > - if ( di ) > - { > - dn = z[k]/di ; > - if ( t < dn ) dn = t; > - if ( s > dn ) dn = s; > - } > - x[k] = ( ( w[k] + v[k]*dn )* xx[k] + u[k] ) / ( vx[k] + > v[k]*dn ); > - xx[k+1] = ( x[k] - xx[k] )* dn + xx[k]; > - } > - endloop (20); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 21 -- matrix*matrix product > - > ******************************************************************* > - */ > - > - parameters (21); > - > - do > - { > - for ( k=0 ; k<25 ; k++ ) > - { > - for ( i=0 ; i<25 ; i++ ) > - { > - for ( j=0 ; j - { > - px[j][i] += vy[k][i] * cx[j][k]; > - } > - } > - } > - endloop (21); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 22 -- Planckian distribution > - > ******************************************************************* > - */ > - > - parameters (22); > - > - expmax = 20.0; > - u[n-1] = 0.99*expmax*v[n-1]; > - do > - { > - for ( k=0 ; k - { > - y[k] = u[k] / v[k]; > - w[k] = x[k] / ( exp( y[k] ) -1.0 ); > - } > - endloop (22); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 23 -- 2-D implicit hydrodynamics fragment > - > ******************************************************************* > - */ > - > - parameters (23); > - > - do > - { > - for ( j=1 ; j<6 ; j++ ) > - { > - for ( k=1 ; k - { > - qa = za[j+1][k]*zr[j][k] + za[j-1][k]*zb[j][k] + > - za[j][k+1]*zu[j][k] + za[j][k-1]*zv[j][k] + > zz[j][k]; > - za[j][k] += 0.175*( qa - za[j][k] ); > - } > - } > - endloop (23); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 24 -- find location of first minimum in array > - > ******************************************************************* > - */ > - > - parameters (24); > - > - x[n/2] = -1.0e+10; > - do > - { > - m24 = 0; > - for ( k=1 ; k - { > - if ( x[k] < x[m24] ) m24 = k; > - } > - endloop (24); > - } > - while (count < loop); > - > - return; > - } > - > -/ > ************************************************************************ > - * endloop procedure - calculate checksums and > MFLOPS * > - > ************************************************************************/ > - > -long endloop(long which) > -{ > - double now = 1.0, useflops; > - long i, j, k, m; > - double Scale = 1000000.0; > - > - count = count + 1; > - if (count >= loop) /* else return */ > - { > - > -/ > ************************************************************************ > - * End of standard set of loops for one > kernel * > - > ************************************************************************/ > - > - count2 = count2 + 1; > - if (count2 == extra_loops[section][which]) > - /* else re-initialise parameters if > required */ > - { > - > -/ > ************************************************************************ > - * End of extra loops for 5 seconds execution > time * > - > ************************************************************************/ > - > - count2 = 0; > - if (which == 1) > - { > - for ( k=0 ; k - { > - Checksum[section][1] = Checksum[section][1] + x[k] > - * (double)(k+1); > - } > - useflops = nflops * (double)(n * loop); > - } > - if (which == 2) > - { > - for ( k=0 ; k - { > - Checksum[section][2] = Checksum[section][2] + x[k] > - * (double)(k+1); > - } > - useflops = nflops * (double)((n-4) * loop); > - } > - if (which == 3) > - { > - Checksum[section][3] = q; > - useflops = nflops * (double)(n * loop); > - } > - if (which == 4) > - { > - for ( k=0 ; k<3 ; k++ ) > - { > - Checksum[section][4] = Checksum[section][4] + v[k] > - * (double)(k+1); > - } > - useflops = nflops * (double) ((((n-5)/5)+1) * 3 * loop); > - } > - if (which == 5) > - { > - for ( k=1 ; k - { > - Checksum[section][5] = Checksum[section][5] + x[k] > - * (double)(k); > - } > - useflops = nflops * (double)((n-1) * loop); > - } > - if (which == 6) > - { > - for ( k=0 ; k - { > - > - Checksum[section][6] = Checksum[section][6] + w[k] > - * (double)(k+1); > - > - } > - useflops = nflops * (double)(n * ((n - 1) / 2) * loop); > - } > - if (which == 7) > - { > - for ( k=0 ; k - { > - Checksum[section][7] = Checksum[section][7] + x[k] > - * (double)(k+1); > - } > - useflops = nflops * (double)(n * loop); > - } > - if (which == 8) > - { > - for ( i=0 ; i<2 ; i++ ) > - { > - for ( j=0 ; j<101 ; j++ ) > - { > - for ( k=0 ; k<5 ; k++ ) > - { > - m = 101 * 5 * i + 5 * j + k + 1; > - if (m < 10 * n + 1) > - { > - Checksum[section][8] = Checksum[section][8] > - + u1[i][j][k] * m > - + u2[i][j][k] * m + u3[i][j][k] * > m; > - } > - } > - } > - } > - useflops = nflops * (double)(2 * (n - 1) * loop); > - } > - if (which == 9) > - { > - for ( i=0 ; i - { > - for ( j=0 ; j<25 ; j++ ) > - { > - m = 25 * i + j + 1; > - if (m < 15 * n + 1) > - { > - Checksum[section][9] = Checksum[section][9] > - + px[i][j] * (double) > (m); > - } > - } > - } > - useflops = nflops * (double)(n * loop); > - } > - if (which == 10) > - { > - for ( i=0 ; i - { > - for (j=0 ; j<25 ; j++ ) > - { > - m = 25 * i + j + 1; > - if (m < 15 * n + 1) > - { > - Checksum[section][10] = Checksum[section][10] > - + px[i][j] * (double) > (m); > - } > - } > - } > - useflops = nflops * (double)(n * loop); > - } > - if (which == 11) > - { > - for ( k=1 ; k - { > - Checksum[section][11] = Checksum[section][11] > - + x[k] * (double)(k); > - } > - useflops = nflops * (double)((n - 1) * loop); > - } > - if (which == 12) > - { > - for ( k=0 ; k - { > - Checksum[section][12] = Checksum[section][12] + x[k] > - * (double)(k+1); > - } > - useflops = nflops * (double)(n * loop); > - } > - if (which == 13) > - { > - for ( k=0 ; k<2*n ; k++ ) > - { > - for ( j=0 ; j<4 ; j++ ) > - { > - m = 4 * k + j + 1; > - Checksum[section][13] = Checksum[section][13] > - + p[k][j]* (double)(m); > - } > - } > - for ( i=0 ; i<8*n/64 ; i++ ) > - { > - for ( j=0 ; j<64 ; j++ ) > - { > - m = 64 * i + j + 1; > - if (m < 8 * n + 1) > - { > - Checksum[section][13] = Checksum[section][13] > - + h[i][j] * > (double)(m); > - } > - } > - } > - useflops = nflops * (double)(n * loop); > - } > - if (which == 14) > - { > - for ( k=0 ; k - { > - Checksum[section][14] = Checksum[section][14] > - + (xx[k] + vx[k]) * > (double)(k+1); > - } > - for ( k=0 ; k<67 ; k++ ) > - { > - Checksum[section][14] = Checksum[section][14] + rh[k] > - * (double)(k+1); > - } > - useflops = nflops * (double)(n * loop); > - } > - if (which == 15) > - { > - for ( j=0 ; j<7 ; j++ ) > - { > - for ( k=0 ; k<101 ; k++ ) > - { > - m = 101 * j + k + 1; > - if (m < n * 7 + 1) > - { > - Checksum[section][15] = Checksum[section][15] > - + (vs[j][k] + vy[j][k]) * > (double)(m); > - } > - } > - } > - useflops = nflops * (double)((n - 1) * 5 * loop); > - } > - if (which == 16) > - { > - Checksum[section][16] = (double)(k3 + k2 + j5 + m16); > - useflops = (k2 + k2 + 10 * k3); > - } > - if (which == 17) > - { > - Checksum[section][17] = xnm; > - for ( k=0 ; k - { > - Checksum[section][17] = Checksum[section][17] > - + (vxne[k] + vxnd[k]) * > (double)(k+1); > - } > - useflops = nflops * (double)(n * loop); > - } > - if (which == 18) > - { > - for ( k=0 ; k<7 ; k++ ) > - { > - for ( j=0 ; j<101 ; j++ ) > - { > - m = 101 * k + j + 1; > - if (m < 7 * n + 1) > - { > - Checksum[section][18] = Checksum[section][18] > - + (zz[k][j] + zr[k][j]) * > (double)(m); > - } > - } > - } > - useflops = nflops * (double)((n - 1) * 5 * loop); > - } > - if (which == 19) > - { > - Checksum[section][19] = stb5; > - for ( k=0 ; k - { > - Checksum[section][19] = Checksum[section][19] + b5[k] > - * (double)(k+1); > - } > - useflops = nflops * (double)(n * loop); > - } > - if (which == 20) > - { > - for ( k=1 ; k - { > - Checksum[section][20] = Checksum[section][20] + xx[k] > - * (double)(k); > - } > - useflops = nflops * (double)(n * loop); > - } > - if (which == 21) > - { > - for ( k=0 ; k - { > - for ( i=0 ; i<25 ; i++ ) > - { > - m = 25 * k + i + 1; > - Checksum[section][21] = Checksum[section][21] > - + px[k][i] * (double) > (m); > - } > - } > - useflops = nflops * (double)(n * 625 * loop); > - > - } > - if (which == 22) > - { > - for ( k=0 ; k - { > - Checksum[section][22] = Checksum[section][22] + w[k] > - * (double)(k+1); > - } > - useflops = nflops * (double)(n * loop); > - } > - if (which == 23) > - { > - for ( j=0 ; j<7 ; j++ ) > - { > - for ( k=0 ; k<101 ; k++ ) > - { > - m = 101 * j + k + 1; > - if (m < 7 * n + 1) > - { > - Checksum[section][23] = Checksum[section] > [23] > - + za[j][k] * > (double)(m); > - } > - } > - } > - useflops = nflops * (double)((n-1) * 5 * loop); > - } > - if (which == 24) > - { > - Checksum[section][24] = (double)(m24); > - useflops = nflops * (double)((n - 1) * loop); > - } > - > - > -/ > ************************************************************************ > - * Deduct overheads from time, calculate MFLOPS, display > results * > - > ************************************************************************/ > - > - RunTime[section][which] = RunTime[section][which] > - - (loop * extra_loops[section][which]) * > overhead_l; > - FPops[section][which] = useflops * extra_loops[section] > [which]; > - Mflops[section][which] = FPops[section][which] / Scale > - / RunTime[section] > [which]; > - > - > -/ > ************************************************************************ > - * Compare sumcheck with standard result, calculate > accuracy * > - > ************************************************************************/ > - > - printf("%10.3f\n", Checksum[section][which]); > - > - } > - else > - { > -/ > ************************************************************************ > - * Re-initialise data if > reqired * > - > ************************************************************************/ > - > - count = 0; > - if (which == 2) > - { > - for ( k=0 ; k - { > - x[k] = x0[k]; > - } > - } > - if (which == 4) > - { > - m = (1001-7)/2; > - for ( k=6 ; k<1001 ; k=k+m ) > - { > - x[k] = x0[k]; > - } > - } > - if (which == 5) > - { > - for ( k=0 ; k - { > - x[k] = x0[k]; > - } > - } > - if (which == 6) > - { > - for ( k=0 ; k - { > - w[k] = w0[k]; > - } > - } > - if (which == 10) > - { > - for ( i=0 ; i - { > - for (j=4 ; j<13 ; j++ ) > - { > - px[i][j] = px0[i][j]; > - } > - } > - } > - if (which == 13) > - { > - for ( i=0 ; i - { > - for (j=0 ; j<4 ; j++ ) > - { > - p[i][j] = p0[i][j]; > - } > - } > - for ( i=0 ; i<64 ; i++ ) > - { > - for (j=0 ; j<64 ; j++ ) > - { > - h[i][j] = h0[i][j]; > - } > - } > - } > - if (which == 14) > - { > - for ( i=0; i - { > - rh[ir[i] - 1] = rh0[ir[i] - 1]; > - rh[ir[i] ] = rh0[ir[i] ]; > - } > - } > - if (which == 17) > - { > - for ( i=0; i - { > - vxne[i] = vxne0[i]; > - } > - } > - if (which == 18) > - { > - for ( i=1 ; i<6 ; i++ ) > - { > - for (j=1 ; j - { > - zr[i][j] = zr0[i][j]; > - zu[i][j] = zu0[i][j]; > - zv[i][j] = zv0[i][j]; > - zz[i][j] = zz0[i][j]; > - } > - } > - } > - if (which == 21) > - { > - for ( i=0 ; i - { > - for (j=0 ; j<25 ; j++ ) > - { > - px[i][j] = px0[i][j]; > - } > - } > - } > - if (which == 23) > - { > - for ( i=1 ; i<6 ; i++ ) > - { > - for (j=1 ; j - { > - za[i][j] = za0[i][j]; > - } > - } > - } > - k3 = k2 = 0; > - stb5 = stb50; > - xx[0] = xx0; > - > - } > - } > - return 0; > -} > - > -/ > ************************************************************************ > - * init procedure - initialises data for all > loops * > - > ************************************************************************/ > - > - void init(long which) > - { > - long i, j, k, l, m, nn; > - double ds, dw, rr, ss; > - double fuzz, fizz, buzz, scaled, one; > - > - scaled = (double)(10.0); > - scaled = (double)(1.0) / scaled; > - fuzz = (double)(0.0012345); > - buzz = (double)(1.0) + fuzz; > - fizz = (double)(1.1) * fuzz; > - one = (double)(1.0); > - > - for ( k=0 ; k<19977 + 34132 ; k++) > - { > - if (k == 19977) > - { > - fuzz = (double)(0.0012345); > - buzz = (double) (1.0) + fuzz; > - fizz = (double) (1.1) * fuzz; > - } > - buzz = (one - fuzz) * buzz + fuzz; > - fuzz = - fuzz; > - u[k] = (buzz - fizz) * scaled; > - } > - > - fuzz = (double)(0.0012345); > - buzz = (double) (1.0) + fuzz; > - fizz = (double) (1.1) * fuzz; > - > - for ( k=1 ; k<40 ; k++) > - { > - buzz = (one - fuzz) * buzz + fuzz; > - fuzz = - fuzz; > - xtra[k] = (buzz - fizz) * scaled; > - } > - > - ds = 1.0; > - dw = 0.5; > - for ( l=0 ; l<4 ; l++ ) > - { > - for ( i=0 ; i<512 ; i++ ) > - { > - p[i][l] = ds; > - ds = ds + dw; > - } > - } > - for ( i=0 ; i<96 ; i++ ) > - { > - e[i] = 1; > - f[i] = 1; > - } > - > - > - iqranf(); > - dw = -100.0; > - for ( i=0; i<1001 ; i++ ) > - { > - dex[i] = dw * dex[i]; > - grd[i] = ix[i]; > - } > - flx = 0.001; > - > - > - d[0]= 1.01980486428764; > - nn = n16; > - > - for ( l=1 ; l<300 ; l++ ) > - { > - d[l] = d[l-1] + 1.000e-4 / d[l-1]; > - } > - rr = d[nn-1]; > - for ( l=1 ; l<=2 ; l++ ) > - { > - m = (nn+nn)*(l-1); > - for ( j=1 ; j<=2 ; j++ ) > - { > - for ( k=1 ; k<=nn ; k++ ) > - { > - m = m + 1; > - ss = (double)(k); > - plan[m-1] = rr * ((ss + 1.0) / ss); > - zone[m-1] = k + k; > - } > - } > - } > - k = nn + nn + 1; > - zone[k-1] = nn; > - > - if (which == 16) > - { > - r = d[n-1]; > - s = d[n-2]; > - t = d[n-3]; > - k3 = k2 = 0; > - } > - expmax = 20.0; > - if (which == 22) > - { > - u[n-1] = 0.99*expmax*v[n-1]; > - } > - if (which == 24) > - { > - x[n/2] = -1.0e+10; > - } > - > -/ > ************************************************************************ > - * Make copies of data for extra > loops * > - > ************************************************************************/ > - > - for ( i=0; i<1001 ; i++ ) > - { > - x0[i] = x[i]; > - w0[i] = w[i]; > - } > - for ( i=0 ; i<101 ; i++ ) > - { > - for (j=0 ; j<25 ; j++ ) > - { > - px0[i][j] = px[i][j]; > - } > - } > - for ( i=0 ; i<512 ; i++ ) > - { > - for (j=0 ; j<4 ; j++ ) > - { > - p0[i][j] = p[i][j]; > - } > - } > - for ( i=0 ; i<64 ; i++ ) > - { > - for (j=0 ; j<64 ; j++ ) > - { > - h0[i][j] = h[i][j]; > - } > - } > - for ( i=0; i<2048 ; i++ ) > - { > - rh0[i] = rh[i]; > - } > - for ( i=0; i<101 ; i++ ) > - { > - vxne0[i] = vxne[i]; > - } > - for ( i=0 ; i<7 ; i++ ) > - { > - for (j=0 ; j<101 ; j++ ) > - { > - zr0[i][j] = zr[i][j]; > - zu0[i][j] = zu[i][j]; > - zv0[i][j] = zv[i][j]; > - zz0[i][j] = zz[i][j]; > - za0[i][j] = za[i][j]; > - } > - } > - stb50 = stb5; > - xx0 = xx[0]; > - > - return; > - } > - > -/ > ************************************************************************ > - * parameters procedure for loop counts, Do spans, sumchecks, > FLOPS * > - > ************************************************************************/ > - > - long parameters(long which) > - { > - > - long nloops[3][25] = > - { {0, 1001, 101, 1001, 1001, 1001, 64, 995, 100, > - 101, 101, 1001, 1000, 64, 1001, 101, 75, > - 101, 100, 101, 1000, 101, 101, 100, 1001 }, > - {0, 101, 101, 101, 101, 101, 32, 101, 100, > - 101, 101, 101, 100, 32, 101, 101, 40, > - 101, 100, 101, 100, 50, 101, 100, 101 }, > - {0, 27, 15, 27, 27, 27, 8, 21, 14, > - 15, 15, 27, 26, 8, 27, 15, 15, > - 15, 14, 15, 26, 20, 15, 14, 27 } }; > - > - > - > - long lpass[3][25] = > - { {0, 7, 67, 9, 14, 10, 3, 4, 10, 36, 34, 11, 12, > - 36, 2, 1, 25, 35, 2, 39, 1, 1, 11, 8, 5 }, > - {0, 40, 40, 53, 70, 55, 7, 22, 6, 21, 19, 64, 68, > - 41, 10, 1, 27, 20, 1, 23, 8, 1, 7, 5, > 31 }, > - {0, 28, 46, 37, 38, 40, 21, 20, 9, 26, 25, 46, 48, > - 31, 8, 1, 14, 26, 2, 28, 7, 1, 8, 7, > 23 } }; > - > - double sums[3][25] = > - { > - { 0.0, > - 5.114652693224671e+04, 1.539721811668385e+03, > 1.000742883066363e+01, > - 5.999250595473891e-01, 4.548871642387267e+03, > 4.375116344729986e+03, > - 6.104251075174761e+04, 1.501268005625798e+05, > 1.189443609974981e+05, > - 7.310369784325296e+04, 3.342910972650109e+07, > 2.907141294167248e-05, > - 1.202533961842803e+11, 3.165553044000334e+09, > 3.943816690352042e+04, > - 5.650760000000000e+05, 1.114641772902486e+03, > 1.015727037502300e+05, > - 5.421816960147207e+02, 3.040644339351239e+07, > 1.597308280710199e+08, > - 2.938604376566697e+02, 3.549900501563623e+04, > 5.000000000000000e+02 > - }, > - > - { 0.0, > - 5.253344778937972e+02, 1.539721811668385e+03, > 1.009741436578952e+00, > - 5.999250595473891e-01, 4.589031939600982e+01, > 8.631675645333210e+01, > - 6.345586315784055e+02, 1.501268005625798e+05, > 1.189443609974981e+05, > - 7.310369784325296e+04, 3.433560407475758e+04, > 7.127569130821465e-06, > - 9.816387810944345e+10, 3.039983465145393e+07, > 3.943816690352042e+04, > - 6.480410000000000e+05, 1.114641772902486e+03, > 1.015727037502300e+05, > - 5.421816960147207e+02, 3.126205178815431e+04, > 7.824524877232093e+07, > - 2.938604376566697e+02, 3.549900501563623e+04, > 5.000000000000000e+01 > - }, > - > - { 0.0, > - 3.855104502494961e+01, 3.953296986903059e+01, > 2.699309089320672e-01, > - 5.999250595473891e-01, 3.182615248447483e+00, > 1.120309393467088e+00, > - 2.845720217644024e+01, 2.960543667875003e+03, > 2.623968460874250e+03, > - 1.651291227698265e+03, 6.551161335845770e+02, > 1.943435981130448e-06, > - 3.847124199949426e+10, 2.923540598672011e+06, > 1.108997288134785e+03, > - 5.152160000000000e+05, 2.947368618589360e+01, > 9.700646212337040e+02, > - 1.268230698051003e+01, 5.987713249475302e+02, > 5.009945671204667e+07, > - 6.109968728263972e+00, 4.850340602749970e+02, > 1.300000000000000e+01 > - } }; > - > - > - > - double number_flops[25] = {0, 5., 4., 2., 2., 2., 2., 16., > 36., 17., > - 9., 1., 1., 7., 11., 33.,10., > 9., 44., > - 6., 26., 2., 17., 11., 1.}; > - double now = 1.0; > - > - > - n = nloops[section][which]; > - nspan[section][which] = n; > - n16 = nloops[section][16]; > - nflops = number_flops[which]; > - xflops[which] = nflops; > - loop = lpass[section][which]; > - xloops[section][which] = loop; > - loop = loop * mult; > - MasterSum = sums[section][which]; > - count = 0; > - > - init(which); > - > - > - return 0; > - } > - > -/ > ************************************************************************ > - * check procedure to check accuracy of > calculations * > - > ************************************************************************/ > - > - void check(long which) > - { > - long maxs = 16; > - double xm, ym, re, min1, max1; > - > - xm = MasterSum; > - ym = Checksum[section][which]; > - > - if (xm * ym < 0.0) > - { > - accuracy[section][which] = 0; > - } > - else > - { > - if ( xm == ym) > - { > - accuracy[section][which] = maxs; > - } > - else > - { > - xm = fabs(xm); > - ym = fabs(ym); > - min1 = xm; > - max1 = ym; > - if (ym < xm) > - { > - min1 = ym; > - max1 = xm; > - } > - re = 1.0 - min1 / max1; > - accuracy[section][which] = > - (long) > ( fabs(log10(fabs(re))) + 0.5); > - } > - } > - > - return; > - } > - > -/ > ************************************************************************ > - * iqranf procedure - random number generator for Kernel > 14 * > - > ************************************************************************/ > - > - void iqranf() > - { > - > - long inset, Mmin, Mmax, nn, i, kk; > - double span, spin, realn, per, scale1, qq, dkk, dp, dq; > - long seed[3] = { 256, 12491249, 1499352848 }; > - > - nn = 1001; > - Mmin = 1; > - Mmax = 1001; > - kk = seed[section]; > - > - inset= Mmin; > - span= Mmax - Mmin; > - spin= 16807; > - per= 2147483647; > - realn= nn; > - scale1= 1.00001; > - qq= scale1 * (span / realn); > - dkk= kk; > - > - for ( i=0 ; i - { > - dp= dkk*spin; > - dkk= dp - (long)( dp/per)*per; > - dq= dkk*span; > - ix[i] = inset + ( dq/ per); > - if (ix[i] < Mmin | ix[i] > Mmax) > - { > - ix[i] = inset + i + 1 * qq; > - } > - } > - > - return; > - } > - > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From isanbard at gmail.com Mon Dec 1 16:56:58 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 01 Dec 2008 22:56:58 -0000 Subject: [llvm-commits] [llvm] r60378 - /llvm/tags/Apple/llvmCore-2085/ Message-ID: <200812012256.mB1MuwJE021339@zion.cs.uiuc.edu> Author: void Date: Mon Dec 1 16:56:58 2008 New Revision: 60378 URL: http://llvm.org/viewvc/llvm-project?rev=60378&view=rev Log: Creating llvmCore-2085 branch Added: llvm/tags/Apple/llvmCore-2085/ - copied from r60377, llvm/trunk/ From isanbard at gmail.com Mon Dec 1 16:57:06 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 01 Dec 2008 22:57:06 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60379 - /llvm-gcc-4.2/tags/Apple/llvmgcc42-2085/ Message-ID: <200812012257.mB1Mv6HC021352@zion.cs.uiuc.edu> Author: void Date: Mon Dec 1 16:57:06 2008 New Revision: 60379 URL: http://llvm.org/viewvc/llvm-project?rev=60379&view=rev Log: Creating llvmgcc42-2085 branch Added: llvm-gcc-4.2/tags/Apple/llvmgcc42-2085/ - copied from r60378, llvm-gcc-4.2/trunk/ From espindola at google.com Mon Dec 1 17:12:00 2008 From: espindola at google.com (Rafael Espindola) Date: Mon, 1 Dec 2008 23:12:00 +0000 Subject: [llvm-commits] [patch] print ".file" directives In-Reply-To: <23C4696E-E675-4BD2-84A8-BEDF2BF52B5D@apple.com> References: <38a0d8450811280731r5ab0fcdn787e06fdfebf0b6d@mail.gmail.com> <23C4696E-E675-4BD2-84A8-BEDF2BF52B5D@apple.com> Message-ID: <38a0d8450812011512s149ecd1di8d382536b4876037@mail.gmail.com> 2008/12/1 Evan Cheng : > Ok if the .file directive is universally accepted by all assemblers. I > suspect not though since TargetAsmInfo has a HasDotLocAndDotFile field. How did I miss that!? In my new patch I added a hasDotFileDirective. Will try with HasDotLocAndDotFile and post again. > Evan Thanks, -- Rafael Avila de Espindola Google | Gordon House | Barrow Street | Dublin 4 | Ireland Registered in Dublin, Ireland | Registration Number: 368047 From isanbard at gmail.com Mon Dec 1 17:28:25 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 01 Dec 2008 23:28:25 -0000 Subject: [llvm-commits] [llvm] r60381 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAG.h lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200812012328.mB1NSQs6022227@zion.cs.uiuc.edu> Author: void Date: Mon Dec 1 17:28:22 2008 New Revision: 60381 URL: http://llvm.org/viewvc/llvm-project?rev=60381&view=rev Log: Expand getVTList, getNodeValueTypes, and SelectNodeTo to handle more value types. Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAG.h?rev=60381&r1=60380&r2=60381&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Mon Dec 1 17:28:22 2008 @@ -227,6 +227,7 @@ SDVTList getVTList(MVT VT); SDVTList getVTList(MVT VT1, MVT VT2); SDVTList getVTList(MVT VT1, MVT VT2, MVT VT3); + SDVTList getVTList(MVT VT1, MVT VT2, MVT VT3, MVT VT4); SDVTList getVTList(const MVT *VTs, unsigned NumVTs); /// getNodeValueTypes - These are obsolete, use getVTList instead. @@ -239,6 +240,9 @@ const MVT *getNodeValueTypes(MVT VT1, MVT VT2, MVT VT3) { return getVTList(VT1, VT2, VT3).VTs; } + const MVT *getNodeValueTypes(MVT VT1, MVT VT2, MVT VT3, MVT VT4) { + return getVTList(VT1, VT2, VT3, VT4).VTs; + } const MVT *getNodeValueTypes(const std::vector &vtList) { return getVTList(&vtList[0], (unsigned)vtList.size()).VTs; } @@ -564,12 +568,17 @@ MVT VT2, const SDValue *Ops, unsigned NumOps); SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT VT1, MVT VT2, MVT VT3, const SDValue *Ops, unsigned NumOps); + SDNode *SelectNodeTo(SDNode *N, unsigned MachineOpc, MVT VT1, + MVT VT2, MVT VT3, MVT VT4, const SDValue *Ops, + unsigned NumOps); SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT VT1, MVT VT2, SDValue Op1); SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT VT1, MVT VT2, SDValue Op1, SDValue Op2); SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT VT1, MVT VT2, SDValue Op1, SDValue Op2, SDValue Op3); + SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT VT1, + MVT VT2, MVT VT3, SDValue Op1, SDValue Op2, SDValue Op3); SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, SDVTList VTs, const SDValue *Ops, unsigned NumOps); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=60381&r1=60380&r2=60381&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Mon Dec 1 17:28:22 2008 @@ -3838,6 +3838,23 @@ return Result; } +SDVTList SelectionDAG::getVTList(MVT VT1, MVT VT2, MVT VT3, MVT VT4) { + for (std::vector::reverse_iterator I = VTList.rbegin(), + E = VTList.rend(); I != E; ++I) + if (I->NumVTs == 4 && I->VTs[0] == VT1 && I->VTs[1] == VT2 && + I->VTs[2] == VT3 && I->VTs[3] == VT4) + return *I; + + MVT *Array = Allocator.Allocate(3); + Array[0] = VT1; + Array[1] = VT2; + Array[2] = VT3; + Array[3] = VT4; + SDVTList Result = makeVTList(Array, 4); + VTList.push_back(Result); + return Result; +} + SDVTList SelectionDAG::getVTList(const MVT *VTs, unsigned NumVTs) { switch (NumVTs) { case 0: assert(0 && "Cannot have nodes without results!"); @@ -4075,6 +4092,13 @@ return SelectNodeTo(N, MachineOpc, VTs, Ops, NumOps); } +SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc, + MVT VT1, MVT VT2, MVT VT3, MVT VT4, + const SDValue *Ops, unsigned NumOps) { + SDVTList VTs = getVTList(VT1, VT2, VT3, VT4); + return SelectNodeTo(N, MachineOpc, VTs, Ops, NumOps); +} + SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc, MVT VT1, MVT VT2, SDValue Op1) { @@ -4101,6 +4125,15 @@ } SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc, + MVT VT1, MVT VT2, MVT VT3, + SDValue Op1, SDValue Op2, + SDValue Op3) { + SDVTList VTs = getVTList(VT1, VT2, VT3); + SDValue Ops[] = { Op1, Op2, Op3 }; + return SelectNodeTo(N, MachineOpc, VTs, Ops, 3); +} + +SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc, SDVTList VTs, const SDValue *Ops, unsigned NumOps) { return MorphNodeTo(N, ~MachineOpc, VTs, Ops, NumOps); From isanbard at gmail.com Mon Dec 1 17:30:42 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 01 Dec 2008 23:30:42 -0000 Subject: [llvm-commits] [llvm] r60382 - in /llvm/trunk/lib/Target/X86: X86Instr64bit.td X86InstrInfo.cpp X86InstrInfo.td Message-ID: <200812012330.mB1NUh0P022309@zion.cs.uiuc.edu> Author: void Date: Mon Dec 1 17:30:42 2008 New Revision: 60382 URL: http://llvm.org/viewvc/llvm-project?rev=60382&view=rev Log: - Have "ADD" instructions return an implicit EFLAGS. - Add support for seto, setno, setc, and setnc instructions. Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td llvm/trunk/lib/Target/X86/X86InstrInfo.cpp llvm/trunk/lib/Target/X86/X86InstrInfo.td Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Instr64bit.td?rev=60382&r1=60381&r2=60382&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Instr64bit.td (original) +++ llvm/trunk/lib/Target/X86/X86Instr64bit.td Mon Dec 1 17:30:42 2008 @@ -314,59 +314,73 @@ let isCommutable = 1 in def ADD64rr : RI<0x01, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), "add{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (add GR64:$src1, GR64:$src2))]>; + [(set GR64:$dst, (add GR64:$src1, GR64:$src2)), + (implicit EFLAGS)]>; def ADD64ri32 : RIi32<0x81, MRM0r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2), "add{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (add GR64:$src1, i64immSExt32:$src2))]>; + [(set GR64:$dst, (add GR64:$src1, i64immSExt32:$src2)), + (implicit EFLAGS)]>; def ADD64ri8 : RIi8<0x83, MRM0r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2), "add{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (add GR64:$src1, i64immSExt8:$src2))]>; + [(set GR64:$dst, (add GR64:$src1, i64immSExt8:$src2)), + (implicit EFLAGS)]>; } // isConvertibleToThreeAddress def ADD64rm : RI<0x03, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), "add{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (add GR64:$src1, (load addr:$src2)))]>; + [(set GR64:$dst, (add GR64:$src1, (load addr:$src2))), + (implicit EFLAGS)]>; } // isTwoAddress def ADD64mr : RI<0x01, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2), "add{q}\t{$src2, $dst|$dst, $src2}", - [(store (add (load addr:$dst), GR64:$src2), addr:$dst)]>; + [(store (add (load addr:$dst), GR64:$src2), addr:$dst), + (implicit EFLAGS)]>; def ADD64mi32 : RIi32<0x81, MRM0m, (outs), (ins i64mem:$dst, i64i32imm :$src2), "add{q}\t{$src2, $dst|$dst, $src2}", - [(store (add (load addr:$dst), i64immSExt32:$src2), addr:$dst)]>; + [(store (add (load addr:$dst), i64immSExt32:$src2), addr:$dst), + (implicit EFLAGS)]>; def ADD64mi8 : RIi8<0x83, MRM0m, (outs), (ins i64mem:$dst, i64i8imm :$src2), "add{q}\t{$src2, $dst|$dst, $src2}", - [(store (add (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>; + [(store (add (load addr:$dst), i64immSExt8:$src2), addr:$dst), + (implicit EFLAGS)]>; let Uses = [EFLAGS] in { let isTwoAddress = 1 in { let isCommutable = 1 in def ADC64rr : RI<0x11, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), "adc{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (adde GR64:$src1, GR64:$src2))]>; + [(set GR64:$dst, (adde GR64:$src1, GR64:$src2)), + (implicit EFLAGS)]>; def ADC64rm : RI<0x13, MRMSrcMem , (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), "adc{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (adde GR64:$src1, (load addr:$src2)))]>; + [(set GR64:$dst, (adde GR64:$src1, (load addr:$src2))), + (implicit EFLAGS)]>; def ADC64ri32 : RIi32<0x81, MRM2r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2), "adc{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (adde GR64:$src1, i64immSExt32:$src2))]>; + [(set GR64:$dst, (adde GR64:$src1, i64immSExt32:$src2)), + (implicit EFLAGS)]>; def ADC64ri8 : RIi8<0x83, MRM2r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2), "adc{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (adde GR64:$src1, i64immSExt8:$src2))]>; + [(set GR64:$dst, (adde GR64:$src1, i64immSExt8:$src2)), + (implicit EFLAGS)]>; } // isTwoAddress def ADC64mr : RI<0x11, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2), "adc{q}\t{$src2, $dst|$dst, $src2}", - [(store (adde (load addr:$dst), GR64:$src2), addr:$dst)]>; + [(store (adde (load addr:$dst), GR64:$src2), addr:$dst), + (implicit EFLAGS)]>; def ADC64mi32 : RIi32<0x81, MRM2m, (outs), (ins i64mem:$dst, i64i32imm:$src2), "adc{q}\t{$src2, $dst|$dst, $src2}", - [(store (adde (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>; + [(store (adde (load addr:$dst), i64immSExt8:$src2), addr:$dst), + (implicit EFLAGS)]>; def ADC64mi8 : RIi8<0x83, MRM2m, (outs), (ins i64mem:$dst, i64i8imm :$src2), "adc{q}\t{$src2, $dst|$dst, $src2}", - [(store (adde (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>; + [(store (adde (load addr:$dst), i64immSExt8:$src2), addr:$dst), + (implicit EFLAGS)]>; } // Uses = [EFLAGS] let isTwoAddress = 1 in { Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=60382&r1=60381&r2=60382&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Mon Dec 1 17:30:42 2008 @@ -280,14 +280,18 @@ { X86::SETAr, X86::SETAm, 0 }, { X86::SETBEr, X86::SETBEm, 0 }, { X86::SETBr, X86::SETBm, 0 }, + { X86::SETCr, X86::SETCm, 0 }, { X86::SETEr, X86::SETEm, 0 }, { X86::SETGEr, X86::SETGEm, 0 }, { X86::SETGr, X86::SETGm, 0 }, { X86::SETLEr, X86::SETLEm, 0 }, { X86::SETLr, X86::SETLm, 0 }, + { X86::SETNCr, X86::SETNCm, 0 }, { X86::SETNEr, X86::SETNEm, 0 }, + { X86::SETNOr, X86::SETNOm, 0 }, { X86::SETNPr, X86::SETNPm, 0 }, { X86::SETNSr, X86::SETNSm, 0 }, + { X86::SETOr, X86::SETOm, 0 }, { X86::SETPr, X86::SETPm, 0 }, { X86::SETSr, X86::SETSm, 0 }, { X86::TAILJMPr, X86::TAILJMPm, 1 }, Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=60382&r1=60381&r2=60382&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Mon Dec 1 17:30:42 2008 @@ -1926,110 +1926,136 @@ def ADD8rr : I<0x00, MRMDestReg, (outs GR8 :$dst), (ins GR8 :$src1, GR8 :$src2), "add{b}\t{$src2, $dst|$dst, $src2}", - [(set GR8:$dst, (add GR8:$src1, GR8:$src2))]>; + [(set GR8:$dst, (add GR8:$src1, GR8:$src2)), + (implicit EFLAGS)]>; let isConvertibleToThreeAddress = 1 in { // Can transform into LEA. def ADD16rr : I<0x01, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2), "add{w}\t{$src2, $dst|$dst, $src2}", - [(set GR16:$dst, (add GR16:$src1, GR16:$src2))]>, OpSize; + [(set GR16:$dst, (add GR16:$src1, GR16:$src2)), + (implicit EFLAGS)]>, OpSize; def ADD32rr : I<0x01, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), "add{l}\t{$src2, $dst|$dst, $src2}", - [(set GR32:$dst, (add GR32:$src1, GR32:$src2))]>; + [(set GR32:$dst, (add GR32:$src1, GR32:$src2)), + (implicit EFLAGS)]>; } // end isConvertibleToThreeAddress } // end isCommutable def ADD8rm : I<0x02, MRMSrcMem, (outs GR8 :$dst), (ins GR8 :$src1, i8mem :$src2), "add{b}\t{$src2, $dst|$dst, $src2}", - [(set GR8:$dst, (add GR8:$src1, (load addr:$src2)))]>; + [(set GR8:$dst, (add GR8:$src1, (load addr:$src2))), + (implicit EFLAGS)]>; def ADD16rm : I<0x03, MRMSrcMem, (outs GR16:$dst), (ins GR16:$src1, i16mem:$src2), "add{w}\t{$src2, $dst|$dst, $src2}", - [(set GR16:$dst, (add GR16:$src1, (load addr:$src2)))]>,OpSize; + [(set GR16:$dst, (add GR16:$src1, (load addr:$src2))), + (implicit EFLAGS)]>, OpSize; def ADD32rm : I<0x03, MRMSrcMem, (outs GR32:$dst), (ins GR32:$src1, i32mem:$src2), "add{l}\t{$src2, $dst|$dst, $src2}", - [(set GR32:$dst, (add GR32:$src1, (load addr:$src2)))]>; + [(set GR32:$dst, (add GR32:$src1, (load addr:$src2))), + (implicit EFLAGS)]>; def ADD8ri : Ii8<0x80, MRM0r, (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2), "add{b}\t{$src2, $dst|$dst, $src2}", - [(set GR8:$dst, (add GR8:$src1, imm:$src2))]>; + [(set GR8:$dst, (add GR8:$src1, imm:$src2)), + (implicit EFLAGS)]>; let isConvertibleToThreeAddress = 1 in { // Can transform into LEA. def ADD16ri : Ii16<0x81, MRM0r, (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2), "add{w}\t{$src2, $dst|$dst, $src2}", - [(set GR16:$dst, (add GR16:$src1, imm:$src2))]>, OpSize; + [(set GR16:$dst, (add GR16:$src1, imm:$src2)), + (implicit EFLAGS)]>, OpSize; def ADD32ri : Ii32<0x81, MRM0r, (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2), "add{l}\t{$src2, $dst|$dst, $src2}", - [(set GR32:$dst, (add GR32:$src1, imm:$src2))]>; + [(set GR32:$dst, (add GR32:$src1, imm:$src2)), + (implicit EFLAGS)]>; def ADD16ri8 : Ii8<0x83, MRM0r, (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2), "add{w}\t{$src2, $dst|$dst, $src2}", - [(set GR16:$dst, (add GR16:$src1, i16immSExt8:$src2))]>, OpSize; + [(set GR16:$dst, (add GR16:$src1, i16immSExt8:$src2)), + (implicit EFLAGS)]>, OpSize; def ADD32ri8 : Ii8<0x83, MRM0r, (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2), "add{l}\t{$src2, $dst|$dst, $src2}", - [(set GR32:$dst, (add GR32:$src1, i32immSExt8:$src2))]>; + [(set GR32:$dst, (add GR32:$src1, i32immSExt8:$src2)), + (implicit EFLAGS)]>; } let isTwoAddress = 0 in { def ADD8mr : I<0x00, MRMDestMem, (outs), (ins i8mem :$dst, GR8 :$src2), "add{b}\t{$src2, $dst|$dst, $src2}", - [(store (add (load addr:$dst), GR8:$src2), addr:$dst)]>; + [(store (add (load addr:$dst), GR8:$src2), addr:$dst), + (implicit EFLAGS)]>; def ADD16mr : I<0x01, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src2), "add{w}\t{$src2, $dst|$dst, $src2}", - [(store (add (load addr:$dst), GR16:$src2), addr:$dst)]>, + [(store (add (load addr:$dst), GR16:$src2), addr:$dst), + (implicit EFLAGS)]>, OpSize; def ADD32mr : I<0x01, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2), "add{l}\t{$src2, $dst|$dst, $src2}", - [(store (add (load addr:$dst), GR32:$src2), addr:$dst)]>; + [(store (add (load addr:$dst), GR32:$src2), addr:$dst), + (implicit EFLAGS)]>; def ADD8mi : Ii8<0x80, MRM0m, (outs), (ins i8mem :$dst, i8imm :$src2), "add{b}\t{$src2, $dst|$dst, $src2}", - [(store (add (loadi8 addr:$dst), imm:$src2), addr:$dst)]>; + [(store (add (loadi8 addr:$dst), imm:$src2), addr:$dst), + (implicit EFLAGS)]>; def ADD16mi : Ii16<0x81, MRM0m, (outs), (ins i16mem:$dst, i16imm:$src2), "add{w}\t{$src2, $dst|$dst, $src2}", - [(store (add (loadi16 addr:$dst), imm:$src2), addr:$dst)]>, + [(store (add (loadi16 addr:$dst), imm:$src2), addr:$dst), + (implicit EFLAGS)]>, OpSize; def ADD32mi : Ii32<0x81, MRM0m, (outs), (ins i32mem:$dst, i32imm:$src2), "add{l}\t{$src2, $dst|$dst, $src2}", - [(store (add (loadi32 addr:$dst), imm:$src2), addr:$dst)]>; + [(store (add (loadi32 addr:$dst), imm:$src2), addr:$dst), + (implicit EFLAGS)]>; def ADD16mi8 : Ii8<0x83, MRM0m, (outs), (ins i16mem:$dst, i16i8imm :$src2), "add{w}\t{$src2, $dst|$dst, $src2}", - [(store (add (load addr:$dst), i16immSExt8:$src2), addr:$dst)]>, + [(store (add (load addr:$dst), i16immSExt8:$src2), addr:$dst), + (implicit EFLAGS)]>, OpSize; def ADD32mi8 : Ii8<0x83, MRM0m, (outs), (ins i32mem:$dst, i32i8imm :$src2), "add{l}\t{$src2, $dst|$dst, $src2}", - [(store (add (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>; + [(store (add (load addr:$dst), i32immSExt8:$src2), addr:$dst), + (implicit EFLAGS)]>; } let Uses = [EFLAGS] in { let isCommutable = 1 in { // X = ADC Y, Z --> X = ADC Z, Y def ADC32rr : I<0x11, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), "adc{l}\t{$src2, $dst|$dst, $src2}", - [(set GR32:$dst, (adde GR32:$src1, GR32:$src2))]>; + [(set GR32:$dst, (adde GR32:$src1, GR32:$src2)), + (implicit EFLAGS)]>; } def ADC32rm : I<0x13, MRMSrcMem , (outs GR32:$dst), (ins GR32:$src1, i32mem:$src2), "adc{l}\t{$src2, $dst|$dst, $src2}", - [(set GR32:$dst, (adde GR32:$src1, (load addr:$src2)))]>; + [(set GR32:$dst, (adde GR32:$src1, (load addr:$src2))), + (implicit EFLAGS)]>; def ADC32ri : Ii32<0x81, MRM2r, (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2), "adc{l}\t{$src2, $dst|$dst, $src2}", - [(set GR32:$dst, (adde GR32:$src1, imm:$src2))]>; + [(set GR32:$dst, (adde GR32:$src1, imm:$src2)), + (implicit EFLAGS)]>; def ADC32ri8 : Ii8<0x83, MRM2r, (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2), "adc{l}\t{$src2, $dst|$dst, $src2}", - [(set GR32:$dst, (adde GR32:$src1, i32immSExt8:$src2))]>; + [(set GR32:$dst, (adde GR32:$src1, i32immSExt8:$src2)), + (implicit EFLAGS)]>; let isTwoAddress = 0 in { def ADC32mr : I<0x11, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2), "adc{l}\t{$src2, $dst|$dst, $src2}", - [(store (adde (load addr:$dst), GR32:$src2), addr:$dst)]>; + [(store (adde (load addr:$dst), GR32:$src2), addr:$dst), + (implicit EFLAGS)]>; def ADC32mi : Ii32<0x81, MRM2m, (outs), (ins i32mem:$dst, i32imm:$src2), "adc{l}\t{$src2, $dst|$dst, $src2}", - [(store (adde (loadi32 addr:$dst), imm:$src2), addr:$dst)]>; + [(store (adde (loadi32 addr:$dst), imm:$src2), addr:$dst), + (implicit EFLAGS)]>; def ADC32mi8 : Ii8<0x83, MRM2m, (outs), (ins i32mem:$dst, i32i8imm :$src2), "adc{l}\t{$src2, $dst|$dst, $src2}", - [(store (adde (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>; + [(store (adde (load addr:$dst), i32immSExt8:$src2), addr:$dst), + (implicit EFLAGS)]>; } } // Uses = [EFLAGS] @@ -2272,6 +2298,7 @@ "sete\t$dst", [(store (X86setcc X86_COND_E, EFLAGS), addr:$dst)]>, TB; // [mem8] = == + def SETNEr : I<0x95, MRM0r, (outs GR8 :$dst), (ins), "setne\t$dst", @@ -2282,6 +2309,7 @@ "setne\t$dst", [(store (X86setcc X86_COND_NE, EFLAGS), addr:$dst)]>, TB; // [mem8] = != + def SETLr : I<0x9C, MRM0r, (outs GR8 :$dst), (ins), "setl\t$dst", @@ -2292,6 +2320,7 @@ "setl\t$dst", [(store (X86setcc X86_COND_L, EFLAGS), addr:$dst)]>, TB; // [mem8] = < signed + def SETGEr : I<0x9D, MRM0r, (outs GR8 :$dst), (ins), "setge\t$dst", @@ -2302,6 +2331,7 @@ "setge\t$dst", [(store (X86setcc X86_COND_GE, EFLAGS), addr:$dst)]>, TB; // [mem8] = >= signed + def SETLEr : I<0x9E, MRM0r, (outs GR8 :$dst), (ins), "setle\t$dst", @@ -2312,6 +2342,7 @@ "setle\t$dst", [(store (X86setcc X86_COND_LE, EFLAGS), addr:$dst)]>, TB; // [mem8] = <= signed + def SETGr : I<0x9F, MRM0r, (outs GR8 :$dst), (ins), "setg\t$dst", @@ -2333,6 +2364,7 @@ "setb\t$dst", [(store (X86setcc X86_COND_B, EFLAGS), addr:$dst)]>, TB; // [mem8] = < unsign + def SETAEr : I<0x93, MRM0r, (outs GR8 :$dst), (ins), "setae\t$dst", @@ -2343,6 +2375,7 @@ "setae\t$dst", [(store (X86setcc X86_COND_AE, EFLAGS), addr:$dst)]>, TB; // [mem8] = >= unsign + def SETBEr : I<0x96, MRM0r, (outs GR8 :$dst), (ins), "setbe\t$dst", @@ -2353,6 +2386,7 @@ "setbe\t$dst", [(store (X86setcc X86_COND_BE, EFLAGS), addr:$dst)]>, TB; // [mem8] = <= unsign + def SETAr : I<0x97, MRM0r, (outs GR8 :$dst), (ins), "seta\t$dst", @@ -2384,6 +2418,7 @@ "setns\t$dst", [(store (X86setcc X86_COND_NS, EFLAGS), addr:$dst)]>, TB; // [mem8] = ! + def SETPr : I<0x9A, MRM0r, (outs GR8 :$dst), (ins), "setp\t$dst", @@ -2404,6 +2439,48 @@ "setnp\t$dst", [(store (X86setcc X86_COND_NP, EFLAGS), addr:$dst)]>, TB; // [mem8] = not parity + +def SETOr : I<0x90, MRM0r, + (outs GR8 :$dst), (ins), + "seto\t$dst", + [(set GR8:$dst, (X86setcc X86_COND_O, EFLAGS))]>, + TB; // GR8 = overflow +def SETOm : I<0x90, MRM0m, + (outs), (ins i8mem:$dst), + "seto\t$dst", + [(store (X86setcc X86_COND_O, EFLAGS), addr:$dst)]>, + TB; // [mem8] = overflow +def SETNOr : I<0x91, MRM0r, + (outs GR8 :$dst), (ins), + "setno\t$dst", + [(set GR8:$dst, (X86setcc X86_COND_NO, EFLAGS))]>, + TB; // GR8 = not overflow +def SETNOm : I<0x91, MRM0m, + (outs), (ins i8mem:$dst), + "setno\t$dst", + [(store (X86setcc X86_COND_NO, EFLAGS), addr:$dst)]>, + TB; // [mem8] = not overflow + +def SETCr : I<0x92, MRM0r, + (outs GR8 :$dst), (ins), + "setc\t$dst", + [(set GR8:$dst, (X86setcc X86_COND_C, EFLAGS))]>, + TB; // GR8 = carry +def SETCm : I<0x92, MRM0m, + (outs), (ins i8mem:$dst), + "setc\t$dst", + [(store (X86setcc X86_COND_C, EFLAGS), addr:$dst)]>, + TB; // [mem8] = carry +def SETNCr : I<0x93, MRM0r, + (outs GR8 :$dst), (ins), + "setnc\t$dst", + [(set GR8:$dst, (X86setcc X86_COND_NC, EFLAGS))]>, + TB; // GR8 = not carry +def SETNCm : I<0x93, MRM0m, + (outs), (ins i8mem:$dst), + "setnc\t$dst", + [(store (X86setcc X86_COND_NC, EFLAGS), addr:$dst)]>, + TB; // [mem8] = not carry } // Uses = [EFLAGS] From clattner at apple.com Mon Dec 1 17:43:09 2008 From: clattner at apple.com (Chris Lattner) Date: Mon, 1 Dec 2008 15:43:09 -0800 Subject: [llvm-commits] [test-suite] r60375 - /test-suite/trunk/SingleSource/Benchmarks/Misc-C++/llloops.cpp In-Reply-To: <6315BAB5-2B40-469F-90B6-7100A3954AEB@apple.com> References: <200812012223.mB1MNhux020136@zion.cs.uiuc.edu> <6315BAB5-2B40-469F-90B6-7100A3954AEB@apple.com> Message-ID: <47F8F25E-16DD-4FD3-9214-D2199B67008D@apple.com> On Dec 1, 2008, at 2:37 PM, Dale Johannesen wrote: > > On Dec 1, 2008, at 2:23 PMPST, Chris Lattner wrote: > >> Author: lattner >> Date: Mon Dec 1 16:23:16 2008 >> New Revision: 60375 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=60375&view=rev >> Log: >> Remove this benchmark, it is using undefined behavior (accessing >> at least the 'u' array beyond its bounds in 'init') and is too >> brain twisting to fix. Owen, if you really really really want this >> benchmark, feel free to fix it and recommit. > > Livermore Loops is an old but well-known benchmark, well worth > fixing. It is brain twisting partly because it was translated from > Fortran, and partly because the Fortran was.:) > > It appears the code in "init" is trying to initialize the entire > Arrays struct, so bolting on a union with double[totalsize] ought to > work. Sure, patches welcome. :) We do have other versions of livermore loops elsewhere in the testsuite. -Chris From isanbard at gmail.com Mon Dec 1 17:44:08 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 01 Dec 2008 23:44:08 -0000 Subject: [llvm-commits] [llvm] r60383 - in /llvm/trunk/lib/Target/X86: X86Instr64bit.td X86InstrInfo.cpp X86InstrInfo.td Message-ID: <200812012344.mB1Ni8xt022673@zion.cs.uiuc.edu> Author: void Date: Mon Dec 1 17:44:08 2008 New Revision: 60383 URL: http://llvm.org/viewvc/llvm-project?rev=60383&view=rev Log: Temporarily revert r60382. It caused CodeGen/X86/i2k.ll and others to fail. Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td llvm/trunk/lib/Target/X86/X86InstrInfo.cpp llvm/trunk/lib/Target/X86/X86InstrInfo.td Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Instr64bit.td?rev=60383&r1=60382&r2=60383&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Instr64bit.td (original) +++ llvm/trunk/lib/Target/X86/X86Instr64bit.td Mon Dec 1 17:44:08 2008 @@ -314,73 +314,59 @@ let isCommutable = 1 in def ADD64rr : RI<0x01, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), "add{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (add GR64:$src1, GR64:$src2)), - (implicit EFLAGS)]>; + [(set GR64:$dst, (add GR64:$src1, GR64:$src2))]>; def ADD64ri32 : RIi32<0x81, MRM0r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2), "add{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (add GR64:$src1, i64immSExt32:$src2)), - (implicit EFLAGS)]>; + [(set GR64:$dst, (add GR64:$src1, i64immSExt32:$src2))]>; def ADD64ri8 : RIi8<0x83, MRM0r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2), "add{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (add GR64:$src1, i64immSExt8:$src2)), - (implicit EFLAGS)]>; + [(set GR64:$dst, (add GR64:$src1, i64immSExt8:$src2))]>; } // isConvertibleToThreeAddress def ADD64rm : RI<0x03, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), "add{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (add GR64:$src1, (load addr:$src2))), - (implicit EFLAGS)]>; + [(set GR64:$dst, (add GR64:$src1, (load addr:$src2)))]>; } // isTwoAddress def ADD64mr : RI<0x01, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2), "add{q}\t{$src2, $dst|$dst, $src2}", - [(store (add (load addr:$dst), GR64:$src2), addr:$dst), - (implicit EFLAGS)]>; + [(store (add (load addr:$dst), GR64:$src2), addr:$dst)]>; def ADD64mi32 : RIi32<0x81, MRM0m, (outs), (ins i64mem:$dst, i64i32imm :$src2), "add{q}\t{$src2, $dst|$dst, $src2}", - [(store (add (load addr:$dst), i64immSExt32:$src2), addr:$dst), - (implicit EFLAGS)]>; + [(store (add (load addr:$dst), i64immSExt32:$src2), addr:$dst)]>; def ADD64mi8 : RIi8<0x83, MRM0m, (outs), (ins i64mem:$dst, i64i8imm :$src2), "add{q}\t{$src2, $dst|$dst, $src2}", - [(store (add (load addr:$dst), i64immSExt8:$src2), addr:$dst), - (implicit EFLAGS)]>; + [(store (add (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>; let Uses = [EFLAGS] in { let isTwoAddress = 1 in { let isCommutable = 1 in def ADC64rr : RI<0x11, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), "adc{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (adde GR64:$src1, GR64:$src2)), - (implicit EFLAGS)]>; + [(set GR64:$dst, (adde GR64:$src1, GR64:$src2))]>; def ADC64rm : RI<0x13, MRMSrcMem , (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), "adc{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (adde GR64:$src1, (load addr:$src2))), - (implicit EFLAGS)]>; + [(set GR64:$dst, (adde GR64:$src1, (load addr:$src2)))]>; def ADC64ri32 : RIi32<0x81, MRM2r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2), "adc{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (adde GR64:$src1, i64immSExt32:$src2)), - (implicit EFLAGS)]>; + [(set GR64:$dst, (adde GR64:$src1, i64immSExt32:$src2))]>; def ADC64ri8 : RIi8<0x83, MRM2r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2), "adc{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (adde GR64:$src1, i64immSExt8:$src2)), - (implicit EFLAGS)]>; + [(set GR64:$dst, (adde GR64:$src1, i64immSExt8:$src2))]>; } // isTwoAddress def ADC64mr : RI<0x11, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2), "adc{q}\t{$src2, $dst|$dst, $src2}", - [(store (adde (load addr:$dst), GR64:$src2), addr:$dst), - (implicit EFLAGS)]>; + [(store (adde (load addr:$dst), GR64:$src2), addr:$dst)]>; def ADC64mi32 : RIi32<0x81, MRM2m, (outs), (ins i64mem:$dst, i64i32imm:$src2), "adc{q}\t{$src2, $dst|$dst, $src2}", - [(store (adde (load addr:$dst), i64immSExt8:$src2), addr:$dst), - (implicit EFLAGS)]>; + [(store (adde (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>; def ADC64mi8 : RIi8<0x83, MRM2m, (outs), (ins i64mem:$dst, i64i8imm :$src2), "adc{q}\t{$src2, $dst|$dst, $src2}", - [(store (adde (load addr:$dst), i64immSExt8:$src2), addr:$dst), - (implicit EFLAGS)]>; + [(store (adde (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>; } // Uses = [EFLAGS] let isTwoAddress = 1 in { Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=60383&r1=60382&r2=60383&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Mon Dec 1 17:44:08 2008 @@ -280,18 +280,14 @@ { X86::SETAr, X86::SETAm, 0 }, { X86::SETBEr, X86::SETBEm, 0 }, { X86::SETBr, X86::SETBm, 0 }, - { X86::SETCr, X86::SETCm, 0 }, { X86::SETEr, X86::SETEm, 0 }, { X86::SETGEr, X86::SETGEm, 0 }, { X86::SETGr, X86::SETGm, 0 }, { X86::SETLEr, X86::SETLEm, 0 }, { X86::SETLr, X86::SETLm, 0 }, - { X86::SETNCr, X86::SETNCm, 0 }, { X86::SETNEr, X86::SETNEm, 0 }, - { X86::SETNOr, X86::SETNOm, 0 }, { X86::SETNPr, X86::SETNPm, 0 }, { X86::SETNSr, X86::SETNSm, 0 }, - { X86::SETOr, X86::SETOm, 0 }, { X86::SETPr, X86::SETPm, 0 }, { X86::SETSr, X86::SETSm, 0 }, { X86::TAILJMPr, X86::TAILJMPm, 1 }, Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=60383&r1=60382&r2=60383&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Mon Dec 1 17:44:08 2008 @@ -1926,136 +1926,110 @@ def ADD8rr : I<0x00, MRMDestReg, (outs GR8 :$dst), (ins GR8 :$src1, GR8 :$src2), "add{b}\t{$src2, $dst|$dst, $src2}", - [(set GR8:$dst, (add GR8:$src1, GR8:$src2)), - (implicit EFLAGS)]>; + [(set GR8:$dst, (add GR8:$src1, GR8:$src2))]>; let isConvertibleToThreeAddress = 1 in { // Can transform into LEA. def ADD16rr : I<0x01, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2), "add{w}\t{$src2, $dst|$dst, $src2}", - [(set GR16:$dst, (add GR16:$src1, GR16:$src2)), - (implicit EFLAGS)]>, OpSize; + [(set GR16:$dst, (add GR16:$src1, GR16:$src2))]>, OpSize; def ADD32rr : I<0x01, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), "add{l}\t{$src2, $dst|$dst, $src2}", - [(set GR32:$dst, (add GR32:$src1, GR32:$src2)), - (implicit EFLAGS)]>; + [(set GR32:$dst, (add GR32:$src1, GR32:$src2))]>; } // end isConvertibleToThreeAddress } // end isCommutable def ADD8rm : I<0x02, MRMSrcMem, (outs GR8 :$dst), (ins GR8 :$src1, i8mem :$src2), "add{b}\t{$src2, $dst|$dst, $src2}", - [(set GR8:$dst, (add GR8:$src1, (load addr:$src2))), - (implicit EFLAGS)]>; + [(set GR8:$dst, (add GR8:$src1, (load addr:$src2)))]>; def ADD16rm : I<0x03, MRMSrcMem, (outs GR16:$dst), (ins GR16:$src1, i16mem:$src2), "add{w}\t{$src2, $dst|$dst, $src2}", - [(set GR16:$dst, (add GR16:$src1, (load addr:$src2))), - (implicit EFLAGS)]>, OpSize; + [(set GR16:$dst, (add GR16:$src1, (load addr:$src2)))]>,OpSize; def ADD32rm : I<0x03, MRMSrcMem, (outs GR32:$dst), (ins GR32:$src1, i32mem:$src2), "add{l}\t{$src2, $dst|$dst, $src2}", - [(set GR32:$dst, (add GR32:$src1, (load addr:$src2))), - (implicit EFLAGS)]>; + [(set GR32:$dst, (add GR32:$src1, (load addr:$src2)))]>; def ADD8ri : Ii8<0x80, MRM0r, (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2), "add{b}\t{$src2, $dst|$dst, $src2}", - [(set GR8:$dst, (add GR8:$src1, imm:$src2)), - (implicit EFLAGS)]>; + [(set GR8:$dst, (add GR8:$src1, imm:$src2))]>; let isConvertibleToThreeAddress = 1 in { // Can transform into LEA. def ADD16ri : Ii16<0x81, MRM0r, (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2), "add{w}\t{$src2, $dst|$dst, $src2}", - [(set GR16:$dst, (add GR16:$src1, imm:$src2)), - (implicit EFLAGS)]>, OpSize; + [(set GR16:$dst, (add GR16:$src1, imm:$src2))]>, OpSize; def ADD32ri : Ii32<0x81, MRM0r, (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2), "add{l}\t{$src2, $dst|$dst, $src2}", - [(set GR32:$dst, (add GR32:$src1, imm:$src2)), - (implicit EFLAGS)]>; + [(set GR32:$dst, (add GR32:$src1, imm:$src2))]>; def ADD16ri8 : Ii8<0x83, MRM0r, (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2), "add{w}\t{$src2, $dst|$dst, $src2}", - [(set GR16:$dst, (add GR16:$src1, i16immSExt8:$src2)), - (implicit EFLAGS)]>, OpSize; + [(set GR16:$dst, (add GR16:$src1, i16immSExt8:$src2))]>, OpSize; def ADD32ri8 : Ii8<0x83, MRM0r, (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2), "add{l}\t{$src2, $dst|$dst, $src2}", - [(set GR32:$dst, (add GR32:$src1, i32immSExt8:$src2)), - (implicit EFLAGS)]>; + [(set GR32:$dst, (add GR32:$src1, i32immSExt8:$src2))]>; } let isTwoAddress = 0 in { def ADD8mr : I<0x00, MRMDestMem, (outs), (ins i8mem :$dst, GR8 :$src2), "add{b}\t{$src2, $dst|$dst, $src2}", - [(store (add (load addr:$dst), GR8:$src2), addr:$dst), - (implicit EFLAGS)]>; + [(store (add (load addr:$dst), GR8:$src2), addr:$dst)]>; def ADD16mr : I<0x01, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src2), "add{w}\t{$src2, $dst|$dst, $src2}", - [(store (add (load addr:$dst), GR16:$src2), addr:$dst), - (implicit EFLAGS)]>, + [(store (add (load addr:$dst), GR16:$src2), addr:$dst)]>, OpSize; def ADD32mr : I<0x01, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2), "add{l}\t{$src2, $dst|$dst, $src2}", - [(store (add (load addr:$dst), GR32:$src2), addr:$dst), - (implicit EFLAGS)]>; + [(store (add (load addr:$dst), GR32:$src2), addr:$dst)]>; def ADD8mi : Ii8<0x80, MRM0m, (outs), (ins i8mem :$dst, i8imm :$src2), "add{b}\t{$src2, $dst|$dst, $src2}", - [(store (add (loadi8 addr:$dst), imm:$src2), addr:$dst), - (implicit EFLAGS)]>; + [(store (add (loadi8 addr:$dst), imm:$src2), addr:$dst)]>; def ADD16mi : Ii16<0x81, MRM0m, (outs), (ins i16mem:$dst, i16imm:$src2), "add{w}\t{$src2, $dst|$dst, $src2}", - [(store (add (loadi16 addr:$dst), imm:$src2), addr:$dst), - (implicit EFLAGS)]>, + [(store (add (loadi16 addr:$dst), imm:$src2), addr:$dst)]>, OpSize; def ADD32mi : Ii32<0x81, MRM0m, (outs), (ins i32mem:$dst, i32imm:$src2), "add{l}\t{$src2, $dst|$dst, $src2}", - [(store (add (loadi32 addr:$dst), imm:$src2), addr:$dst), - (implicit EFLAGS)]>; + [(store (add (loadi32 addr:$dst), imm:$src2), addr:$dst)]>; def ADD16mi8 : Ii8<0x83, MRM0m, (outs), (ins i16mem:$dst, i16i8imm :$src2), "add{w}\t{$src2, $dst|$dst, $src2}", - [(store (add (load addr:$dst), i16immSExt8:$src2), addr:$dst), - (implicit EFLAGS)]>, + [(store (add (load addr:$dst), i16immSExt8:$src2), addr:$dst)]>, OpSize; def ADD32mi8 : Ii8<0x83, MRM0m, (outs), (ins i32mem:$dst, i32i8imm :$src2), "add{l}\t{$src2, $dst|$dst, $src2}", - [(store (add (load addr:$dst), i32immSExt8:$src2), addr:$dst), - (implicit EFLAGS)]>; + [(store (add (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>; } let Uses = [EFLAGS] in { let isCommutable = 1 in { // X = ADC Y, Z --> X = ADC Z, Y def ADC32rr : I<0x11, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), "adc{l}\t{$src2, $dst|$dst, $src2}", - [(set GR32:$dst, (adde GR32:$src1, GR32:$src2)), - (implicit EFLAGS)]>; + [(set GR32:$dst, (adde GR32:$src1, GR32:$src2))]>; } def ADC32rm : I<0x13, MRMSrcMem , (outs GR32:$dst), (ins GR32:$src1, i32mem:$src2), "adc{l}\t{$src2, $dst|$dst, $src2}", - [(set GR32:$dst, (adde GR32:$src1, (load addr:$src2))), - (implicit EFLAGS)]>; + [(set GR32:$dst, (adde GR32:$src1, (load addr:$src2)))]>; def ADC32ri : Ii32<0x81, MRM2r, (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2), "adc{l}\t{$src2, $dst|$dst, $src2}", - [(set GR32:$dst, (adde GR32:$src1, imm:$src2)), - (implicit EFLAGS)]>; + [(set GR32:$dst, (adde GR32:$src1, imm:$src2))]>; def ADC32ri8 : Ii8<0x83, MRM2r, (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2), "adc{l}\t{$src2, $dst|$dst, $src2}", - [(set GR32:$dst, (adde GR32:$src1, i32immSExt8:$src2)), - (implicit EFLAGS)]>; + [(set GR32:$dst, (adde GR32:$src1, i32immSExt8:$src2))]>; let isTwoAddress = 0 in { def ADC32mr : I<0x11, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2), "adc{l}\t{$src2, $dst|$dst, $src2}", - [(store (adde (load addr:$dst), GR32:$src2), addr:$dst), - (implicit EFLAGS)]>; + [(store (adde (load addr:$dst), GR32:$src2), addr:$dst)]>; def ADC32mi : Ii32<0x81, MRM2m, (outs), (ins i32mem:$dst, i32imm:$src2), "adc{l}\t{$src2, $dst|$dst, $src2}", - [(store (adde (loadi32 addr:$dst), imm:$src2), addr:$dst), - (implicit EFLAGS)]>; + [(store (adde (loadi32 addr:$dst), imm:$src2), addr:$dst)]>; def ADC32mi8 : Ii8<0x83, MRM2m, (outs), (ins i32mem:$dst, i32i8imm :$src2), "adc{l}\t{$src2, $dst|$dst, $src2}", - [(store (adde (load addr:$dst), i32immSExt8:$src2), addr:$dst), - (implicit EFLAGS)]>; + [(store (adde (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>; } } // Uses = [EFLAGS] @@ -2298,7 +2272,6 @@ "sete\t$dst", [(store (X86setcc X86_COND_E, EFLAGS), addr:$dst)]>, TB; // [mem8] = == - def SETNEr : I<0x95, MRM0r, (outs GR8 :$dst), (ins), "setne\t$dst", @@ -2309,7 +2282,6 @@ "setne\t$dst", [(store (X86setcc X86_COND_NE, EFLAGS), addr:$dst)]>, TB; // [mem8] = != - def SETLr : I<0x9C, MRM0r, (outs GR8 :$dst), (ins), "setl\t$dst", @@ -2320,7 +2292,6 @@ "setl\t$dst", [(store (X86setcc X86_COND_L, EFLAGS), addr:$dst)]>, TB; // [mem8] = < signed - def SETGEr : I<0x9D, MRM0r, (outs GR8 :$dst), (ins), "setge\t$dst", @@ -2331,7 +2302,6 @@ "setge\t$dst", [(store (X86setcc X86_COND_GE, EFLAGS), addr:$dst)]>, TB; // [mem8] = >= signed - def SETLEr : I<0x9E, MRM0r, (outs GR8 :$dst), (ins), "setle\t$dst", @@ -2342,7 +2312,6 @@ "setle\t$dst", [(store (X86setcc X86_COND_LE, EFLAGS), addr:$dst)]>, TB; // [mem8] = <= signed - def SETGr : I<0x9F, MRM0r, (outs GR8 :$dst), (ins), "setg\t$dst", @@ -2364,7 +2333,6 @@ "setb\t$dst", [(store (X86setcc X86_COND_B, EFLAGS), addr:$dst)]>, TB; // [mem8] = < unsign - def SETAEr : I<0x93, MRM0r, (outs GR8 :$dst), (ins), "setae\t$dst", @@ -2375,7 +2343,6 @@ "setae\t$dst", [(store (X86setcc X86_COND_AE, EFLAGS), addr:$dst)]>, TB; // [mem8] = >= unsign - def SETBEr : I<0x96, MRM0r, (outs GR8 :$dst), (ins), "setbe\t$dst", @@ -2386,7 +2353,6 @@ "setbe\t$dst", [(store (X86setcc X86_COND_BE, EFLAGS), addr:$dst)]>, TB; // [mem8] = <= unsign - def SETAr : I<0x97, MRM0r, (outs GR8 :$dst), (ins), "seta\t$dst", @@ -2418,7 +2384,6 @@ "setns\t$dst", [(store (X86setcc X86_COND_NS, EFLAGS), addr:$dst)]>, TB; // [mem8] = ! - def SETPr : I<0x9A, MRM0r, (outs GR8 :$dst), (ins), "setp\t$dst", @@ -2439,48 +2404,6 @@ "setnp\t$dst", [(store (X86setcc X86_COND_NP, EFLAGS), addr:$dst)]>, TB; // [mem8] = not parity - -def SETOr : I<0x90, MRM0r, - (outs GR8 :$dst), (ins), - "seto\t$dst", - [(set GR8:$dst, (X86setcc X86_COND_O, EFLAGS))]>, - TB; // GR8 = overflow -def SETOm : I<0x90, MRM0m, - (outs), (ins i8mem:$dst), - "seto\t$dst", - [(store (X86setcc X86_COND_O, EFLAGS), addr:$dst)]>, - TB; // [mem8] = overflow -def SETNOr : I<0x91, MRM0r, - (outs GR8 :$dst), (ins), - "setno\t$dst", - [(set GR8:$dst, (X86setcc X86_COND_NO, EFLAGS))]>, - TB; // GR8 = not overflow -def SETNOm : I<0x91, MRM0m, - (outs), (ins i8mem:$dst), - "setno\t$dst", - [(store (X86setcc X86_COND_NO, EFLAGS), addr:$dst)]>, - TB; // [mem8] = not overflow - -def SETCr : I<0x92, MRM0r, - (outs GR8 :$dst), (ins), - "setc\t$dst", - [(set GR8:$dst, (X86setcc X86_COND_C, EFLAGS))]>, - TB; // GR8 = carry -def SETCm : I<0x92, MRM0m, - (outs), (ins i8mem:$dst), - "setc\t$dst", - [(store (X86setcc X86_COND_C, EFLAGS), addr:$dst)]>, - TB; // [mem8] = carry -def SETNCr : I<0x93, MRM0r, - (outs GR8 :$dst), (ins), - "setnc\t$dst", - [(set GR8:$dst, (X86setcc X86_COND_NC, EFLAGS))]>, - TB; // GR8 = not carry -def SETNCm : I<0x93, MRM0m, - (outs), (ins i8mem:$dst), - "setnc\t$dst", - [(store (X86setcc X86_COND_NC, EFLAGS), addr:$dst)]>, - TB; // [mem8] = not carry } // Uses = [EFLAGS] From isanbard at gmail.com Mon Dec 1 18:07:05 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 02 Dec 2008 00:07:05 -0000 Subject: [llvm-commits] [llvm] r60385 - in /llvm/trunk/lib/Target/X86: X86Instr64bit.td X86InstrInfo.cpp X86InstrInfo.td Message-ID: <200812020007.mB2075Ye023327@zion.cs.uiuc.edu> Author: void Date: Mon Dec 1 18:07:05 2008 New Revision: 60385 URL: http://llvm.org/viewvc/llvm-project?rev=60385&view=rev Log: Reapply r60382. This time, don't mark "ADC" nodes with "implicit EFLAGS". Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td llvm/trunk/lib/Target/X86/X86InstrInfo.cpp llvm/trunk/lib/Target/X86/X86InstrInfo.td Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Instr64bit.td?rev=60385&r1=60384&r2=60385&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Instr64bit.td (original) +++ llvm/trunk/lib/Target/X86/X86Instr64bit.td Mon Dec 1 18:07:05 2008 @@ -314,30 +314,37 @@ let isCommutable = 1 in def ADD64rr : RI<0x01, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), "add{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (add GR64:$src1, GR64:$src2))]>; + [(set GR64:$dst, (add GR64:$src1, GR64:$src2)), + (implicit EFLAGS)]>; def ADD64ri32 : RIi32<0x81, MRM0r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2), "add{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (add GR64:$src1, i64immSExt32:$src2))]>; + [(set GR64:$dst, (add GR64:$src1, i64immSExt32:$src2)), + (implicit EFLAGS)]>; def ADD64ri8 : RIi8<0x83, MRM0r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2), "add{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (add GR64:$src1, i64immSExt8:$src2))]>; + [(set GR64:$dst, (add GR64:$src1, i64immSExt8:$src2)), + (implicit EFLAGS)]>; } // isConvertibleToThreeAddress def ADD64rm : RI<0x03, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), "add{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (add GR64:$src1, (load addr:$src2)))]>; + [(set GR64:$dst, (add GR64:$src1, (load addr:$src2))), + (implicit EFLAGS)]>; } // isTwoAddress def ADD64mr : RI<0x01, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2), "add{q}\t{$src2, $dst|$dst, $src2}", - [(store (add (load addr:$dst), GR64:$src2), addr:$dst)]>; + [(store (add (load addr:$dst), GR64:$src2), addr:$dst), + (implicit EFLAGS)]>; def ADD64mi32 : RIi32<0x81, MRM0m, (outs), (ins i64mem:$dst, i64i32imm :$src2), "add{q}\t{$src2, $dst|$dst, $src2}", - [(store (add (load addr:$dst), i64immSExt32:$src2), addr:$dst)]>; + [(store (add (load addr:$dst), i64immSExt32:$src2), addr:$dst), + (implicit EFLAGS)]>; def ADD64mi8 : RIi8<0x83, MRM0m, (outs), (ins i64mem:$dst, i64i8imm :$src2), "add{q}\t{$src2, $dst|$dst, $src2}", - [(store (add (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>; + [(store (add (load addr:$dst), i64immSExt8:$src2), addr:$dst), + (implicit EFLAGS)]>; let Uses = [EFLAGS] in { let isTwoAddress = 1 in { @@ -363,10 +370,10 @@ [(store (adde (load addr:$dst), GR64:$src2), addr:$dst)]>; def ADC64mi32 : RIi32<0x81, MRM2m, (outs), (ins i64mem:$dst, i64i32imm:$src2), "adc{q}\t{$src2, $dst|$dst, $src2}", - [(store (adde (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>; + [(store (adde (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>; def ADC64mi8 : RIi8<0x83, MRM2m, (outs), (ins i64mem:$dst, i64i8imm :$src2), "adc{q}\t{$src2, $dst|$dst, $src2}", - [(store (adde (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>; + [(store (adde (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>; } // Uses = [EFLAGS] let isTwoAddress = 1 in { Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=60385&r1=60384&r2=60385&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Mon Dec 1 18:07:05 2008 @@ -280,14 +280,18 @@ { X86::SETAr, X86::SETAm, 0 }, { X86::SETBEr, X86::SETBEm, 0 }, { X86::SETBr, X86::SETBm, 0 }, + { X86::SETCr, X86::SETCm, 0 }, { X86::SETEr, X86::SETEm, 0 }, { X86::SETGEr, X86::SETGEm, 0 }, { X86::SETGr, X86::SETGm, 0 }, { X86::SETLEr, X86::SETLEm, 0 }, { X86::SETLr, X86::SETLm, 0 }, + { X86::SETNCr, X86::SETNCm, 0 }, { X86::SETNEr, X86::SETNEm, 0 }, + { X86::SETNOr, X86::SETNOm, 0 }, { X86::SETNPr, X86::SETNPm, 0 }, { X86::SETNSr, X86::SETNSm, 0 }, + { X86::SETOr, X86::SETOm, 0 }, { X86::SETPr, X86::SETPm, 0 }, { X86::SETSr, X86::SETSm, 0 }, { X86::TAILJMPr, X86::TAILJMPm, 1 }, Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=60385&r1=60384&r2=60385&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Mon Dec 1 18:07:05 2008 @@ -1926,82 +1926,101 @@ def ADD8rr : I<0x00, MRMDestReg, (outs GR8 :$dst), (ins GR8 :$src1, GR8 :$src2), "add{b}\t{$src2, $dst|$dst, $src2}", - [(set GR8:$dst, (add GR8:$src1, GR8:$src2))]>; + [(set GR8:$dst, (add GR8:$src1, GR8:$src2)), + (implicit EFLAGS)]>; let isConvertibleToThreeAddress = 1 in { // Can transform into LEA. def ADD16rr : I<0x01, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2), "add{w}\t{$src2, $dst|$dst, $src2}", - [(set GR16:$dst, (add GR16:$src1, GR16:$src2))]>, OpSize; + [(set GR16:$dst, (add GR16:$src1, GR16:$src2)), + (implicit EFLAGS)]>, OpSize; def ADD32rr : I<0x01, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), "add{l}\t{$src2, $dst|$dst, $src2}", - [(set GR32:$dst, (add GR32:$src1, GR32:$src2))]>; + [(set GR32:$dst, (add GR32:$src1, GR32:$src2)), + (implicit EFLAGS)]>; } // end isConvertibleToThreeAddress } // end isCommutable def ADD8rm : I<0x02, MRMSrcMem, (outs GR8 :$dst), (ins GR8 :$src1, i8mem :$src2), "add{b}\t{$src2, $dst|$dst, $src2}", - [(set GR8:$dst, (add GR8:$src1, (load addr:$src2)))]>; + [(set GR8:$dst, (add GR8:$src1, (load addr:$src2))), + (implicit EFLAGS)]>; def ADD16rm : I<0x03, MRMSrcMem, (outs GR16:$dst), (ins GR16:$src1, i16mem:$src2), "add{w}\t{$src2, $dst|$dst, $src2}", - [(set GR16:$dst, (add GR16:$src1, (load addr:$src2)))]>,OpSize; + [(set GR16:$dst, (add GR16:$src1, (load addr:$src2))), + (implicit EFLAGS)]>, OpSize; def ADD32rm : I<0x03, MRMSrcMem, (outs GR32:$dst), (ins GR32:$src1, i32mem:$src2), "add{l}\t{$src2, $dst|$dst, $src2}", - [(set GR32:$dst, (add GR32:$src1, (load addr:$src2)))]>; + [(set GR32:$dst, (add GR32:$src1, (load addr:$src2))), + (implicit EFLAGS)]>; def ADD8ri : Ii8<0x80, MRM0r, (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2), "add{b}\t{$src2, $dst|$dst, $src2}", - [(set GR8:$dst, (add GR8:$src1, imm:$src2))]>; + [(set GR8:$dst, (add GR8:$src1, imm:$src2)), + (implicit EFLAGS)]>; let isConvertibleToThreeAddress = 1 in { // Can transform into LEA. def ADD16ri : Ii16<0x81, MRM0r, (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2), "add{w}\t{$src2, $dst|$dst, $src2}", - [(set GR16:$dst, (add GR16:$src1, imm:$src2))]>, OpSize; + [(set GR16:$dst, (add GR16:$src1, imm:$src2)), + (implicit EFLAGS)]>, OpSize; def ADD32ri : Ii32<0x81, MRM0r, (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2), "add{l}\t{$src2, $dst|$dst, $src2}", - [(set GR32:$dst, (add GR32:$src1, imm:$src2))]>; + [(set GR32:$dst, (add GR32:$src1, imm:$src2)), + (implicit EFLAGS)]>; def ADD16ri8 : Ii8<0x83, MRM0r, (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2), "add{w}\t{$src2, $dst|$dst, $src2}", - [(set GR16:$dst, (add GR16:$src1, i16immSExt8:$src2))]>, OpSize; + [(set GR16:$dst, (add GR16:$src1, i16immSExt8:$src2)), + (implicit EFLAGS)]>, OpSize; def ADD32ri8 : Ii8<0x83, MRM0r, (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2), "add{l}\t{$src2, $dst|$dst, $src2}", - [(set GR32:$dst, (add GR32:$src1, i32immSExt8:$src2))]>; + [(set GR32:$dst, (add GR32:$src1, i32immSExt8:$src2)), + (implicit EFLAGS)]>; } let isTwoAddress = 0 in { def ADD8mr : I<0x00, MRMDestMem, (outs), (ins i8mem :$dst, GR8 :$src2), "add{b}\t{$src2, $dst|$dst, $src2}", - [(store (add (load addr:$dst), GR8:$src2), addr:$dst)]>; + [(store (add (load addr:$dst), GR8:$src2), addr:$dst), + (implicit EFLAGS)]>; def ADD16mr : I<0x01, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src2), "add{w}\t{$src2, $dst|$dst, $src2}", - [(store (add (load addr:$dst), GR16:$src2), addr:$dst)]>, + [(store (add (load addr:$dst), GR16:$src2), addr:$dst), + (implicit EFLAGS)]>, OpSize; def ADD32mr : I<0x01, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2), "add{l}\t{$src2, $dst|$dst, $src2}", - [(store (add (load addr:$dst), GR32:$src2), addr:$dst)]>; + [(store (add (load addr:$dst), GR32:$src2), addr:$dst), + (implicit EFLAGS)]>; def ADD8mi : Ii8<0x80, MRM0m, (outs), (ins i8mem :$dst, i8imm :$src2), "add{b}\t{$src2, $dst|$dst, $src2}", - [(store (add (loadi8 addr:$dst), imm:$src2), addr:$dst)]>; + [(store (add (loadi8 addr:$dst), imm:$src2), addr:$dst), + (implicit EFLAGS)]>; def ADD16mi : Ii16<0x81, MRM0m, (outs), (ins i16mem:$dst, i16imm:$src2), "add{w}\t{$src2, $dst|$dst, $src2}", - [(store (add (loadi16 addr:$dst), imm:$src2), addr:$dst)]>, + [(store (add (loadi16 addr:$dst), imm:$src2), addr:$dst), + (implicit EFLAGS)]>, OpSize; def ADD32mi : Ii32<0x81, MRM0m, (outs), (ins i32mem:$dst, i32imm:$src2), "add{l}\t{$src2, $dst|$dst, $src2}", - [(store (add (loadi32 addr:$dst), imm:$src2), addr:$dst)]>; + [(store (add (loadi32 addr:$dst), imm:$src2), addr:$dst), + (implicit EFLAGS)]>; def ADD16mi8 : Ii8<0x83, MRM0m, (outs), (ins i16mem:$dst, i16i8imm :$src2), "add{w}\t{$src2, $dst|$dst, $src2}", - [(store (add (load addr:$dst), i16immSExt8:$src2), addr:$dst)]>, + [(store (add (load addr:$dst), i16immSExt8:$src2), addr:$dst), + (implicit EFLAGS)]>, OpSize; def ADD32mi8 : Ii8<0x83, MRM0m, (outs), (ins i32mem:$dst, i32i8imm :$src2), "add{l}\t{$src2, $dst|$dst, $src2}", - [(store (add (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>; + [(store (add (load addr:$dst), i32immSExt8:$src2), addr:$dst), + (implicit EFLAGS)]>; } let Uses = [EFLAGS] in { @@ -2029,7 +2048,7 @@ [(store (adde (loadi32 addr:$dst), imm:$src2), addr:$dst)]>; def ADC32mi8 : Ii8<0x83, MRM2m, (outs), (ins i32mem:$dst, i32i8imm :$src2), "adc{l}\t{$src2, $dst|$dst, $src2}", - [(store (adde (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>; + [(store (adde (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>; } } // Uses = [EFLAGS] @@ -2272,6 +2291,7 @@ "sete\t$dst", [(store (X86setcc X86_COND_E, EFLAGS), addr:$dst)]>, TB; // [mem8] = == + def SETNEr : I<0x95, MRM0r, (outs GR8 :$dst), (ins), "setne\t$dst", @@ -2282,6 +2302,7 @@ "setne\t$dst", [(store (X86setcc X86_COND_NE, EFLAGS), addr:$dst)]>, TB; // [mem8] = != + def SETLr : I<0x9C, MRM0r, (outs GR8 :$dst), (ins), "setl\t$dst", @@ -2292,6 +2313,7 @@ "setl\t$dst", [(store (X86setcc X86_COND_L, EFLAGS), addr:$dst)]>, TB; // [mem8] = < signed + def SETGEr : I<0x9D, MRM0r, (outs GR8 :$dst), (ins), "setge\t$dst", @@ -2302,6 +2324,7 @@ "setge\t$dst", [(store (X86setcc X86_COND_GE, EFLAGS), addr:$dst)]>, TB; // [mem8] = >= signed + def SETLEr : I<0x9E, MRM0r, (outs GR8 :$dst), (ins), "setle\t$dst", @@ -2312,6 +2335,7 @@ "setle\t$dst", [(store (X86setcc X86_COND_LE, EFLAGS), addr:$dst)]>, TB; // [mem8] = <= signed + def SETGr : I<0x9F, MRM0r, (outs GR8 :$dst), (ins), "setg\t$dst", @@ -2333,6 +2357,7 @@ "setb\t$dst", [(store (X86setcc X86_COND_B, EFLAGS), addr:$dst)]>, TB; // [mem8] = < unsign + def SETAEr : I<0x93, MRM0r, (outs GR8 :$dst), (ins), "setae\t$dst", @@ -2343,6 +2368,7 @@ "setae\t$dst", [(store (X86setcc X86_COND_AE, EFLAGS), addr:$dst)]>, TB; // [mem8] = >= unsign + def SETBEr : I<0x96, MRM0r, (outs GR8 :$dst), (ins), "setbe\t$dst", @@ -2353,6 +2379,7 @@ "setbe\t$dst", [(store (X86setcc X86_COND_BE, EFLAGS), addr:$dst)]>, TB; // [mem8] = <= unsign + def SETAr : I<0x97, MRM0r, (outs GR8 :$dst), (ins), "seta\t$dst", @@ -2384,6 +2411,7 @@ "setns\t$dst", [(store (X86setcc X86_COND_NS, EFLAGS), addr:$dst)]>, TB; // [mem8] = ! + def SETPr : I<0x9A, MRM0r, (outs GR8 :$dst), (ins), "setp\t$dst", @@ -2404,6 +2432,48 @@ "setnp\t$dst", [(store (X86setcc X86_COND_NP, EFLAGS), addr:$dst)]>, TB; // [mem8] = not parity + +def SETOr : I<0x90, MRM0r, + (outs GR8 :$dst), (ins), + "seto\t$dst", + [(set GR8:$dst, (X86setcc X86_COND_O, EFLAGS))]>, + TB; // GR8 = overflow +def SETOm : I<0x90, MRM0m, + (outs), (ins i8mem:$dst), + "seto\t$dst", + [(store (X86setcc X86_COND_O, EFLAGS), addr:$dst)]>, + TB; // [mem8] = overflow +def SETNOr : I<0x91, MRM0r, + (outs GR8 :$dst), (ins), + "setno\t$dst", + [(set GR8:$dst, (X86setcc X86_COND_NO, EFLAGS))]>, + TB; // GR8 = not overflow +def SETNOm : I<0x91, MRM0m, + (outs), (ins i8mem:$dst), + "setno\t$dst", + [(store (X86setcc X86_COND_NO, EFLAGS), addr:$dst)]>, + TB; // [mem8] = not overflow + +def SETCr : I<0x92, MRM0r, + (outs GR8 :$dst), (ins), + "setc\t$dst", + [(set GR8:$dst, (X86setcc X86_COND_C, EFLAGS))]>, + TB; // GR8 = carry +def SETCm : I<0x92, MRM0m, + (outs), (ins i8mem:$dst), + "setc\t$dst", + [(store (X86setcc X86_COND_C, EFLAGS), addr:$dst)]>, + TB; // [mem8] = carry +def SETNCr : I<0x93, MRM0r, + (outs GR8 :$dst), (ins), + "setnc\t$dst", + [(set GR8:$dst, (X86setcc X86_COND_NC, EFLAGS))]>, + TB; // GR8 = not carry +def SETNCm : I<0x93, MRM0m, + (outs), (ins i8mem:$dst), + "setnc\t$dst", + [(store (X86setcc X86_COND_NC, EFLAGS), addr:$dst)]>, + TB; // [mem8] = not carry } // Uses = [EFLAGS] From isanbard at gmail.com Mon Dec 1 19:06:39 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 02 Dec 2008 01:06:39 -0000 Subject: [llvm-commits] [llvm] r60388 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h test/CodeGen/X86/add-with-overflow.ll Message-ID: <200812020106.mB216dUK025251@zion.cs.uiuc.edu> Author: void Date: Mon Dec 1 19:06:39 2008 New Revision: 60388 URL: http://llvm.org/viewvc/llvm-project?rev=60388&view=rev Log: Second stab at target-dependent lowering of everyone's favorite nodes: [SU]ADDO - LowerXADDO lowers [SU]ADDO into an ADD with an implicit EFLAGS define. The EFLAGS are fed into a SETCC node which has the conditional COND_O or COND_C, depending on the type of ADDO requested. - LowerBRCOND now recognizes if it's coming from a SETCC node with COND_O or COND_C set. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.h llvm/trunk/test/CodeGen/X86/add-with-overflow.ll Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=60388&r1=60387&r2=60388&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Dec 1 19:06:39 2008 @@ -5186,6 +5186,8 @@ if (Cond.getOpcode() == ISD::SETCC) Cond = LowerSETCC(Cond, DAG); + else if (Cond.getOpcode() == ISD::SADDO || Cond.getOpcode() == ISD::UADDO) + Cond = LowerXADDO(Cond, DAG); // If condition flag is set by a X86ISD::CMP, then use it as the condition // setting operand in place of the X86ISD::SETCC. @@ -5199,6 +5201,17 @@ Opc == X86ISD::UCOMI) { Cond = Cmp; addTest = false; + } else { + if (ConstantSDNode *CSDN = dyn_cast(CC.getNode())) { + switch (CSDN->getZExtValue()) { + default: break; + case X86::COND_O: + case X86::COND_C: + Cond = Cond.getNode()->getOperand(1); + addTest = false; + break; + } + } } // Also, recognize the pattern generated by an FCMP_UNE. We can emit // two branches instead of an explicit OR instruction with a @@ -6102,31 +6115,27 @@ return Op; } -SDValue X86TargetLowering::LowerXADDO(SDValue Op, SelectionDAG &DAG, - ISD::NodeType NTy) { -#if 0 - // FIXME: Lowering XADDO should use BRCOND as well. +SDValue X86TargetLowering::LowerXADDO(SDValue Op, SelectionDAG &DAG) { + // Lower the "add with overflow" instruction into a regular "add" plus a + // "setcc" instruction that checks the overflow flag. The "brcond" lowering + // looks for this combo and may remove the "setcc" instruction if the "setcc" + // has only one use. SDNode *N = Op.getNode(); + SDValue LHS = N->getOperand(0); + SDValue RHS = N->getOperand(1); - for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) { - SDNode *UseNode = *I; + // Also sets EFLAGS. + SDVTList VTs = DAG.getVTList(N->getValueType(0), MVT::i32); + SDValue Sum = DAG.getNode(ISD::ADD, VTs, LHS, RHS); + + SDValue SetCC = + DAG.getNode(X86ISD::SETCC, N->getValueType(1), + DAG.getConstant((Op.getOpcode() == ISD::SADDO) ? + X86::COND_O : X86::COND_C, + MVT::i32), SDValue(Sum.getNode(), 1)); - if (UseNode->getOpcode() == ISD::BRCOND) { - // Lower a branch on the overflow/carry flag into a "JO"/"JC" - // instruction. Convert the addition into an actual addition, not just a - // pseudo node. - SDValue LHS = N->getOperand(0); - SDValue RHS = N->getOperand(1); - SDValue Sum = DAG.getNode(ISD::ADD, LHS.getValueType(), LHS, RHS); - - SDValue Ops[] = { UseNode->getOperand(2), UseNode->getOperand(0) }; - DAG.SelectNodeTo(UseNode, (NTy == ISD::SADDO) ? X86::JO : X86::JC, - MVT::Other, Ops, 2); - return Sum; - } - } -#endif - return SDValue(); + DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1), SetCC); + return Sum; } SDValue X86TargetLowering::LowerCMP_SWAP(SDValue Op, SelectionDAG &DAG) { @@ -6143,7 +6152,7 @@ assert(Subtarget->is64Bit() && "Node not type legal!"); Reg = X86::RAX; size = 8; break; - }; + } SDValue cpIn = DAG.getCopyToReg(Op.getOperand(0), Reg, Op.getOperand(2), SDValue()); SDValue Ops[] = { cpIn.getValue(0), @@ -6247,8 +6256,8 @@ case ISD::FLT_ROUNDS_: return LowerFLT_ROUNDS_(Op, DAG); case ISD::CTLZ: return LowerCTLZ(Op, DAG); case ISD::CTTZ: return LowerCTTZ(Op, DAG); - case ISD::SADDO: return LowerXADDO(Op, DAG, ISD::SADDO); - case ISD::UADDO: return LowerXADDO(Op, DAG, ISD::UADDO); + case ISD::SADDO: return LowerXADDO(Op, DAG); + case ISD::UADDO: return LowerXADDO(Op, DAG); case ISD::READCYCLECOUNTER: return LowerREADCYCLECOUNTER(Op, DAG); } } Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=60388&r1=60387&r2=60388&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Mon Dec 1 19:06:39 2008 @@ -593,7 +593,7 @@ SDValue LowerFLT_ROUNDS_(SDValue Op, SelectionDAG &DAG); SDValue LowerCTLZ(SDValue Op, SelectionDAG &DAG); SDValue LowerCTTZ(SDValue Op, SelectionDAG &DAG); - SDValue LowerXADDO(SDValue Op, SelectionDAG &DAG, ISD::NodeType NTy); + SDValue LowerXADDO(SDValue Op, SelectionDAG &DAG); SDValue LowerCMP_SWAP(SDValue Op, SelectionDAG &DAG); SDValue LowerLOAD_SUB(SDValue Op, SelectionDAG &DAG); Modified: llvm/trunk/test/CodeGen/X86/add-with-overflow.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/add-with-overflow.ll?rev=60388&r1=60387&r2=60388&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/add-with-overflow.ll (original) +++ llvm/trunk/test/CodeGen/X86/add-with-overflow.ll Mon Dec 1 19:06:39 2008 @@ -1,6 +1,5 @@ ; RUN: llvm-as < %s | llc -march=x86 | grep {jo} | count 1 ; RUN: llvm-as < %s | llc -march=x86 | grep {jc} | count 1 -; XFAIL: * @ok = internal constant [4 x i8] c"%d\0A\00" @no = internal constant [4 x i8] c"no\0A\00" From resistor at mac.com Mon Dec 1 19:07:11 2008 From: resistor at mac.com (Owen Anderson) Date: Mon, 01 Dec 2008 17:07:11 -0800 Subject: [llvm-commits] [test-suite] r60375 - /test-suite/trunk/SingleSource/Benchmarks/Misc-C++/llloops.cpp In-Reply-To: <200812012223.mB1MNhux020136@zion.cs.uiuc.edu> References: <200812012223.mB1MNhux020136@zion.cs.uiuc.edu> Message-ID: I have no particular love of it. --Owen On Dec 1, 2008, at 2:23 PM, Chris Lattner wrote: > Author: lattner > Date: Mon Dec 1 16:23:16 2008 > New Revision: 60375 > > URL: http://llvm.org/viewvc/llvm-project?rev=60375&view=rev > Log: > Remove this benchmark, it is using undefined behavior (accessing > at least the 'u' array beyond its bounds in 'init') and is too > brain twisting to fix. Owen, if you really really really want this > benchmark, feel free to fix it and recommit. > > Removed: > test-suite/trunk/SingleSource/Benchmarks/Misc-C++/llloops.cpp > > Removed: test-suite/trunk/SingleSource/Benchmarks/Misc-C++/llloops.cpp > URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/Benchmarks/Misc-C%2B%2B/llloops.cpp?rev=60374&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- test-suite/trunk/SingleSource/Benchmarks/Misc-C++/llloops.cpp > (original) > +++ test-suite/trunk/SingleSource/Benchmarks/Misc-C++/llloops.cpp > (removed) > @@ -1,2217 +0,0 @@ > -/ > ************************************************************************ > - > * * > - * L. L. N. L. " C " K E R N E L S: M F L O P S P C V E R S I > O N * > - > * * > - * These kernels measure " C " numerical > computation * > - * rates for a spectrum of cpu-limited > computational * > - * structures or benchmarks. Mathematical through- > put * > - * is measured in units of millions of floating- > point * > - * operations executed per second, called Megaflops/ > sec. * > - > * * > - > ************************************************************************ > - * Originally from Greg Astfalk, AT&T, P.O.Box 900, > Princeton, * > - * NJ. 08540. by way of Frank McMahon > (LLNL). * > - > * * > - * Modifications by Tim Peters, Kendall Square Res. Corp. Oct > 92. * > - > * * > - * This version by Roy Longbottom (retired, ex-CCTA > UK) * > - * Roy_Longbottom > 101323.2241 at compuserve.com * > - * March > 1996 * > - > * * > - * > REFERENCE * > - > * * > - * F.H.McMahon, The Livermore Fortran > Kernels: * > - * A Computer Test Of The Numerical Performance > Range, * > - * Lawrence Livermore National > Laboratory, * > - * Livermore, California, UCRL-53745, December > 1986. * > - > * * > - * from: National Technical Information > Service * > - * U.S. Department of > Commerce * > - * 5285 Port Royal > Road * > - * Springfield, VA. > 22161 * > - > * * > - > ************************************************************************ > - * The standard "C" code accesses the FORTRAN version for > data * > - * generation and result analysis. These features have been > merged * > - * to produce a program more suitable to run on PCs. FORTRAN > features * > - * for detailed statistical analysis of the results have been > omitted. * > - > * * > - * Changes to "C" code to produce correct > results: * > - > * * > - * Kernel 2 change i = ipntp - 1; to i = > ipntp; * > - * Kernel 7 third line of inner loop change r to > q * > - > ************************************************************************ > - * > - * The kernels are executed as follows: > - * > - * parameters(x); > - * do > - * { > - * execute kernel code > - * > - * endloop(x); > - * } > - * while (count < loop); > - * > - * Function parameters obtains the loop parameters, generates all > the data > - * and makes a copy of it for use with extra loops. Timing is > started at > - * the end of the function. > - * > - * The variable loop has a defined number of passes (e.g. 7 for > kernel 1, > - * long span - see Passes in table). This is multiplied by a further > - * constant for which checksums are defined - 200/400/1600 for > long/medium > - * /short spans was chosen. The overhead of executing function > endloop is > - * calculated as below. This is deducted from the total time but > probably > - * could be ignored on PCs. > - * > - * The running time for each loop is set to a minimum of five > seconds via > - * repeating all loops until each has recorded at least 0.07 > seconds (see > - * calibration below). The extra loops required are shown under E > in the > - * tables. The data used in the loops is re-initialised from the > copy in > - * function endloop for each of the extra loops. The worst case > overhead > - * of this has been measured as less than 1% and is ignored. Note, > the > - * alternative of summing the time for each set of count passes > cannot > - * be relied upon when the time for one set is of the same order of > - * magnitude as the clock resolution (0.05 to 0.06 seconds). > Calibration > - * also gives an indication of the linearity of timing. In the > example > - * shown, the overhead of 24 occurrences of data generation, which > is > - * excluded from the main timing, is about 0.6 seconds. > - * > - * The total floating point operations for the first kernel 1 > results are > - * 200 x 7 x 15 x 5 x 1001. For some other kernels, the total is not > - * proportional to the span. > - * > - * The OK column in the tables indicates the number of correct > significant > - * digits out of 16 compared with the defined checksums. > - * > - * > - * Example of Results > - * > - * L.L.N.L. 'C' KERNELS: MFLOPS P.C. VERSION > - * > - * Calculating outer loop overhead > - * 1000 times 0.00 seconds > - * 10000 times 0.00 seconds > - * 100000 times 0.06 seconds > - * 1000000 times 0.33 seconds > - * 2000000 times 0.88 seconds > - * 4000000 times 1.59 seconds > - * 8000000 times 3.30 seconds > - * 16000000 times 6.64 seconds > - * Overhead for each loop 4.1500e-007 seconds > - * > - * Calibrating part 1 of 3 > - * > - * Loop count 4 0.94 seconds > - * Loop count 16 2.08 seconds > - * Loop count 32 3.52 seconds > - * Loop count 64 6.42 seconds > - * Loop count 128 12.31 seconds > - * > - * Loops 200 x 1 x Passes > - * > - * Kernel Floating Pt ops > - * No Passes E No Total Secs. MFLOPS Span > Checksums OK > - * ------------ -- ------------- ----- ------- ---- > ---------------------- -- > - * 1 7 x 15 5 1.051050e+008 5.10 20.60 1001 > 5.114652693224671e+004 16 > - * 2 67 x 21 4 1.091832e+008 5.20 20.98 101 > 1.539721811668384e+003 15 > - * 3 9 x 15 2 5.405400e+007 4.17 12.97 1001 > 1.000742883066364e+001 15 > - * 4 14 x 30 2 1.008000e+008 5.52 18.28 1001 > 5.999250595473891e-001 16 > - * 5 10 x 12 2 4.800000e+007 5.43 8.84 1001 > 4.548871642387267e+003 16 > - * 6 3 x 19 2 4.523520e+007 4.34 10.43 64 > 4.375116344729986e+003 16 > - * 7 4 x 10 16 1.273600e+008 4.45 28.64 995 > 6.104251075174761e+004 16 > - * 8 10 x 7 36 9.979200e+007 5.15 19.36 100 > 1.501268005625795e+005 15 > - * 9 36 x 6 17 7.417440e+007 5.20 14.26 101 > 1.189443609974981e+005 16 > - * 10 34 x 5 9 3.090600e+007 5.48 5.64 101 > 7.310369784325296e+004 16 > - * 11 11 x 15 1 3.300000e+007 5.65 5.84 1001 > 3.342910972650109e+007 16 > - * 12 12 x 30 1 7.200000e+007 6.50 11.08 1000 > 2.907141294167248e-005 16 > - * 13 36 x 4 7 1.290240e+007 6.41 2.01 64 > 1.202533961842804e+011 15 > - * 14 2 x 4 11 1.761760e+007 5.61 3.14 1001 > 3.165553044000335e+009 15 > - * 15 1 x 15 33 4.950000e+007 5.66 8.75 101 > 3.943816690352044e+004 15 > - * 16 25 x 30 10 7.950000e+007 6.14 12.95 75 > 5.650760000000000e+005 16 > - * 17 35 x 9 9 5.726700e+007 5.03 11.38 101 > 1.114641772902486e+003 16 > - * 18 2 x 11 44 9.583200e+007 5.76 16.64 100 > 1.015727037502299e+005 15 > - * 19 39 x 21 6 9.926280e+007 6.14 16.16 101 > 5.421816960147207e+002 16 > - * 20 1 x 15 26 7.800000e+007 5.93 13.16 1000 > 3.040644339351238e+007 16 > - * 21 1 x 1 2 2.525000e+007 6.37 3.96 101 > 1.597308280710200e+008 15 > - * 22 11 x 12 17 4.532880e+007 5.43 8.35 101 > 2.938604376566698e+002 15 > - * 23 8 x 12 11 1.045440e+008 5.10 20.49 100 > 3.549900501563624e+004 15 > - * 24 5 x 30 1 3.000000e+007 4.93 6.09 1001 > 5.000000000000000e+002 16 > - * > - * Maximum Rate 28.64 > - * Average Rate 12.50 > - * Geometric Mean 10.50 > - * Harmonic Mean 8.25 > - * Minimum Rate 2.01 > - * > - * Do Span 471 > - * > - * Calibrating part 2 of 3 > - * > - * Loop count 8 0.88 seconds > - * Loop count 32 1.86 seconds > - * Loop count 64 3.19 seconds > - * Loop count 128 5.77 seconds > - * Loop count 256 10.93 seconds > - * > - * Loops 200 x 2 x Passes > - * > - * Kernel Floating Pt ops > - * No Passes E No Total Secs. MFLOPS Span > Checksums OK > - * ------------ -- ------------- ----- ------- ---- > ---------------------- -- > - * 1 40 x 15 5 1.212000e+008 4.84 25.04 101 > 5.253344778937972e+002 16 > - * 2 40 x 20 4 1.241600e+008 5.91 21.02 101 > 1.539721811668384e+003 15 > - * 3 53 x 20 2 8.564800e+007 5.10 16.78 101 > 1.009741436578952e+000 16 > - * 4 70 x 32 2 1.075200e+008 4.29 25.07 101 > 5.999250595473891e-001 16 > - * 5 55 x 13 2 5.720000e+007 4.99 11.46 101 > 4.589031939600982e+001 16 > - * 6 7 x 19 2 5.107200e+007 4.70 10.87 32 > 8.631675645333210e+001 16 > - * 7 22 x 12 16 1.706496e+008 5.56 30.71 101 > 6.345586315784055e+002 16 > - * 8 6 x 6 36 1.026432e+008 5.26 19.50 100 > 1.501268005625795e+005 15 > - * 9 21 x 5 17 7.211400e+007 5.03 14.33 101 > 1.189443609974981e+005 16 > - * 10 19 x 5 9 3.454200e+007 6.13 5.63 101 > 7.310369784325296e+004 16 > - * 11 64 x 20 1 5.120000e+007 4.95 10.35 101 > 3.433560407475758e+004 16 > - * 12 68 x 20 1 5.440000e+007 5.16 10.53 100 > 7.127569130821465e-006 16 > - * 13 41 x 3 7 1.102080e+007 5.47 2.01 32 > 9.816387810944356e+010 15 > - * 14 10 x 4 11 1.777600e+007 5.49 3.24 101 > 3.039983465145392e+007 15 > - * 15 1 x 7 33 4.620000e+007 5.32 8.69 101 > 3.943816690352044e+004 15 > - * 16 27 x 21 10 6.350400e+007 5.02 12.66 40 > 6.480410000000000e+005 16 > - * 17 20 x 9 9 6.544800e+007 5.74 11.40 101 > 1.114641772902486e+003 16 > - * 18 1 x 10 44 8.712000e+007 5.22 16.69 100 > 1.015727037502299e+005 15 > - * 19 23 x 15 6 8.362800e+007 5.11 16.36 101 > 5.421816960147207e+002 16 > - * 20 8 x 9 26 7.488000e+007 5.43 13.80 100 > 3.126205178815432e+004 16 > - * 21 1 x 2 2 5.000000e+007 5.55 9.01 50 > 7.824524877232093e+007 16 > - * 22 7 x 9 17 4.326840e+007 5.21 8.31 101 > 2.938604376566698e+002 15 > - * 23 5 x 9 11 9.801000e+007 4.77 20.54 100 > 3.549900501563624e+004 15 > - * 24 31 x 30 1 3.720000e+007 6.06 6.14 101 > 5.000000000000000e+001 16 > - * > - * Maximum Rate 30.71 > - * Average Rate 13.76 > - * Geometric Mean 11.69 > - * Harmonic Mean 9.19 > - * Minimum Rate 2.01 > - * > - * Do Span 90 > - * > - * Calibrating part 3 of 3 > - * > - * Loop count 32 0.77 seconds > - * Loop count 128 1.54 seconds > - * Loop count 256 2.47 seconds > - * Loop count 512 4.34 seconds > - * Loop count 1024 8.13 seconds > - * > - * Loops 200 x 8 x Passes > - * > - * Kernel Floating Pt ops > - * No Passes E No Total Secs. MFLOPS Span > Checksums OK > - * ------------ -- ------------- ----- ------- ---- > ---------------------- -- > - * 1 28 x 22 5 1.330560e+008 5.31 25.05 27 > 3.855104502494961e+001 16 > - * 2 46 x 22 4 7.124480e+007 4.38 16.27 15 > 3.953296986903060e+001 16 > - * 3 37 x 23 2 7.352640e+007 4.26 17.24 27 > 2.699309089320672e-001 16 > - * 4 38 x 35 2 6.384000e+007 3.79 16.86 27 > 5.999250595473891e-001 16 > - * 5 40 x 23 2 7.654400e+007 4.45 17.20 27 > 3.182615248447483e+000 16 > - * 6 21 x 32 2 5.160960e+007 4.82 10.70 8 > 1.120309393467088e+000 15 > - * 7 20 x 12 16 1.290240e+008 4.24 30.43 21 > 2.845720217644024e+001 16 > - * 8 9 x 8 36 1.078272e+008 5.17 20.85 14 > 2.960543667875005e+003 15 > - * 9 26 x 16 17 1.697280e+008 5.33 31.82 15 > 2.623968460874250e+003 16 > - * 10 25 x 11 9 5.940000e+007 5.42 10.96 15 > 1.651291227698265e+003 16 > - * 11 46 x 22 1 4.209920e+007 3.67 11.48 27 > 6.551161335845770e+002 16 > - * 12 48 x 23 1 4.592640e+007 5.04 9.12 26 > 1.943435981130448e-006 16 > - * 13 31 x 4 7 1.111040e+007 5.57 2.00 8 > 3.847124199949431e+010 15 > - * 14 8 x 6 11 2.280960e+007 5.19 4.40 27 > 2.923540598672009e+006 15 > - * 15 1 x 15 33 5.544000e+007 6.14 9.03 15 > 1.108997288134785e+003 16 > - * 16 14 x 31 10 7.638400e+007 5.80 13.17 15 > 5.152160000000000e+005 16 > - * 17 26 x 11 9 6.177600e+007 5.14 12.02 15 > 2.947368618589360e+001 16 > - * 18 2 x 12 44 1.098240e+008 5.36 20.47 14 > 9.700646212337040e+002 16 > - * 19 28 x 21 6 8.467200e+007 5.38 15.74 15 > 1.268230698051004e+001 15 > - * 20 7 x 10 26 7.571200e+007 5.27 14.36 26 > 5.987713249475302e+002 16 > - * 21 1 x 2 2 8.000000e+007 5.50 14.55 20 > 5.009945671204667e+007 16 > - * 22 8 x 13 17 4.243200e+007 5.04 8.42 15 > 6.109968728263973e+000 16 > - * 23 7 x 15 11 1.201200e+008 4.38 27.42 14 > 4.850340602749970e+002 16 > - * 24 23 x 32 1 3.061760e+007 5.01 6.11 27 > 1.300000000000000e+001 16 > - * > - * Maximum Rate 31.82 > - * Average Rate 15.24 > - * Geometric Mean 13.06 > - * Harmonic Mean 10.26 > - * Minimum Rate 2.00 > - * > - * Do Span 19 > - * > - * Overall > - * > - * Part 1 weight 1 > - * Part 2 weight 2 > - * Part 3 weight 1 > - * > - * Maximum Rate 31.82 > - * Average Rate 13.81 > - * Geometric Mean 11.70 > - * Harmonic Mean 9.17 > - * Minimum Rate 2.00 > - * > - * Do Span 167 > - * > - * Enter the following data which will be filed with the results > - * > - * Month run 9/1996 > - * PC model Escom > - * CPU Pentium > - * Clock MHz 100 > - * Cache 256K > - * Options Neptune chipset > - * OS/DOS Windows 95 > - * Compiler Watcom C/C++ Version 10.5 > - * OptLevel Win386 -zp4 -otexan -om -fp5 -zc -5r > - * Run by Roy Longbottom > - * From UK > - * Mail 101323.2241 at compuserve.com > - * > - * Note: the date, compiler and opt level are inserted by the > program. > - * > - * The tables of results and running details are appended to file > - * LLloops.txt. > - * > - * When a single MFLOPS rating is claimed for this benchmark it is > - * usually the overall geometric mean result. > - * > - > ********************************************************************** > - * > - * Pre-compiled codes were produced via a Watcom C/C++ 10.5 > compiler. > - * Versions are available for DOS, Windows 3/95 and NT/Win 95. Both > - * non-optimised and optimised programs are available. The latter > have > - * options as in the above example. > - * > - * In this source code, function prototypes are declared and > function > - * headers have embedded parameter types to produce code for C and > C++ > - * at least suitable for compiling as such with the Watcom compiler. > - * > - > *********************************************************************** > - */ > - > -#include > -#include > -#include > - > - > - struct Arrays > - { > - double U[1001]; > - double V[1001]; > - double W[1001]; > - double X[1001]; > - double Y[1001]; > - double Z[1001]; > - double G[1001]; > - double Du1[101]; > - double Du2[101]; > - double Du3[101]; > - double Grd[1001]; > - double Dex[1001]; > - double Xi[1001]; > - double Ex[1001]; > - double Ex1[1001]; > - double Dex1[1001]; > - double Vx[1001]; > - double Xx[1001]; > - double Rx[1001]; > - double Rh[2048]; > - double Vsp[101]; > - double Vstp[101]; > - double Vxne[101]; > - double Vxnd[101]; > - double Ve3[101]; > - double Vlr[101]; > - double Vlin[101]; > - double B5[101]; > - double Plan[300]; > - double D[300]; > - double Sa[101]; > - double Sb[101]; > - double P[512][4]; > - double Px[101][25]; > - double Cx[101][25]; > - double Vy[25][101]; > - double Vh[7][101]; > - double Vf[7][101]; > - double Vg[7][101]; > - double Vs[7][101]; > - double Za[7][101]; > - double Zp[7][101]; > - double Zq[7][101]; > - double Zr[7][101]; > - double Zm[7][101]; > - double Zb[7][101]; > - double Zu[7][101]; > - double Zv[7][101]; > - double Zz[7][101]; > - double B[64][64]; > - double C[64][64]; > - double H[64][64]; > - double U1[2][101][5]; > - double U2[2][101][5]; > - double U3[2][101][5]; > - double Xtra[40]; > - long E[96]; > - long F[96]; > - long Ix[1001]; > - long Ir[1001]; > - long Zone[301]; > - double X0[1001]; > - double W0[1001]; > - double Px0[101][25]; > - double P0[512][4]; > - double H0[64][64]; > - double Rh0[2048]; > - double Vxne0[101]; > - double Zr0[7][101]; > - double Zu0[7][101]; > - double Zv0[7][101]; > - double Zz0[7][101]; > - double Za0[101][25]; > - double Stb50; > - double Xx0; > - > - > - }as1; > - #define u as1.U > - #define v as1.V > - #define w as1.W > - #define x as1.X > - #define y as1.Y > - #define z as1.Z > - #define g as1.G > - #define du1 as1.Du1 > - #define du2 as1.Du2 > - #define du3 as1.Du3 > - #define grd as1.Grd > - #define dex as1.Dex > - #define xi as1.Xi > - #define ex as1.Ex > - #define ex1 as1.Ex1 > - #define dex1 as1.Dex1 > - #define vx as1.Vx > - #define xx as1.Xx > - #define rx as1.Rx > - #define rh as1.Rh > - #define vsp as1.Vsp > - #define vstp as1.Vstp > - #define vxne as1.Vxne > - #define vxnd as1.Vxnd > - #define ve3 as1.Ve3 > - #define vlr as1.Vlr > - #define vlin as1.Vlin > - #define b5 as1.B5 > - #define plan as1.Plan > - #define d as1.D > - #define sa as1.Sa > - #define sb as1.Sb > - #define p as1.P > - #define px as1.Px > - #define cx as1.Cx > - #define vy as1.Vy > - #define vh as1.Vh > - #define vf as1.Vf > - #define vg as1.Vg > - #define vs as1.Vs > - #define za as1.Za > - #define zb as1.Zb > - #define zp as1.Zp > - #define zq as1.Zq > - #define zr as1.Zr > - #define zm as1.Zm > - #define zz as1.Zz > - #define zu as1.Zu > - #define zv as1.Zv > - #define b as1.B > - #define c as1.C > - #define h as1.H > - #define u1 as1.U1 > - #define u2 as1.U2 > - #define u3 as1.U3 > - #define xtra as1.Xtra > - #define a11 as1.Xtra[1] > - #define a12 as1.Xtra[2] > - #define a13 as1.Xtra[3] > - #define a21 as1.Xtra[4] > - #define a22 as1.Xtra[5] > - #define a23 as1.Xtra[6] > - #define a31 as1.Xtra[7] > - #define a32 as1.Xtra[8] > - #define a33 as1.Xtra[9] > - #define c0 as1.Xtra[12] > - #define dk as1.Xtra[15] > - #define dm22 as1.Xtra[16] > - #define dm23 as1.Xtra[17] > - #define dm24 as1.Xtra[18] > - #define dm25 as1.Xtra[19] > - #define dm26 as1.Xtra[20] > - #define dm27 as1.Xtra[21] > - #define dm28 as1.Xtra[22] > - #define expmax as1.Xtra[26] > - #define flx as1.Xtra[27] > - #define q as1.Xtra[28] > - #define r as1.Xtra[30] > - #define s as1.Xtra[32] > - #define sig as1.Xtra[34] > - #define stb5 as1.Xtra[35] > - #define t as1.Xtra[36] > - #define xnm as1.Xtra[39] > - #define e as1.E > - #define f as1.F > - #define ix as1.Ix > - #define ir as1.Ir > - #define zone as1.Zone > - #define x0 as1.X0 > - #define w0 as1.W0 > - #define px0 as1.Px0 > - #define p0 as1.P0 > - #define h0 as1.H0 > - #define rh0 as1.Rh0 > - #define vxne0 as1.Vxne0 > - #define zr0 as1.Zr0 > - #define zu0 as1.Zu0 > - #define zv0 as1.Zv0 > - #define zz0 as1.Zz0 > - #define za0 as1.Za0 > - #define stb50 as1.Stb50 > - #define xx0 as1.Xx0 > - > - > - struct Parameters > - { > - long Inner_loops; > - long Outer_loops; > - long Loop_mult; > - double Flops_per_loop; > - double Sumcheck[3][25]; > - long Accuracy[3][25]; > - double LoopTime[3][25]; > - double LoopSpeed[3][25]; > - double LoopFlos[3][25]; > - long Xflops[25]; > - long Xloops[3][25]; > - long Nspan[3][25]; > - double TimeStart; > - double TimeEnd; > - double Loopohead; > - long Count; > - long Count2; > - long Pass; > - long Extra_loops[3][25]; > - long K2; > - long K3; > - long M16; > - long J5; > - long Section; > - long N16; > - double Mastersum; > - long M24; > - > - > - }as2; > - > - #define n as2.Inner_loops > - #define loop as2.Outer_loops > - #define mult as2.Loop_mult > - #define nflops as2.Flops_per_loop > - #define Checksum as2.Sumcheck > - #define accuracy as2.Accuracy > - #define RunTime as2.LoopTime > - #define Mflops as2.LoopSpeed > - #define FPops as2.LoopFlos > - #define nspan as2.Nspan > - #define xflops as2.Xflops > - #define xloops as2.Xloops > - #define StartTime as2.TimeStart > - #define EndTime as2.TimeEnd > - #define overhead_l as2.Loopohead > - #define count as2.Count > - #define count2 as2.Count2 > - #define pass as2.Pass > - #define extra_loops as2.Extra_loops > - #define k2 as2.K2 > - #define k3 as2.K3 > - #define m16 as2.M16 > - #define j5 as2.J5 > - #define section as2.Section > - #define n16 as2.N16 > - #define MasterSum as2.Mastersum > - #define m24 as2.M24 > - > - > - void init(long which); > - > - /* Initialises arrays and variables */ > - > - long endloop(long which); > - > - /* Controls outer loops and stores results */ > - > - long parameters(long which); > - > - /* Gets loop parameters and variables, starts timer */ > - > - void kernels(); > - > - /* The 24 kernels */ > - > - void check(long which); > - > - /* Calculates checksum accuracy */ > - > - void iqranf(); > - > - /* Random number generator for Kernel 14 */ > - > -main(int argc, char *argv[]) > -{ > - double pass_time, least, lmult, now = 1.0, wt; > - double time1, time2; > - long i, k, loop_passes; > - long mul[3] = {1, 2, 8}; > - double weight[3] = {1.0, 2.0, 1.0}; > - long Endit, which; > - double maximum[4]; > - double minimum[4]; > - double average[4]; > - double harmonic[4]; > - double geometric[4]; > - long xspan[4]; > - char general[9][80] = {" "}; > - FILE *outfile; > - int getinput = 1; > - > - if (argc > 1) > - { > - switch (argv[1][0]) > - { > - case 'N': > - getinput = 0; > - break; > - case 'n': > - getinput = 0; > - break; > - } > - } > - > - > - printf ("L.L.N.L. 'C' KERNELS: MFLOPS P.C. VERSION 4.0\n\n"); > - > - if (getinput == 0) > - { > - printf ("***** No run time input data *****\n\n"); > - } > - else > - { > - printf ("*** With run time input data ***\n\n"); > - } > - > -/ > ************************************************************************ > - * Execute the kernels three times at different Do > Spans * > - > ************************************************************************/ > - > - for ( section=0 ; section<3 ; section++ ) > - { > - loop_passes = 200 * mul[section]; > - pass = -20; > - mult = 2 * mul[section]; > - > - for ( i=1; i<25; i++) > - { > - extra_loops[section][i] = 500; > - } > - > -/ > ************************************************************************ > - * Execute the > kernels * > - > ************************************************************************/ > - > - kernels(); > - > - maximum[section] = 0.0; > - minimum[section] = Mflops[section][1]; > - average[section] = 0.0; > - harmonic[section] = 0.0; > - geometric[section] = 0.0; > - xspan[section] = 0.0; > - } > - > -/ > ************************************************************************ > - * End of executing the kernels three times at different Do > Spans * > - > ************************************************************************/ > -} > - > -/ > ************************************************************************ > - * The > Kernels * > - > ************************************************************************/ > - > -void kernels() > - { > - > - long lw; > - long ipnt, ipntp, ii; > - double temp; > - long nl1, nl2; > - long kx, ky; > - double ar, br, cr; > - long i, j, k, m; > - long ip, i1, i2, j1, j2, j4, lb; > - long ng, nz; > - double tmp; > - double scale, xnei, xnc, e3,e6; > - long ink, jn, kn, kb5i; > - double di, dn; > - double qa; > - > - for ( k=0 ; k<25; k++) > - { > - Checksum[section][k] = 0.0; > - } > - > - > - > - /* > - > ******************************************************************* > - * Kernel 1 -- hydro fragment > - > ******************************************************************* > - */ > - > - parameters (1); > - > - do > - { > - for ( k=0 ; k - { > - x[k] = q + y[k]*( r*z[k+10] + t*z[k+11] ); > - } > - > - endloop (1); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 2 -- ICCG excerpt (Incomplete Cholesky Conjugate > Gradient) > - > ******************************************************************* > - */ > - > - parameters (2); > - > - do > - { > - ii = n; > - ipntp = 0; > - do > - { > - ipnt = ipntp; > - ipntp += ii; > - ii /= 2; > - i = ipntp; > - for ( k=ipnt+1 ; k - { > - i++; > - x[i] = x[k] - v[k]*x[k-1] - v[k+1]*x[k+1]; > - } > - } while ( ii>0 ); > - > - endloop (2); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 3 -- inner product > - > ******************************************************************* > - */ > - > - parameters (3); > - > - do > - { > - q = 0.0; > - for ( k=0 ; k - { > - q += z[k]*x[k]; > - } > - > - endloop (3); > - } > - while (count < loop); > - > - > - /* > - > ******************************************************************* > - * Kernel 4 -- banded linear equations > - > ******************************************************************* > - */ > - > - parameters (4); > - > - m = ( 1001-7 )/2; > - do > - { > - for ( k=6 ; k<1001 ; k=k+m ) > - { > - lw = k - 6; > - temp = x[k-1]; > - > - for ( j=4 ; j - { > - temp -= x[lw]*y[j]; > - lw++; > - } > - x[k-1] = y[4]*temp; > - } > - > - endloop (4); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 5 -- tri-diagonal elimination, below diagonal > - > ******************************************************************* > - */ > - > - parameters (5); > - > - do > - { > - for ( i=1 ; i - { > - x[i] = z[i]*( y[i] - x[i-1] ); > - } > - > - endloop (5); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 6 -- general linear recurrence equations > - > ******************************************************************* > - */ > - > - parameters (6); > - > - > - do > - { > - for ( i=1 ; i - { > - w[i] = 0.01; > - for ( k=0 ; k - { > - w[i] += b[k][i] * w[(i-k)-1]; > - } > - } > - > - endloop (6); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 7 -- equation of state fragment > - > ******************************************************************* > - */ > - > - parameters (7); > - > - do > - { > - > - for ( k=0 ; k - { > - x[k] = u[k] + r*( z[k] + r*y[k] ) + > - t*( u[k+3] + r*( u[k+2] + r*u[k+1] ) + > - t*( u[k+6] + q*( u[k+5] + q*u[k+4] ) ) ); > - } > - > - endloop (7); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 8 -- ADI integration > - > ******************************************************************* > - */ > - > - nl1 = 0; > - nl2 = 1; > - > - parameters (8); > - > - do > - { > - for ( kx=1 ; kx<3 ; kx++ ) > - { > - > - for ( ky=1 ; ky - { > - du1[ky] = u1[nl1][ky+1][kx] - u1[nl1][ky-1][kx]; > - du2[ky] = u2[nl1][ky+1][kx] - u2[nl1][ky-1][kx]; > - du3[ky] = u3[nl1][ky+1][kx] - u3[nl1][ky-1][kx]; > - u1[nl2][ky][kx]= > - u1[nl1][ky][kx]+a11*du1[ky]+a12*du2[ky] > +a13*du3[ky] + sig* > - (u1[nl1][ky][kx+1]-2.0*u1[nl1][ky][kx]+u1[nl1][ky] > [kx-1]); > - u2[nl2][ky][kx]= > - u2[nl1][ky][kx]+a21*du1[ky]+a22*du2[ky] > +a23*du3[ky] + sig* > - (u2[nl1][ky][kx+1]-2.0*u2[nl1][ky][kx]+u2[nl1][ky] > [kx-1]); > - u3[nl2][ky][kx]= > - u3[nl1][ky][kx]+a31*du1[ky]+a32*du2[ky] > +a33*du3[ky] + sig* > - (u3[nl1][ky][kx+1]-2.0*u3[nl1][ky][kx]+u3[nl1][ky] > [kx-1]); > - } > - } > - > - endloop (8); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 9 -- integrate predictors > - > ******************************************************************* > - */ > - > - parameters (9); > - > - do > - { > - for ( i=0 ; i - { > - px[i][0] = dm28*px[i][12] + dm27*px[i][11] + dm26*px[i] > [10] + > - dm25*px[i][ 9] + dm24*px[i][ 8] + dm23*px[i] > [ 7] + > - dm22*px[i][ 6] + c0*( px[i][ 4] + px[i][ 5]) > - + px[i][ 2]; > - } > - > - endloop (9); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 10 -- difference predictors > - > ******************************************************************* > - */ > - > - parameters (10); > - > - do > - { > - for ( i=0 ; i - { > - ar = cx[i][ 4]; > - br = ar - px[i][ 4]; > - px[i][ 4] = ar; > - cr = br - px[i][ 5]; > - px[i][ 5] = br; > - ar = cr - px[i][ 6]; > - px[i][ 6] = cr; > - br = ar - px[i][ 7]; > - px[i][ 7] = ar; > - cr = br - px[i][ 8]; > - px[i][ 8] = br; > - ar = cr - px[i][ 9]; > - px[i][ 9] = cr; > - br = ar - px[i][10]; > - px[i][10] = ar; > - cr = br - px[i][11]; > - px[i][11] = br; > - px[i][13] = cr - px[i][12]; > - px[i][12] = cr; > - } > - > - endloop (10); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 11 -- first sum > - > ******************************************************************* > - */ > - > - parameters (11); > - > - do > - { > - x[0] = y[0]; > - for ( k=1 ; k - { > - x[k] = x[k-1] + y[k]; > - } > - > - endloop (11); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 12 -- first difference > - > ******************************************************************* > - */ > - > - parameters (12); > - > - do > - { > - for ( k=0 ; k - { > - x[k] = y[k+1] - y[k]; > - } > - > - endloop (12); > - } > - while (count < loop); > - > - > - /* > - > ******************************************************************* > - * Kernel 13 -- 2-D PIC (Particle In Cell) > - > ******************************************************************* > - */ > - > - parameters (13); > - > - do > - { > - for ( ip=0; ip - { > - i1 = p[ip][0]; > - j1 = p[ip][1]; > - i1 &= 64-1; > - j1 &= 64-1; > - p[ip][2] += b[j1][i1]; > - p[ip][3] += c[j1][i1]; > - p[ip][0] += p[ip][2]; > - p[ip][1] += p[ip][3]; > - i2 = p[ip][0]; > - j2 = p[ip][1]; > - i2 = ( i2 & 64-1 ) - 1 ; > - j2 = ( j2 & 64-1 ) - 1 ; > - p[ip][0] += y[i2+32]; > - p[ip][1] += z[j2+32]; > - i2 += e[i2+32]; > - j2 += f[j2+32]; > - h[j2][i2] += 1.0; > - } > - endloop (13); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 14 -- 1-D PIC (Particle In Cell) > - > ******************************************************************* > - */ > - > - parameters (14); > - > - do > - { > - for ( k=0 ; k - { > - vx[k] = 0.0; > - xx[k] = 0.0; > - ix[k] = (long) grd[k]; > - xi[k] = (double) ix[k]; > - ex1[k] = ex[ ix[k] - 1 ]; > - dex1[k] = dex[ ix[k] - 1 ]; > - } > - for ( k=0 ; k - { > - vx[k] = vx[k] + ex1[k] + ( xx[k] - xi[k] )*dex1[k]; > - xx[k] = xx[k] + vx[k] + flx; > - ir[k] = xx[k]; > - rx[k] = xx[k] - ir[k]; > - ir[k] = ( ir[k] & 2048-1 ) + 1; > - xx[k] = rx[k] + ir[k]; > - } > - for ( k=0 ; k - { > - rh[ ir[k]-1 ] += 1.0 - rx[k]; > - rh[ ir[k] ] += rx[k]; > - } > - endloop (14); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 15 -- Casual Fortran. Development version > - > ******************************************************************* > - */ > - > - parameters (15); > - > - do > - { > - ng = 7; > - nz = n; > - ar = 0.053; > - br = 0.073; > - for ( j=1 ; j - { > - for ( k=1 ; k - { > - if ( (j+1) >= ng ) > - { > - vy[j][k] = 0.0; > - continue; > - } > - if ( vh[j+1][k] > vh[j][k] ) > - { > - t = ar; > - } > - else > - { > - t = br; > - } > - if ( vf[j][k] < vf[j][k-1] ) > - { > - if ( vh[j][k-1] > vh[j+1][k-1] ) > - r = vh[j][k-1]; > - else > - r = vh[j+1][k-1]; > - s = vf[j][k-1]; > - } > - else > - { > - if ( vh[j][k] > vh[j+1][k] ) > - r = vh[j][k]; > - else > - r = vh[j+1][k]; > - s = vf[j][k]; > - } > - vy[j][k] = sqrt( vg[j][k]*vg[j][k] + r*r )* t/s; > - if ( (k+1) >= nz ) > - { > - vs[j][k] = 0.0; > - continue; > - } > - if ( vf[j][k] < vf[j-1][k] ) > - { > - if ( vg[j-1][k] > vg[j-1][k+1] ) > - r = vg[j-1][k]; > - else > - r = vg[j-1][k+1]; > - s = vf[j-1][k]; > - t = br; > - } > - else > - { > - if ( vg[j][k] > vg[j][k+1] ) > - r = vg[j][k]; > - else > - r = vg[j][k+1]; > - s = vf[j][k]; > - t = ar; > - } > - vs[j][k] = sqrt( vh[j][k]*vh[j][k] + r*r )* t / s; > - } > - } > - endloop (15); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 16 -- Monte Carlo search loop > - > ******************************************************************* > - */ > - > - parameters (16); > - > - > - ii = n / 3; > - lb = ii + ii; > - k3 = k2 = 0; > - do > - { > - i1 = m16 = 1; > - label410: > - j2 = ( n + n )*( m16 - 1 ) + 1; > - for ( k=1 ; k<=n ; k++ ) > - { > - k2++; > - j4 = j2 + k + k; > - j5 = zone[j4-1]; > - if ( j5 < n ) > - { > - if ( j5+lb < n ) > - { /* 420 */ > - tmp = plan[j5-1] - t; /* 435 */ > - } > - else > - { > - if ( j5+ii < n ) > - { /* 415 */ > - tmp = plan[j5-1] - s; /* 430 */ > - } > - else > - { > - tmp = plan[j5-1] - r; /* 425 */ > - } > - } > - } > - else if( j5 == n ) > - { > - break; /* 475 */ > - } > - else > - { > - k3++; /* 450 */ > - tmp=(d[j5-1]-(d[j5-2]*(t-d[j5-3])*(t-d[j5-3])+(s- > d[j5-4])* > - (s-d[j5-4])+(r-d[j5-5])*(r-d[j5-5]))); > - } > - if ( tmp < 0.0 ) > - { > - if ( zone[j4-2] < 0 ) /* 445 */ > - continue; /* 470 */ > - else if ( !zone[j4-2] ) > - break; /* 480 */ > - } > - else if ( tmp ) > - { > - if ( zone[j4-2] > 0 ) /* 440 */ > - continue; /* 470 */ > - else if ( !zone[j4-2] ) > - break; /* 480 */ > - } > - else break; /* 485 */ > - m16++; /* 455 */ > - if ( m16 > zone[0] ) > - m16 = 1; /* 460 */ > - if ( i1-m16 ) /* 465 */ > - goto label410; > - else > - break; > - } > - endloop (16); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 17 -- implicit, conditional computation > - > ******************************************************************* > - */ > - > - parameters (17); > - > - do > - { > - i = n-1; > - j = 0; > - ink = -1; > - scale = 5.0 / 3.0; > - xnm = 1.0 / 3.0; > - e6 = 1.03 / 3.07; > - goto l61; > -l60: e6 = xnm*vsp[i] + vstp[i]; > - vxne[i] = e6; > - xnm = e6; > - ve3[i] = e6; > - i += ink; > - if ( i==j ) goto l62; > -l61: e3 = xnm*vlr[i] + vlin[i]; > - xnei = vxne[i]; > - vxnd[i] = e6; > - xnc = scale*e3; > - if ( xnm > xnc ) goto l60; > - if ( xnei > xnc ) goto l60; > - ve3[i] = e3; > - e6 = e3 + e3 - xnm; > - vxne[i] = e3 + e3 - xnei; > - xnm = e6; > - i += ink; > - if ( i != j ) goto l61; > -l62:; > - endloop (17); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 18 - 2-D explicit hydrodynamics fragment > - > ******************************************************************* > - */ > - > - parameters (18); > - > - do > - { > - t = 0.0037; > - s = 0.0041; > - kn = 6; > - jn = n; > - for ( k=1 ; k - { > - > - for ( j=1 ; j - { > - za[k][j] = ( zp[k+1][j-1] +zq[k+1][j-1] -zp[k][j-1] - > zq[k][j-1] )* > - ( zr[k][j] +zr[k][j-1] ) / ( zm[k][j-1] +zm[k > +1][j-1]); > - zb[k][j] = ( zp[k][j-1] +zq[k][j-1] -zp[k][j] -zq[k] > [j] ) * > - ( zr[k][j] +zr[k-1][j] ) / ( zm[k][j] +zm[k] > [j-1]); > - } > - } > - for ( k=1 ; k - { > - > - for ( j=1 ; j - { > - zu[k][j] += s*( za[k][j] *( zz[k][j] - zz[k][j > +1] ) - > - za[k][j-1] *( zz[k][j] - zz[k] > [j-1] ) - > - zb[k][j] *( zz[k][j] - zz[k-1] > [j] ) + > - zb[k+1][j] *( zz[k][j] - zz[k+1] > [j] ) ); > - zv[k][j] += s*( za[k][j] *( zr[k][j] - zr[k][j > +1] ) - > - za[k][j-1] *( zr[k][j] - zr[k] > [j-1] ) - > - zb[k][j] *( zr[k][j] - zr[k-1] > [j] ) + > - zb[k+1][j] *( zr[k][j] - zr[k+1] > [j] ) ); > - } > - } > - for ( k=1 ; k - { > - > - for ( j=1 ; j - { > - zr[k][j] = zr[k][j] + t*zu[k][j]; > - zz[k][j] = zz[k][j] + t*zv[k][j]; > - } > - } > - endloop (18); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 19 -- general linear recurrence equations > - > ******************************************************************* > - */ > - > - parameters (19); > - > - kb5i = 0; > - > - do > - { > - for ( k=0 ; k - { > - b5[k+kb5i] = sa[k] + stb5*sb[k]; > - stb5 = b5[k+kb5i] - stb5; > - } > - for ( i=1 ; i<=n ; i++ ) > - { > - k = n - i; > - b5[k+kb5i] = sa[k] + stb5*sb[k]; > - stb5 = b5[k+kb5i] - stb5; > - } > - endloop (19); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 20 - Discrete ordinates transport, conditional > recurrence on xx > - > ******************************************************************* > - */ > - > - parameters (20); > - > - do > - { > - for ( k=0 ; k - { > - di = y[k] - g[k] / ( xx[k] + dk ); > - dn = 0.2; > - if ( di ) > - { > - dn = z[k]/di ; > - if ( t < dn ) dn = t; > - if ( s > dn ) dn = s; > - } > - x[k] = ( ( w[k] + v[k]*dn )* xx[k] + u[k] ) / ( vx[k] + > v[k]*dn ); > - xx[k+1] = ( x[k] - xx[k] )* dn + xx[k]; > - } > - endloop (20); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 21 -- matrix*matrix product > - > ******************************************************************* > - */ > - > - parameters (21); > - > - do > - { > - for ( k=0 ; k<25 ; k++ ) > - { > - for ( i=0 ; i<25 ; i++ ) > - { > - for ( j=0 ; j - { > - px[j][i] += vy[k][i] * cx[j][k]; > - } > - } > - } > - endloop (21); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 22 -- Planckian distribution > - > ******************************************************************* > - */ > - > - parameters (22); > - > - expmax = 20.0; > - u[n-1] = 0.99*expmax*v[n-1]; > - do > - { > - for ( k=0 ; k - { > - y[k] = u[k] / v[k]; > - w[k] = x[k] / ( exp( y[k] ) -1.0 ); > - } > - endloop (22); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 23 -- 2-D implicit hydrodynamics fragment > - > ******************************************************************* > - */ > - > - parameters (23); > - > - do > - { > - for ( j=1 ; j<6 ; j++ ) > - { > - for ( k=1 ; k - { > - qa = za[j+1][k]*zr[j][k] + za[j-1][k]*zb[j][k] + > - za[j][k+1]*zu[j][k] + za[j][k-1]*zv[j][k] + > zz[j][k]; > - za[j][k] += 0.175*( qa - za[j][k] ); > - } > - } > - endloop (23); > - } > - while (count < loop); > - > - /* > - > ******************************************************************* > - * Kernel 24 -- find location of first minimum in array > - > ******************************************************************* > - */ > - > - parameters (24); > - > - x[n/2] = -1.0e+10; > - do > - { > - m24 = 0; > - for ( k=1 ; k - { > - if ( x[k] < x[m24] ) m24 = k; > - } > - endloop (24); > - } > - while (count < loop); > - > - return; > - } > - > -/ > ************************************************************************ > - * endloop procedure - calculate checksums and > MFLOPS * > - > ************************************************************************/ > - > -long endloop(long which) > -{ > - double now = 1.0, useflops; > - long i, j, k, m; > - double Scale = 1000000.0; > - > - count = count + 1; > - if (count >= loop) /* else return */ > - { > - > -/ > ************************************************************************ > - * End of standard set of loops for one > kernel * > - > ************************************************************************/ > - > - count2 = count2 + 1; > - if (count2 == extra_loops[section][which]) > - /* else re-initialise parameters if > required */ > - { > - > -/ > ************************************************************************ > - * End of extra loops for 5 seconds execution > time * > - > ************************************************************************/ > - > - count2 = 0; > - if (which == 1) > - { > - for ( k=0 ; k - { > - Checksum[section][1] = Checksum[section][1] + x[k] > - * (double)(k+1); > - } > - useflops = nflops * (double)(n * loop); > - } > - if (which == 2) > - { > - for ( k=0 ; k - { > - Checksum[section][2] = Checksum[section][2] + x[k] > - * (double)(k+1); > - } > - useflops = nflops * (double)((n-4) * loop); > - } > - if (which == 3) > - { > - Checksum[section][3] = q; > - useflops = nflops * (double)(n * loop); > - } > - if (which == 4) > - { > - for ( k=0 ; k<3 ; k++ ) > - { > - Checksum[section][4] = Checksum[section][4] + v[k] > - * (double)(k+1); > - } > - useflops = nflops * (double) ((((n-5)/5)+1) * 3 * loop); > - } > - if (which == 5) > - { > - for ( k=1 ; k - { > - Checksum[section][5] = Checksum[section][5] + x[k] > - * (double)(k); > - } > - useflops = nflops * (double)((n-1) * loop); > - } > - if (which == 6) > - { > - for ( k=0 ; k - { > - > - Checksum[section][6] = Checksum[section][6] + w[k] > - * (double)(k+1); > - > - } > - useflops = nflops * (double)(n * ((n - 1) / 2) * loop); > - } > - if (which == 7) > - { > - for ( k=0 ; k - { > - Checksum[section][7] = Checksum[section][7] + x[k] > - * (double)(k+1); > - } > - useflops = nflops * (double)(n * loop); > - } > - if (which == 8) > - { > - for ( i=0 ; i<2 ; i++ ) > - { > - for ( j=0 ; j<101 ; j++ ) > - { > - for ( k=0 ; k<5 ; k++ ) > - { > - m = 101 * 5 * i + 5 * j + k + 1; > - if (m < 10 * n + 1) > - { > - Checksum[section][8] = Checksum[section][8] > - + u1[i][j][k] * m > - + u2[i][j][k] * m + u3[i][j][k] * > m; > - } > - } > - } > - } > - useflops = nflops * (double)(2 * (n - 1) * loop); > - } > - if (which == 9) > - { > - for ( i=0 ; i - { > - for ( j=0 ; j<25 ; j++ ) > - { > - m = 25 * i + j + 1; > - if (m < 15 * n + 1) > - { > - Checksum[section][9] = Checksum[section][9] > - + px[i][j] * (double) > (m); > - } > - } > - } > - useflops = nflops * (double)(n * loop); > - } > - if (which == 10) > - { > - for ( i=0 ; i - { > - for (j=0 ; j<25 ; j++ ) > - { > - m = 25 * i + j + 1; > - if (m < 15 * n + 1) > - { > - Checksum[section][10] = Checksum[section][10] > - + px[i][j] * (double) > (m); > - } > - } > - } > - useflops = nflops * (double)(n * loop); > - } > - if (which == 11) > - { > - for ( k=1 ; k - { > - Checksum[section][11] = Checksum[section][11] > - + x[k] * (double)(k); > - } > - useflops = nflops * (double)((n - 1) * loop); > - } > - if (which == 12) > - { > - for ( k=0 ; k - { > - Checksum[section][12] = Checksum[section][12] + x[k] > - * (double)(k+1); > - } > - useflops = nflops * (double)(n * loop); > - } > - if (which == 13) > - { > - for ( k=0 ; k<2*n ; k++ ) > - { > - for ( j=0 ; j<4 ; j++ ) > - { > - m = 4 * k + j + 1; > - Checksum[section][13] = Checksum[section][13] > - + p[k][j]* (double)(m); > - } > - } > - for ( i=0 ; i<8*n/64 ; i++ ) > - { > - for ( j=0 ; j<64 ; j++ ) > - { > - m = 64 * i + j + 1; > - if (m < 8 * n + 1) > - { > - Checksum[section][13] = Checksum[section][13] > - + h[i][j] * > (double)(m); > - } > - } > - } > - useflops = nflops * (double)(n * loop); > - } > - if (which == 14) > - { > - for ( k=0 ; k - { > - Checksum[section][14] = Checksum[section][14] > - + (xx[k] + vx[k]) * > (double)(k+1); > - } > - for ( k=0 ; k<67 ; k++ ) > - { > - Checksum[section][14] = Checksum[section][14] + rh[k] > - * (double)(k+1); > - } > - useflops = nflops * (double)(n * loop); > - } > - if (which == 15) > - { > - for ( j=0 ; j<7 ; j++ ) > - { > - for ( k=0 ; k<101 ; k++ ) > - { > - m = 101 * j + k + 1; > - if (m < n * 7 + 1) > - { > - Checksum[section][15] = Checksum[section][15] > - + (vs[j][k] + vy[j][k]) * > (double)(m); > - } > - } > - } > - useflops = nflops * (double)((n - 1) * 5 * loop); > - } > - if (which == 16) > - { > - Checksum[section][16] = (double)(k3 + k2 + j5 + m16); > - useflops = (k2 + k2 + 10 * k3); > - } > - if (which == 17) > - { > - Checksum[section][17] = xnm; > - for ( k=0 ; k - { > - Checksum[section][17] = Checksum[section][17] > - + (vxne[k] + vxnd[k]) * > (double)(k+1); > - } > - useflops = nflops * (double)(n * loop); > - } > - if (which == 18) > - { > - for ( k=0 ; k<7 ; k++ ) > - { > - for ( j=0 ; j<101 ; j++ ) > - { > - m = 101 * k + j + 1; > - if (m < 7 * n + 1) > - { > - Checksum[section][18] = Checksum[section][18] > - + (zz[k][j] + zr[k][j]) * > (double)(m); > - } > - } > - } > - useflops = nflops * (double)((n - 1) * 5 * loop); > - } > - if (which == 19) > - { > - Checksum[section][19] = stb5; > - for ( k=0 ; k - { > - Checksum[section][19] = Checksum[section][19] + b5[k] > - * (double)(k+1); > - } > - useflops = nflops * (double)(n * loop); > - } > - if (which == 20) > - { > - for ( k=1 ; k - { > - Checksum[section][20] = Checksum[section][20] + xx[k] > - * (double)(k); > - } > - useflops = nflops * (double)(n * loop); > - } > - if (which == 21) > - { > - for ( k=0 ; k - { > - for ( i=0 ; i<25 ; i++ ) > - { > - m = 25 * k + i + 1; > - Checksum[section][21] = Checksum[section][21] > - + px[k][i] * (double) > (m); > - } > - } > - useflops = nflops * (double)(n * 625 * loop); > - > - } > - if (which == 22) > - { > - for ( k=0 ; k - { > - Checksum[section][22] = Checksum[section][22] + w[k] > - * (double)(k+1); > - } > - useflops = nflops * (double)(n * loop); > - } > - if (which == 23) > - { > - for ( j=0 ; j<7 ; j++ ) > - { > - for ( k=0 ; k<101 ; k++ ) > - { > - m = 101 * j + k + 1; > - if (m < 7 * n + 1) > - { > - Checksum[section][23] = Checksum[section] > [23] > - + za[j][k] * > (double)(m); > - } > - } > - } > - useflops = nflops * (double)((n-1) * 5 * loop); > - } > - if (which == 24) > - { > - Checksum[section][24] = (double)(m24); > - useflops = nflops * (double)((n - 1) * loop); > - } > - > - > -/ > ************************************************************************ > - * Deduct overheads from time, calculate MFLOPS, display > results * > - > ************************************************************************/ > - > - RunTime[section][which] = RunTime[section][which] > - - (loop * extra_loops[section][which]) * > overhead_l; > - FPops[section][which] = useflops * extra_loops[section] > [which]; > - Mflops[section][which] = FPops[section][which] / Scale > - / RunTime[section] > [which]; > - > - > -/ > ************************************************************************ > - * Compare sumcheck with standard result, calculate > accuracy * > - > ************************************************************************/ > - > - printf("%10.3f\n", Checksum[section][which]); > - > - } > - else > - { > -/ > ************************************************************************ > - * Re-initialise data if > reqired * > - > ************************************************************************/ > - > - count = 0; > - if (which == 2) > - { > - for ( k=0 ; k - { > - x[k] = x0[k]; > - } > - } > - if (which == 4) > - { > - m = (1001-7)/2; > - for ( k=6 ; k<1001 ; k=k+m ) > - { > - x[k] = x0[k]; > - } > - } > - if (which == 5) > - { > - for ( k=0 ; k - { > - x[k] = x0[k]; > - } > - } > - if (which == 6) > - { > - for ( k=0 ; k - { > - w[k] = w0[k]; > - } > - } > - if (which == 10) > - { > - for ( i=0 ; i - { > - for (j=4 ; j<13 ; j++ ) > - { > - px[i][j] = px0[i][j]; > - } > - } > - } > - if (which == 13) > - { > - for ( i=0 ; i - { > - for (j=0 ; j<4 ; j++ ) > - { > - p[i][j] = p0[i][j]; > - } > - } > - for ( i=0 ; i<64 ; i++ ) > - { > - for (j=0 ; j<64 ; j++ ) > - { > - h[i][j] = h0[i][j]; > - } > - } > - } > - if (which == 14) > - { > - for ( i=0; i - { > - rh[ir[i] - 1] = rh0[ir[i] - 1]; > - rh[ir[i] ] = rh0[ir[i] ]; > - } > - } > - if (which == 17) > - { > - for ( i=0; i - { > - vxne[i] = vxne0[i]; > - } > - } > - if (which == 18) > - { > - for ( i=1 ; i<6 ; i++ ) > - { > - for (j=1 ; j - { > - zr[i][j] = zr0[i][j]; > - zu[i][j] = zu0[i][j]; > - zv[i][j] = zv0[i][j]; > - zz[i][j] = zz0[i][j]; > - } > - } > - } > - if (which == 21) > - { > - for ( i=0 ; i - { > - for (j=0 ; j<25 ; j++ ) > - { > - px[i][j] = px0[i][j]; > - } > - } > - } > - if (which == 23) > - { > - for ( i=1 ; i<6 ; i++ ) > - { > - for (j=1 ; j - { > - za[i][j] = za0[i][j]; > - } > - } > - } > - k3 = k2 = 0; > - stb5 = stb50; > - xx[0] = xx0; > - > - } > - } > - return 0; > -} > - > -/ > ************************************************************************ > - * init procedure - initialises data for all > loops * > - > ************************************************************************/ > - > - void init(long which) > - { > - long i, j, k, l, m, nn; > - double ds, dw, rr, ss; > - double fuzz, fizz, buzz, scaled, one; > - > - scaled = (double)(10.0); > - scaled = (double)(1.0) / scaled; > - fuzz = (double)(0.0012345); > - buzz = (double)(1.0) + fuzz; > - fizz = (double)(1.1) * fuzz; > - one = (double)(1.0); > - > - for ( k=0 ; k<19977 + 34132 ; k++) > - { > - if (k == 19977) > - { > - fuzz = (double)(0.0012345); > - buzz = (double) (1.0) + fuzz; > - fizz = (double) (1.1) * fuzz; > - } > - buzz = (one - fuzz) * buzz + fuzz; > - fuzz = - fuzz; > - u[k] = (buzz - fizz) * scaled; > - } > - > - fuzz = (double)(0.0012345); > - buzz = (double) (1.0) + fuzz; > - fizz = (double) (1.1) * fuzz; > - > - for ( k=1 ; k<40 ; k++) > - { > - buzz = (one - fuzz) * buzz + fuzz; > - fuzz = - fuzz; > - xtra[k] = (buzz - fizz) * scaled; > - } > - > - ds = 1.0; > - dw = 0.5; > - for ( l=0 ; l<4 ; l++ ) > - { > - for ( i=0 ; i<512 ; i++ ) > - { > - p[i][l] = ds; > - ds = ds + dw; > - } > - } > - for ( i=0 ; i<96 ; i++ ) > - { > - e[i] = 1; > - f[i] = 1; > - } > - > - > - iqranf(); > - dw = -100.0; > - for ( i=0; i<1001 ; i++ ) > - { > - dex[i] = dw * dex[i]; > - grd[i] = ix[i]; > - } > - flx = 0.001; > - > - > - d[0]= 1.01980486428764; > - nn = n16; > - > - for ( l=1 ; l<300 ; l++ ) > - { > - d[l] = d[l-1] + 1.000e-4 / d[l-1]; > - } > - rr = d[nn-1]; > - for ( l=1 ; l<=2 ; l++ ) > - { > - m = (nn+nn)*(l-1); > - for ( j=1 ; j<=2 ; j++ ) > - { > - for ( k=1 ; k<=nn ; k++ ) > - { > - m = m + 1; > - ss = (double)(k); > - plan[m-1] = rr * ((ss + 1.0) / ss); > - zone[m-1] = k + k; > - } > - } > - } > - k = nn + nn + 1; > - zone[k-1] = nn; > - > - if (which == 16) > - { > - r = d[n-1]; > - s = d[n-2]; > - t = d[n-3]; > - k3 = k2 = 0; > - } > - expmax = 20.0; > - if (which == 22) > - { > - u[n-1] = 0.99*expmax*v[n-1]; > - } > - if (which == 24) > - { > - x[n/2] = -1.0e+10; > - } > - > -/ > ************************************************************************ > - * Make copies of data for extra > loops * > - > ************************************************************************/ > - > - for ( i=0; i<1001 ; i++ ) > - { > - x0[i] = x[i]; > - w0[i] = w[i]; > - } > - for ( i=0 ; i<101 ; i++ ) > - { > - for (j=0 ; j<25 ; j++ ) > - { > - px0[i][j] = px[i][j]; > - } > - } > - for ( i=0 ; i<512 ; i++ ) > - { > - for (j=0 ; j<4 ; j++ ) > - { > - p0[i][j] = p[i][j]; > - } > - } > - for ( i=0 ; i<64 ; i++ ) > - { > - for (j=0 ; j<64 ; j++ ) > - { > - h0[i][j] = h[i][j]; > - } > - } > - for ( i=0; i<2048 ; i++ ) > - { > - rh0[i] = rh[i]; > - } > - for ( i=0; i<101 ; i++ ) > - { > - vxne0[i] = vxne[i]; > - } > - for ( i=0 ; i<7 ; i++ ) > - { > - for (j=0 ; j<101 ; j++ ) > - { > - zr0[i][j] = zr[i][j]; > - zu0[i][j] = zu[i][j]; > - zv0[i][j] = zv[i][j]; > - zz0[i][j] = zz[i][j]; > - za0[i][j] = za[i][j]; > - } > - } > - stb50 = stb5; > - xx0 = xx[0]; > - > - return; > - } > - > -/ > ************************************************************************ > - * parameters procedure for loop counts, Do spans, sumchecks, > FLOPS * > - > ************************************************************************/ > - > - long parameters(long which) > - { > - > - long nloops[3][25] = > - { {0, 1001, 101, 1001, 1001, 1001, 64, 995, 100, > - 101, 101, 1001, 1000, 64, 1001, 101, 75, > - 101, 100, 101, 1000, 101, 101, 100, 1001 }, > - {0, 101, 101, 101, 101, 101, 32, 101, 100, > - 101, 101, 101, 100, 32, 101, 101, 40, > - 101, 100, 101, 100, 50, 101, 100, 101 }, > - {0, 27, 15, 27, 27, 27, 8, 21, 14, > - 15, 15, 27, 26, 8, 27, 15, 15, > - 15, 14, 15, 26, 20, 15, 14, 27 } }; > - > - > - > - long lpass[3][25] = > - { {0, 7, 67, 9, 14, 10, 3, 4, 10, 36, 34, 11, 12, > - 36, 2, 1, 25, 35, 2, 39, 1, 1, 11, 8, 5 }, > - {0, 40, 40, 53, 70, 55, 7, 22, 6, 21, 19, 64, 68, > - 41, 10, 1, 27, 20, 1, 23, 8, 1, 7, 5, > 31 }, > - {0, 28, 46, 37, 38, 40, 21, 20, 9, 26, 25, 46, 48, > - 31, 8, 1, 14, 26, 2, 28, 7, 1, 8, 7, > 23 } }; > - > - double sums[3][25] = > - { > - { 0.0, > - 5.114652693224671e+04, 1.539721811668385e+03, > 1.000742883066363e+01, > - 5.999250595473891e-01, 4.548871642387267e+03, > 4.375116344729986e+03, > - 6.104251075174761e+04, 1.501268005625798e+05, > 1.189443609974981e+05, > - 7.310369784325296e+04, 3.342910972650109e+07, > 2.907141294167248e-05, > - 1.202533961842803e+11, 3.165553044000334e+09, > 3.943816690352042e+04, > - 5.650760000000000e+05, 1.114641772902486e+03, > 1.015727037502300e+05, > - 5.421816960147207e+02, 3.040644339351239e+07, > 1.597308280710199e+08, > - 2.938604376566697e+02, 3.549900501563623e+04, > 5.000000000000000e+02 > - }, > - > - { 0.0, > - 5.253344778937972e+02, 1.539721811668385e+03, > 1.009741436578952e+00, > - 5.999250595473891e-01, 4.589031939600982e+01, > 8.631675645333210e+01, > - 6.345586315784055e+02, 1.501268005625798e+05, > 1.189443609974981e+05, > - 7.310369784325296e+04, 3.433560407475758e+04, > 7.127569130821465e-06, > - 9.816387810944345e+10, 3.039983465145393e+07, > 3.943816690352042e+04, > - 6.480410000000000e+05, 1.114641772902486e+03, > 1.015727037502300e+05, > - 5.421816960147207e+02, 3.126205178815431e+04, > 7.824524877232093e+07, > - 2.938604376566697e+02, 3.549900501563623e+04, > 5.000000000000000e+01 > - }, > - > - { 0.0, > - 3.855104502494961e+01, 3.953296986903059e+01, > 2.699309089320672e-01, > - 5.999250595473891e-01, 3.182615248447483e+00, > 1.120309393467088e+00, > - 2.845720217644024e+01, 2.960543667875003e+03, > 2.623968460874250e+03, > - 1.651291227698265e+03, 6.551161335845770e+02, > 1.943435981130448e-06, > - 3.847124199949426e+10, 2.923540598672011e+06, > 1.108997288134785e+03, > - 5.152160000000000e+05, 2.947368618589360e+01, > 9.700646212337040e+02, > - 1.268230698051003e+01, 5.987713249475302e+02, > 5.009945671204667e+07, > - 6.109968728263972e+00, 4.850340602749970e+02, > 1.300000000000000e+01 > - } }; > - > - > - > - double number_flops[25] = {0, 5., 4., 2., 2., 2., 2., 16., > 36., 17., > - 9., 1., 1., 7., 11., 33.,10., > 9., 44., > - 6., 26., 2., 17., 11., 1.}; > - double now = 1.0; > - > - > - n = nloops[section][which]; > - nspan[section][which] = n; > - n16 = nloops[section][16]; > - nflops = number_flops[which]; > - xflops[which] = nflops; > - loop = lpass[section][which]; > - xloops[section][which] = loop; > - loop = loop * mult; > - MasterSum = sums[section][which]; > - count = 0; > - > - init(which); > - > - > - return 0; > - } > - > -/ > ************************************************************************ > - * check procedure to check accuracy of > calculations * > - > ************************************************************************/ > - > - void check(long which) > - { > - long maxs = 16; > - double xm, ym, re, min1, max1; > - > - xm = MasterSum; > - ym = Checksum[section][which]; > - > - if (xm * ym < 0.0) > - { > - accuracy[section][which] = 0; > - } > - else > - { > - if ( xm == ym) > - { > - accuracy[section][which] = maxs; > - } > - else > - { > - xm = fabs(xm); > - ym = fabs(ym); > - min1 = xm; > - max1 = ym; > - if (ym < xm) > - { > - min1 = ym; > - max1 = xm; > - } > - re = 1.0 - min1 / max1; > - accuracy[section][which] = > - (long) > ( fabs(log10(fabs(re))) + 0.5); > - } > - } > - > - return; > - } > - > -/ > ************************************************************************ > - * iqranf procedure - random number generator for Kernel > 14 * > - > ************************************************************************/ > - > - void iqranf() > - { > - > - long inset, Mmin, Mmax, nn, i, kk; > - double span, spin, realn, per, scale1, qq, dkk, dp, dq; > - long seed[3] = { 256, 12491249, 1499352848 }; > - > - nn = 1001; > - Mmin = 1; > - Mmax = 1001; > - kk = seed[section]; > - > - inset= Mmin; > - span= Mmax - Mmin; > - spin= 16807; > - per= 2147483647; > - realn= nn; > - scale1= 1.00001; > - qq= scale1 * (span / realn); > - dkk= kk; > - > - for ( i=0 ; i - { > - dp= dkk*spin; > - dkk= dp - (long)( dp/per)*per; > - dq= dkk*span; > - ix[i] = inset + ( dq/ per); > - if (ix[i] < Mmin | ix[i] > Mmax) > - { > - ix[i] = inset + i + 1 * qq; > - } > - } > - > - return; > - } > - > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2624 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081201/066fdba5/attachment.bin From dalej at apple.com Mon Dec 1 19:30:54 2008 From: dalej at apple.com (Dale Johannesen) Date: Tue, 02 Dec 2008 01:30:54 -0000 Subject: [llvm-commits] [llvm] r60391 - /llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200812020130.mB21Usi0025951@zion.cs.uiuc.edu> Author: johannes Date: Mon Dec 1 19:30:54 2008 New Revision: 60391 URL: http://llvm.org/viewvc/llvm-project?rev=60391&view=rev Log: Add a few more transformations. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=60391&r1=60390&r2=60391&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon Dec 1 19:30:54 2008 @@ -1013,6 +1013,30 @@ // fold ((B-A)+A) -> B if (N0.getOpcode() == ISD::SUB && N1 == N0.getOperand(1)) return N0.getOperand(0); + // fold (A+(B-(A+C))) to (B-C) + if (N1.getOpcode() == ISD::SUB && N1.getOperand(1).getOpcode() == ISD::ADD && + N0 == N1.getOperand(1).getOperand(0)) { + return DAG.getNode(ISD::SUB, VT, N1.getOperand(0), + N1.getOperand(1).getOperand(1)); + } + // fold (A+(B-(C+A))) to (B-C) + if (N1.getOpcode() == ISD::SUB && N1.getOperand(1).getOpcode() == ISD::ADD && + N0 == N1.getOperand(1).getOperand(1)) { + return DAG.getNode(ISD::SUB, VT, N1.getOperand(0), + N1.getOperand(1).getOperand(0)); + } + // fold (A-B)+(C-D) to (A+C)-(B+D) when A or C is constant + if (N0.getOpcode() == ISD::SUB && N1.getOpcode() == ISD::SUB) { + SDValue N00 = N0.getOperand(0); + SDValue N01 = N0.getOperand(1); + SDValue N10 = N1.getOperand(0); + SDValue N11 = N1.getOperand(1); + if (isa(N00) || isa(N10)) { + return DAG.getNode(ISD::SUB, VT, + DAG.getNode(ISD::ADD, VT, N00, N10), + DAG.getNode(ISD::ADD, VT, N01, N11)); + } + } if (!VT.isVector() && SimplifyDemandedBits(SDValue(N, 0))) return SDValue(N, 0); From evan.cheng at apple.com Mon Dec 1 20:15:36 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 02 Dec 2008 02:15:36 -0000 Subject: [llvm-commits] [llvm] r60392 - in /llvm/trunk: lib/CodeGen/VirtRegMap.cpp test/CodeGen/X86/2008-12-01-SpillerAssert.ll Message-ID: <200812020215.mB22Fa98027101@zion.cs.uiuc.edu> Author: evancheng Date: Mon Dec 1 20:15:36 2008 New Revision: 60392 URL: http://llvm.org/viewvc/llvm-project?rev=60392&view=rev Log: Fix PR3124: overly strict assert. Added: llvm/trunk/test/CodeGen/X86/2008-12-01-SpillerAssert.ll Modified: llvm/trunk/lib/CodeGen/VirtRegMap.cpp Modified: llvm/trunk/lib/CodeGen/VirtRegMap.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.cpp?rev=60392&r1=60391&r2=60392&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/VirtRegMap.cpp (original) +++ llvm/trunk/lib/CodeGen/VirtRegMap.cpp Mon Dec 1 20:15:36 2008 @@ -1760,8 +1760,10 @@ SmallVector KillRegs; InvalidateKills(MI, RegKills, KillOps, &KillRegs); if (MO.isDead() && !KillRegs.empty()) { - // Source register or an implicit super-register use is killed. - assert(KillRegs[0] == Dst || TRI->isSubRegister(KillRegs[0], Dst)); + // Source register or an implicit super/sub-register use is killed. + assert(KillRegs[0] == Dst || + TRI->isSubRegister(KillRegs[0], Dst) || + TRI->isSuperRegister(KillRegs[0], Dst)); // Last def is now dead. TransferDeadness(&MBB, Dist, Src, RegKills, KillOps); } Added: llvm/trunk/test/CodeGen/X86/2008-12-01-SpillerAssert.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2008-12-01-SpillerAssert.ll?rev=60392&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2008-12-01-SpillerAssert.ll (added) +++ llvm/trunk/test/CodeGen/X86/2008-12-01-SpillerAssert.ll Mon Dec 1 20:15:36 2008 @@ -0,0 +1,15 @@ +; RUN: llvm-as < %s | llc -mtriple=x86_64-unknown-linux-gnu +; PR3124 + + %struct.cpuinfo_x86 = type { i8, i8, i8, i8, i32, i8, i8, i8, i32, i32, [9 x i32], [16 x i8], [64 x i8], i32, i32, i32, i64, %struct.cpumask_t, i16, i16, i16, i16, i16, i16, i16, i16, i32 } + %struct.cpumask_t = type { [1 x i64] } + at .str10 = external constant [70 x i8] ; <[70 x i8]*> [#uses=1] + +declare i32 @printk(i8*, ...) + +define void @display_cacheinfo(%struct.cpuinfo_x86* %c) nounwind section ".cpuinit.text" { +entry: + %asmtmp = tail call { i32, i32, i32, i32 } asm "cpuid", "={ax},={bx},={cx},={dx},0,2,~{dirflag},~{fpsr},~{flags}"(i32 -2147483643, i32 0) nounwind ; <{ i32, i32, i32, i32 }> [#uses=0] + %0 = tail call i32 (i8*, ...)* @printk(i8* getelementptr ([70 x i8]* @.str10, i32 0, i64 0), i32 0, i32 0, i32 0, i32 0) nounwind ; [#uses=0] + unreachable +} From resistor at mac.com Mon Dec 1 22:09:22 2008 From: resistor at mac.com (Owen Anderson) Date: Tue, 02 Dec 2008 04:09:22 -0000 Subject: [llvm-commits] [llvm] r60393 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp Message-ID: <200812020409.mB249NKL030492@zion.cs.uiuc.edu> Author: resistor Date: Mon Dec 1 22:09:22 2008 New Revision: 60393 URL: http://llvm.org/viewvc/llvm-project?rev=60393&view=rev Log: Fix an issue that Chris noticed, where local PRE was not properly instantiating a new value numbering set after splitting a critical edge. This increases the number of instances of PRE on 403.gcc from ~60 to ~570. Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=60393&r1=60392&r2=60393&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Mon Dec 1 22:09:22 2008 @@ -1299,6 +1299,7 @@ if (isCriticalEdge(PREPred->getTerminator(), succNum)) { toSplit.push_back(std::make_pair(PREPred->getTerminator(), succNum)); + Changed = true; continue; } @@ -1361,10 +1362,14 @@ } for (SmallVector, 4>::iterator - I = toSplit.begin(), E = toSplit.end(); I != E; ++I) + I = toSplit.begin(), E = toSplit.end(); I != E; ++I) { SplitCriticalEdge(I->first, I->second, this); + BasicBlock* NewBlock = I->first->getSuccessor(I->second); + localAvail[NewBlock] = + new ValueNumberScope(localAvail[I->first->getParent()]); + } - return Changed || toSplit.size(); + return Changed; } // iterateOnFunction - Executes one iteration of GVN From clattner at apple.com Mon Dec 1 22:12:12 2008 From: clattner at apple.com (Chris Lattner) Date: Mon, 1 Dec 2008 20:12:12 -0800 Subject: [llvm-commits] [llvm] r60393 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp In-Reply-To: <200812020409.mB249NKL030492@zion.cs.uiuc.edu> References: <200812020409.mB249NKL030492@zion.cs.uiuc.edu> Message-ID: <327FDE4D-65E6-4B55-9F78-FFE14220A86E@apple.com> On Dec 1, 2008, at 8:09 PM, Owen Anderson wrote: > Author: resistor > Date: Mon Dec 1 22:09:22 2008 > New Revision: 60393 > > URL: http://llvm.org/viewvc/llvm-project?rev=60393&view=rev > Log: > Fix an issue that Chris noticed, where local PRE was not properly > instantiating > a new value numbering set after splitting a critical edge. This > increases > the number of instances of PRE on 403.gcc from ~60 to ~570. Thanks Owen, but testcase please! We don't have enough feature tests for GVN, please help fix! -Chris > > > Modified: > llvm/trunk/lib/Transforms/Scalar/GVN.cpp > > Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=60393&r1=60392&r2=60393&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) > +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Mon Dec 1 22:09:22 2008 > @@ -1299,6 +1299,7 @@ > > if (isCriticalEdge(PREPred->getTerminator(), succNum)) { > toSplit.push_back(std::make_pair(PREPred->getTerminator(), > succNum)); > + Changed = true; > continue; > } > > @@ -1361,10 +1362,14 @@ > } > > for (SmallVector, 4>::iterator > - I = toSplit.begin(), E = toSplit.end(); I != E; ++I) > + I = toSplit.begin(), E = toSplit.end(); I != E; ++I) { > SplitCriticalEdge(I->first, I->second, this); > + BasicBlock* NewBlock = I->first->getSuccessor(I->second); > + localAvail[NewBlock] = > + new ValueNumberScope(localAvail[I->first->getParent()]); > + } > > - return Changed || toSplit.size(); > + return Changed; > } > > // iterateOnFunction - Executes one iteration of GVN > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From resistor at mac.com Mon Dec 1 22:25:45 2008 From: resistor at mac.com (Owen Anderson) Date: Tue, 02 Dec 2008 04:25:45 -0000 Subject: [llvm-commits] [llvm] r60394 - /llvm/trunk/test/Transforms/GVN/pre.ll Message-ID: <200812020425.mB24PjU7031032@zion.cs.uiuc.edu> Author: resistor Date: Mon Dec 1 22:25:42 2008 New Revision: 60394 URL: http://llvm.org/viewvc/llvm-project?rev=60394&view=rev Log: Add a test for my previous PRE fix. Added: llvm/trunk/test/Transforms/GVN/pre.ll Added: llvm/trunk/test/Transforms/GVN/pre.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/pre.ll?rev=60394&view=auto ============================================================================== --- llvm/trunk/test/Transforms/GVN/pre.ll (added) +++ llvm/trunk/test/Transforms/GVN/pre.ll Mon Dec 1 22:25:42 2008 @@ -0,0 +1,27 @@ +; RUN: llvm-as < %s | opt -gvn -enable-pre | llvm-dis | grep {.pre} + + at H = common global i32 0 ; [#uses=2] + at G = common global i32 0 ; [#uses=1] + +define i32 @test() nounwind { +entry: + %0 = load i32* @H, align 4 ; [#uses=2] + %1 = call i32 (...)* @foo() nounwind ; [#uses=1] + %2 = icmp ne i32 %1, 0 ; [#uses=1] + br i1 %2, label %bb, label %bb1 + +bb: ; preds = %entry + %3 = add i32 %0, 42 ; [#uses=1] + store i32 %3, i32* @G, align 4 + br label %bb1 + +bb1: ; preds = %bb, %entry + %4 = add i32 %0, 42 ; [#uses=1] + store i32 %4, i32* @H, align 4 + br label %return + +return: ; preds = %bb1 + ret i32 0 +} + +declare i32 @foo(...) From resistor at mac.com Mon Dec 1 22:25:56 2008 From: resistor at mac.com (Owen Anderson) Date: Mon, 01 Dec 2008 20:25:56 -0800 Subject: [llvm-commits] [llvm] r60393 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp In-Reply-To: <327FDE4D-65E6-4B55-9F78-FFE14220A86E@apple.com> References: <200812020409.mB249NKL030492@zion.cs.uiuc.edu> <327FDE4D-65E6-4B55-9F78-FFE14220A86E@apple.com> Message-ID: <0DCB96AA-A9FC-4240-8E45-52FC5607ECA2@mac.com> Done. --Owen On Dec 1, 2008, at 8:12 PM, Chris Lattner wrote: > > On Dec 1, 2008, at 8:09 PM, Owen Anderson wrote: > >> Author: resistor >> Date: Mon Dec 1 22:09:22 2008 >> New Revision: 60393 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=60393&view=rev >> Log: >> Fix an issue that Chris noticed, where local PRE was not properly >> instantiating >> a new value numbering set after splitting a critical edge. This >> increases >> the number of instances of PRE on 403.gcc from ~60 to ~570. > > Thanks Owen, but testcase please! We don't have enough feature tests > for GVN, please help fix! > > -Chris > >> >> >> Modified: >> llvm/trunk/lib/Transforms/Scalar/GVN.cpp >> >> Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=60393&r1=60392&r2=60393&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) >> +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Mon Dec 1 22:09:22 2008 >> @@ -1299,6 +1299,7 @@ >> >> if (isCriticalEdge(PREPred->getTerminator(), succNum)) { >> toSplit.push_back(std::make_pair(PREPred->getTerminator(), >> succNum)); >> + Changed = true; >> continue; >> } >> >> @@ -1361,10 +1362,14 @@ >> } >> >> for (SmallVector, 4>::iterator >> - I = toSplit.begin(), E = toSplit.end(); I != E; ++I) >> + I = toSplit.begin(), E = toSplit.end(); I != E; ++I) { >> SplitCriticalEdge(I->first, I->second, this); >> + BasicBlock* NewBlock = I->first->getSuccessor(I->second); >> + localAvail[NewBlock] = >> + new ValueNumberScope(localAvail[I->first- >> >getParent()]); >> + } >> >> - return Changed || toSplit.size(); >> + return Changed; >> } >> >> // iterateOnFunction - Executes one iteration of GVN >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2624 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081201/529f2ff8/attachment.bin From sabre at nondot.org Mon Dec 1 22:52:27 2008 From: sabre at nondot.org (Chris Lattner) Date: Tue, 02 Dec 2008 04:52:27 -0000 Subject: [llvm-commits] [llvm] r60395 - /llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200812020452.mB24qRDS031990@zion.cs.uiuc.edu> Author: lattner Date: Mon Dec 1 22:52:26 2008 New Revision: 60395 URL: http://llvm.org/viewvc/llvm-project?rev=60395&view=rev Log: some random comment improvements. Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=60395&r1=60394&r2=60395&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Mon Dec 1 22:52:26 2008 @@ -643,8 +643,10 @@ // cases (e.g. use of a post-incremented induction variable) the NewBase // value will be pinned to live somewhere after the original computation. // In this case, we have to back off. - // However, do not insert new code inside the loop when the reference - // is outside. + // + // If this is a use outside the loop (which means after, since it is based + // on a loop indvar) we use the post-incremented value, so that we don't + // artificially make the preinc value live out the bottom of the loop. if (!isUseOfPostIncrementedValue && L->contains(Inst->getParent())) { if (NewBasePt && isa(OperandValToReplace)) { InsertPt = NewBasePt; @@ -920,17 +922,22 @@ /// RemoveCommonExpressionsFromUseBases - Look through all of the uses in Bases, /// removing any common subexpressions from it. Anything truly common is /// removed, accumulated, and returned. This looks for things like (a+b+c) and -/// (a+c+d) -> (a+c). The common expression is *removed* from the Bases. +/// (a+c+d) and computes the common (a+c) subexpression. The common expression +/// is *removed* from the Bases and returned. static SCEVHandle RemoveCommonExpressionsFromUseBases(std::vector &Uses, ScalarEvolution *SE, Loop *L) { unsigned NumUses = Uses.size(); - // Only one use? If inside the loop, use its base, regardless of what it is; - // if outside, use 0. + // Only one use? This is a very common case, so we handle it specially and + // cheaply. SCEVHandle Zero = SE->getIntegerSCEV(0, Uses[0].Base->getType()); SCEVHandle Result = Zero; if (NumUses == 1) { + // If the use is inside the loop, use its base, regardless of what it is: + // it is clearly shared across all the IV's. If the use is outside the loop + // (which means after it) we don't want to factor anything *into* the loop, + // so just use 0 as the base. if (L->contains(Uses[0].Inst->getParent())) std::swap(Result, Uses[0].Base); return Result; @@ -945,9 +952,14 @@ std::vector UniqueSubExprs; std::vector SubExprs; - uint64_t NumUsesInsideLoop = 0; + unsigned NumUsesInsideLoop = 0; for (unsigned i = 0; i != NumUses; ++i) { - // For this purpose, consider only uses that are inside the loop. + // If the user is outside the loop, just ignore it for base computation. + // Since the user is outside the loop, it must be *after* the loop (if it + // were before, it could not be based on the loop IV). We don't want users + // after the loop to affect base computation of values *inside* the loop, + // because we can always add their offsets to the result IV after the loop + // is done, ensuring we get good code inside the loop. if (!L->contains(Uses[i].Inst->getParent())) continue; NumUsesInsideLoop++; @@ -971,12 +983,11 @@ std::map::iterator I = SubExpressionUseCounts.find(UniqueSubExprs[i]); assert(I != SubExpressionUseCounts.end() && "Entry not found?"); - if (I->second == NumUsesInsideLoop) { // Found CSE! + if (I->second == NumUsesInsideLoop) // Found CSE! Result = SE->getAddExpr(Result, I->first); - } else { + else // Remove non-cse's from SubExpressionUseCounts. SubExpressionUseCounts.erase(I); - } } // If we found no CSE's, return now. @@ -998,7 +1009,7 @@ --j; --e; } - // Finally, the non-shared expressions together. + // Finally, add the non-shared expressions together. if (SubExprs.empty()) Uses[i].Base = Zero; else From dpatel at apple.com Mon Dec 1 22:53:57 2008 From: dpatel at apple.com (Devang Patel) Date: Tue, 02 Dec 2008 04:53:57 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60396 - /llvm-gcc-4.2/trunk/build_gcc Message-ID: <200812020453.mB24rvKP032069@zion.cs.uiuc.edu> Author: dpatel Date: Mon Dec 1 22:53:57 2008 New Revision: 60396 URL: http://llvm.org/viewvc/llvm-project?rev=60396&view=rev Log: This does not work as expected. Modified: llvm-gcc-4.2/trunk/build_gcc Modified: llvm-gcc-4.2/trunk/build_gcc URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/build_gcc?rev=60396&r1=60395&r2=60396&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/build_gcc (original) +++ llvm-gcc-4.2/trunk/build_gcc Mon Dec 1 22:53:57 2008 @@ -618,12 +618,6 @@ rm libllvmgcc.dylib ln -s ../../libllvmgcc.dylib done - -if [ "x$RC_XBS" != "x" ]; then - mkdir -p $DEST_DIR/usr/bin - ln -s $DEST_DIR$LLVM_BIN_DIR/llvm-gcc $DEST_DIR/usr/bin/llvm-gcc - ln -s $DEST_DIR$LLVM_BIN_DIR/llvm-g++ $DEST_DIR/usr/bin/llvm-g++ -fi # LLVM LOCAL end find $DEST_DIR -name \*.dSYM -print | xargs rm -r || exit 1 From clattner at apple.com Mon Dec 1 22:56:08 2008 From: clattner at apple.com (Chris Lattner) Date: Mon, 1 Dec 2008 20:56:08 -0800 Subject: [llvm-commits] [llvm] r60374 - in /llvm/trunk: lib/Transforms/Scalar/LoopStrengthReduce.cpp test/CodeGen/X86/2008-12-01-loop-iv-used-outside-loop.ll In-Reply-To: <200812012200.mB1M02ID019041@zion.cs.uiuc.edu> References: <200812012200.mB1M02ID019041@zion.cs.uiuc.edu> Message-ID: On Dec 1, 2008, at 2:00 PM, Dale Johannesen wrote: > URL: http://llvm.org/viewvc/llvm-project?rev=60374&view=rev > Log: > Consider only references to an IV within the loop when > figuring out the base of the IV. This produces better > code in the example. (Addresses use (IV) instead of > (BASE,IV) - a significant improvement on low-register > machines like x86). Dale, this is an outstanding patch, thank you for tackling this! For anyone following on the sidelines, this helps fix a performance problem when compiling an inner loop of the GCC lexer. One question: > > // Otherwise, remove all of the CSE's we found from each of the > base values. > for (unsigned i = 0; i != NumUses; ++i) { > + // For this purpose, consider only uses that are inside the loop. > + if (!L->contains(Uses[i].Inst->getParent())) > + continue; > + > > @@ -1450,6 +1464,12 @@ > > + // If this reference is not in the loop and we have a Common > base, > + // that has been added into the induction variable and must be > + // subtracted off here. > + if (HaveCommonExprs && !L->contains(User.Inst->getParent())) > + RewriteExpr = SE->getMinusSCEV(RewriteExpr, CommonExprs); > + These two hunks add a very subtle (and undocumented/commented) issue: users outside the loop are missing common exprs from their base. Would it be possible to change the first hunk to something like: if (!L->contains(Uses[i].Inst->getParent())) { Uses[i].Base = SE->getSubExpr(Uses[i].Base, CommonExprs); continue; } I think this eliminates the need for the second hunk. Could this work? -Chris From clattner at apple.com Mon Dec 1 23:00:49 2008 From: clattner at apple.com (Chris Lattner) Date: Mon, 1 Dec 2008 21:00:49 -0800 Subject: [llvm-commits] [llvm] r60343 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp In-Reply-To: <200812010823.mB18NRsh013532@zion.cs.uiuc.edu> References: <200812010823.mB18NRsh013532@zion.cs.uiuc.edu> Message-ID: <3CA29621-0342-4FA9-A4EA-FEFDD370AA70@apple.com> On Dec 1, 2008, at 12:23 AM, Bill Wendling wrote: > Author: void > Date: Mon Dec 1 02:23:25 2008 > New Revision: 60343 > > URL: http://llvm.org/viewvc/llvm-project?rev=60343&view=rev > Log: > Reduce copy-and-paste code by splitting out the code into its own > function. Thanks! Next step: > +Instruction *InstCombiner::FoldOrWithConstants(BinaryOperator &I, > + Value *A, Value *B, > Value *C) { > + Value *Op1 = I.getOperand(1); > + > + if (ConstantInt *CI = dyn_cast(C)) { > + if (CI->getValue() == 1) { Now that this is a function, there is no need to nest this. Just use early outs to keep it linear and unnested. > > + Value *V1 = 0, *C2 = 0; > + if (match(Op1, m_And(m_Value(V1), m_Value(C2)))) { > + ConstantInt *CI2 = dyn_cast(C2); > + > + if (!CI2) { > + std::swap(V1, C2); > + CI2 = dyn_cast(C2); > + } No need to test for this. and(cst, V) will be canonicalized to and(V, cst). All commutative operations commute constants to their RHS. > > + > + if (CI2) { > + APInt NegTwo = -APInt(CI2->getValue().getBitWidth(), 2, > true); You're still testing magic constants. Please generalize this. > > + if (CI2->getValue().eq(NegTwo)) { I think you can use == instead of .eq. > > + if (V1 == B) { > + Instruction *NewOp = > + InsertNewInstBefore(BinaryOperator::CreateAnd(A, > CI), I); > + return BinaryOperator::CreateOr(NewOp, B); > + } > + if (V1 == A) { > + Instruction *NewOp = > + InsertNewInstBefore(BinaryOperator::CreateAnd(B, > CI), I); > + return BinaryOperator::CreateOr(NewOp, A); > + } Please merge these two if's. -Chris From clattner at apple.com Mon Dec 1 23:03:06 2008 From: clattner at apple.com (Chris Lattner) Date: Mon, 1 Dec 2008 21:03:06 -0800 Subject: [llvm-commits] [llvm] r60344 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp In-Reply-To: <200812010832.mB18WiJ8013930@zion.cs.uiuc.edu> References: <200812010832.mB18WiJ8013930@zion.cs.uiuc.edu> Message-ID: <63452EFC-CDF5-4395-8BBB-601CA29897AE@apple.com> On Dec 1, 2008, at 12:32 AM, Bill Wendling wrote: > Author: void > Date: Mon Dec 1 02:32:40 2008 > New Revision: 60344 > > URL: http://llvm.org/viewvc/llvm-project?rev=60344&view=rev > Log: > Generalize the FoldOrWithConstant method to fold for any two > constants which > don't have overlapping bits. Ah, thank you for generalizing this! > /// FoldOrWithConstants - This helper function folds: > /// > +/// ((A | B) & 1) | (B & -2) > /// > /// into: > /// > +/// (A & 1) | B > +/// > +/// The constants aren't important. Only that they don't overlap. > (I.e., the XOR > +/// of the two constants is "all ones".) I don't think this comment is correct, "1" and "4" don't overlap, but they don't xor to -1. -Chris From isanbard at gmail.com Mon Dec 1 23:04:25 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 1 Dec 2008 21:04:25 -0800 Subject: [llvm-commits] [llvm] r60343 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp In-Reply-To: <3CA29621-0342-4FA9-A4EA-FEFDD370AA70@apple.com> References: <200812010823.mB18NRsh013532@zion.cs.uiuc.edu> <3CA29621-0342-4FA9-A4EA-FEFDD370AA70@apple.com> Message-ID: <19B654BC-6B1F-4BD9-A0E1-E1D9DF9634F0@gmail.com> On Dec 1, 2008, at 9:00 PM, Chris Lattner wrote: > > On Dec 1, 2008, at 12:23 AM, Bill Wendling wrote: > >> Author: void >> Date: Mon Dec 1 02:23:25 2008 >> New Revision: 60343 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=60343&view=rev >> Log: >> Reduce copy-and-paste code by splitting out the code into its own >> function. > > Thanks! Next step: > >> +Instruction *InstCombiner::FoldOrWithConstants(BinaryOperator &I, >> + Value *A, Value *B, >> Value *C) { >> + Value *Op1 = I.getOperand(1); >> + >> + if (ConstantInt *CI = dyn_cast(C)) { >> + if (CI->getValue() == 1) { > > Now that this is a function, there is no need to nest this. Just use > early outs to keep it linear and unnested. > Okay. >> >> + Value *V1 = 0, *C2 = 0; >> + if (match(Op1, m_And(m_Value(V1), m_Value(C2)))) { >> + ConstantInt *CI2 = dyn_cast(C2); >> + >> + if (!CI2) { >> + std::swap(V1, C2); >> + CI2 = dyn_cast(C2); >> + } > > No need to test for this. and(cst, V) will be canonicalized to and(V, > cst). All commutative operations commute constants to their RHS. > Ah! good to know. >> >> + >> + if (CI2) { >> + APInt NegTwo = -APInt(CI2->getValue().getBitWidth(), 2, >> true); > > You're still testing magic constants. Please generalize this. > I did in a following patch. >> + if (V1 == B) { >> + Instruction *NewOp = >> + InsertNewInstBefore(BinaryOperator::CreateAnd(A, >> CI), I); >> + return BinaryOperator::CreateOr(NewOp, B); >> + } >> + if (V1 == A) { >> + Instruction *NewOp = >> + InsertNewInstBefore(BinaryOperator::CreateAnd(B, >> CI), I); >> + return BinaryOperator::CreateOr(NewOp, A); >> + } > > Please merge these two if's. > Okay. -bw From isanbard at gmail.com Mon Dec 1 23:06:44 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 02 Dec 2008 05:06:44 -0000 Subject: [llvm-commits] [llvm] r60397 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200812020506.mB256jvO032631@zion.cs.uiuc.edu> Author: void Date: Mon Dec 1 23:06:43 2008 New Revision: 60397 URL: http://llvm.org/viewvc/llvm-project?rev=60397&view=rev Log: - Reduce nesting. - No need to do a swap on a canonicalized pattern. No functionality change. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60397&r1=60396&r2=60397&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Mon Dec 1 23:06:43 2008 @@ -4447,30 +4447,24 @@ /// of the two constants is "all ones".) Instruction *InstCombiner::FoldOrWithConstants(BinaryOperator &I, Value *Op, Value *A, Value *B, Value *C) { - if (ConstantInt *CI1 = dyn_cast(C)) { - Value *V1 = 0, *C2 = 0; - if (match(Op, m_And(m_Value(V1), m_Value(C2)))) { - ConstantInt *CI2 = dyn_cast(C2); - - if (!CI2) { - std::swap(V1, C2); - CI2 = dyn_cast(C2); - } - - if (CI2) { - APInt Xor = CI1->getValue() ^ CI2->getValue(); - if (Xor.isAllOnesValue()) { - if (V1 == B) { - Instruction *NewOp = - InsertNewInstBefore(BinaryOperator::CreateAnd(A, CI1), I); - return BinaryOperator::CreateOr(NewOp, B); - } - if (V1 == A) { - Instruction *NewOp = - InsertNewInstBefore(BinaryOperator::CreateAnd(B, CI1), I); - return BinaryOperator::CreateOr(NewOp, A); - } - } + ConstantInt *CI1 = dyn_cast(C); + if (!CI1) return 0; + + Value *V1 = 0, *C2 = 0; + if (match(Op, m_And(m_Value(V1), m_Value(C2)))) { + ConstantInt *CI2 = dyn_cast(C2); + if (!CI2) return 0; + + APInt Xor = CI1->getValue() ^ CI2->getValue(); + if (Xor.isAllOnesValue()) { + if (V1 == B) { + Instruction *NewOp = + InsertNewInstBefore(BinaryOperator::CreateAnd(A, CI1), I); + return BinaryOperator::CreateOr(NewOp, B); + } else if (V1 == A) { + Instruction *NewOp = + InsertNewInstBefore(BinaryOperator::CreateAnd(B, CI1), I); + return BinaryOperator::CreateOr(NewOp, A); } } } From isanbard at gmail.com Mon Dec 1 23:09:00 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 02 Dec 2008 05:09:00 -0000 Subject: [llvm-commits] [llvm] r60398 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200812020509.mB2591wW000325@zion.cs.uiuc.edu> Author: void Date: Mon Dec 1 23:09:00 2008 New Revision: 60398 URL: http://llvm.org/viewvc/llvm-project?rev=60398&view=rev Log: Improve comment. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60398&r1=60397&r2=60398&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Mon Dec 1 23:09:00 2008 @@ -4437,14 +4437,13 @@ /// FoldOrWithConstants - This helper function folds: /// -/// ((A | B) & 1) | (B & -2) +/// ((A | B) & C1) | (B & C2) /// /// into: /// -/// (A & 1) | B +/// (A & C1) | B /// -/// The constants aren't important. Only that they don't overlap. (I.e., the XOR -/// of the two constants is "all ones".) +/// when the XOR of the two constants is "all ones" (-1). Instruction *InstCombiner::FoldOrWithConstants(BinaryOperator &I, Value *Op, Value *A, Value *B, Value *C) { ConstantInt *CI1 = dyn_cast(C); From isanbard at gmail.com Mon Dec 1 23:09:09 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 1 Dec 2008 21:09:09 -0800 Subject: [llvm-commits] [llvm] r60344 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp In-Reply-To: <63452EFC-CDF5-4395-8BBB-601CA29897AE@apple.com> References: <200812010832.mB18WiJ8013930@zion.cs.uiuc.edu> <63452EFC-CDF5-4395-8BBB-601CA29897AE@apple.com> Message-ID: <8FA079B4-226A-4D4B-B09E-DEFFB157E027@gmail.com> On Dec 1, 2008, at 9:03 PM, Chris Lattner wrote: > On Dec 1, 2008, at 12:32 AM, Bill Wendling wrote: > >> /// FoldOrWithConstants - This helper function folds: >> /// >> +/// ((A | B) & 1) | (B & -2) >> /// >> /// into: >> /// >> +/// (A & 1) | B >> +/// >> +/// The constants aren't important. Only that they don't overlap. >> (I.e., the XOR >> +/// of the two constants is "all ones".) > > I don't think this comment is correct, "1" and "4" don't overlap, but > they don't xor to -1. > Okay. -bw From isanbard at gmail.com Mon Dec 1 23:12:48 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 02 Dec 2008 05:12:48 -0000 Subject: [llvm-commits] [llvm] r60399 - in /llvm/trunk/lib: Target/README.txt Transforms/Scalar/InstructionCombining.cpp Message-ID: <200812020512.mB25CmMp000446@zion.cs.uiuc.edu> Author: void Date: Mon Dec 1 23:12:47 2008 New Revision: 60399 URL: http://llvm.org/viewvc/llvm-project?rev=60399&view=rev Log: - Remove the buggy -X/C -> X/-C transform. This isn't valid when X isn't a constant. If X is a constant, then this is folded elsewhere. - Added a note to Target/README.txt to indicate that we'd like to implement this when we're able. Modified: llvm/trunk/lib/Target/README.txt llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=60399&r1=60398&r2=60399&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Mon Dec 1 23:12:47 2008 @@ -1242,3 +1242,13 @@ optimized with "clang -emit-llvm-bc | opt -std-compile-opts". //===---------------------------------------------------------------------===// + +We would like to do the following transform in the instcombiner: + + -X/C -> X/-C + +However, this isn't valid if (-X) overflows. We can implement this when we +have the concept of a "C signed subtraction" operator that which is undefined +on overflow. + +//===---------------------------------------------------------------------===// Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60399&r1=60398&r2=60399&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Mon Dec 1 23:12:47 2008 @@ -2929,18 +2929,6 @@ // sdiv X, -1 == -X if (RHS->isAllOnesValue()) return BinaryOperator::CreateNeg(Op0); - - // -X/C -> X/-C, if and only if negation doesn't overflow. - if (Value *LHSNeg = dyn_castNegVal(Op0)) { - if (ConstantInt *CI = dyn_cast(LHSNeg)) { - Constant *RHSNeg = ConstantExpr::getNeg(RHS); - if (RHS != RHSNeg) { // Check that there is no overflow. - Constant *CINeg = ConstantExpr::getNeg(CI); - if (CI != CINeg) // Check that there is no overflow. - return BinaryOperator::CreateSDiv(LHSNeg, RHSNeg); - } - } - } } // If the sign bits of both operands are zero (i.e. we can prove they are From clattner at apple.com Mon Dec 1 23:58:01 2008 From: clattner at apple.com (Chris Lattner) Date: Mon, 1 Dec 2008 21:58:01 -0800 Subject: [llvm-commits] [llvm] r60397 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp In-Reply-To: <200812020506.mB256jvO032631@zion.cs.uiuc.edu> References: <200812020506.mB256jvO032631@zion.cs.uiuc.edu> Message-ID: <14C59E60-219E-4EDC-ADBF-1099D3EA082C@apple.com> On Dec 1, 2008, at 9:06 PM, Bill Wendling wrote: > Author: void > Date: Mon Dec 1 23:06:43 2008 > New Revision: 60397 > > URL: http://llvm.org/viewvc/llvm-project?rev=60397&view=rev > Log: > - Reduce nesting. > - No need to do a swap on a canonicalized pattern. > > No functionality change. Thanks Bill, getting better. > + ConstantInt *CI1 = dyn_cast(C); > + if (!CI1) return 0; > + > + Value *V1 = 0, *C2 = 0; > + if (match(Op, m_And(m_Value(V1), m_Value(C2)))) { if (!match) return 0; > > + ConstantInt *CI2 = dyn_cast(C2); > + if (!CI2) return 0; Please pull the matching of C2 -> constantint into the "match". > > + > + APInt Xor = CI1->getValue() ^ CI2->getValue(); > + if (Xor.isAllOnesValue()) { if (!Xor.isAllOnesValue()) return 0; > > + if (V1 == B) { > + Instruction *NewOp = > + InsertNewInstBefore(BinaryOperator::CreateAnd(A, CI1), I); > + return BinaryOperator::CreateOr(NewOp, B); > + } else if (V1 == A) { > + Instruction *NewOp = > + InsertNewInstBefore(BinaryOperator::CreateAnd(B, CI1), I); > + return BinaryOperator::CreateOr(NewOp, A); > } Please merge these. -Chris > > } > } > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Tue Dec 2 00:08:04 2008 From: sabre at nondot.org (Chris Lattner) Date: Tue, 02 Dec 2008 06:08:04 -0000 Subject: [llvm-commits] [llvm] r60400 - /llvm/trunk/include/llvm/ADT/DenseMap.h Message-ID: <200812020608.mB2684jk002314@zion.cs.uiuc.edu> Author: lattner Date: Tue Dec 2 00:08:04 2008 New Revision: 60400 URL: http://llvm.org/viewvc/llvm-project?rev=60400&view=rev Log: add densemap range insertion method. Modified: llvm/trunk/include/llvm/ADT/DenseMap.h Modified: llvm/trunk/include/llvm/ADT/DenseMap.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/DenseMap.h?rev=60400&r1=60399&r2=60400&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/DenseMap.h (original) +++ llvm/trunk/include/llvm/ADT/DenseMap.h Tue Dec 2 00:08:04 2008 @@ -213,6 +213,14 @@ true); } + /// insert - Range insertion of pairs. + template + void insert(InputIt I, InputIt E) { + for (; I != E; ++I) + insert(*I); + } + + bool erase(const KeyT &Val) { BucketT *TheBucket; if (!LookupBucketFor(Val, TheBucket)) From isanbard at gmail.com Tue Dec 2 00:18:12 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 02 Dec 2008 06:18:12 -0000 Subject: [llvm-commits] [llvm] r60401 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200812020618.mB26ICgG002550@zion.cs.uiuc.edu> Author: void Date: Tue Dec 2 00:18:11 2008 New Revision: 60401 URL: http://llvm.org/viewvc/llvm-project?rev=60401&view=rev Log: More styalistic changes. No functionality change. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60401&r1=60400&r2=60401&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Tue Dec 2 00:18:11 2008 @@ -4438,22 +4438,19 @@ if (!CI1) return 0; Value *V1 = 0, *C2 = 0; - if (match(Op, m_And(m_Value(V1), m_Value(C2)))) { - ConstantInt *CI2 = dyn_cast(C2); - if (!CI2) return 0; - - APInt Xor = CI1->getValue() ^ CI2->getValue(); - if (Xor.isAllOnesValue()) { - if (V1 == B) { - Instruction *NewOp = - InsertNewInstBefore(BinaryOperator::CreateAnd(A, CI1), I); - return BinaryOperator::CreateOr(NewOp, B); - } else if (V1 == A) { - Instruction *NewOp = - InsertNewInstBefore(BinaryOperator::CreateAnd(B, CI1), I); - return BinaryOperator::CreateOr(NewOp, A); - } - } + if (!match(Op, m_And(m_Value(V1), m_ConstantInt(C2)))) return 0; + + APInt Xor = CI1->getValue() ^ CI2->getValue(); + if (!Xor.isAllOnesValue()) return 0; + + if (V1 == B) { + Instruction *NewOp = + InsertNewInstBefore(BinaryOperator::CreateAnd(A, CI1), I); + return BinaryOperator::CreateOr(NewOp, B); + } else if (V1 == A) { + Instruction *NewOp = + InsertNewInstBefore(BinaryOperator::CreateAnd(B, CI1), I); + return BinaryOperator::CreateOr(NewOp, A); } return 0; From isanbard at gmail.com Tue Dec 2 00:22:05 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 02 Dec 2008 06:22:05 -0000 Subject: [llvm-commits] [llvm] r60402 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200812020622.mB26M5cG002669@zion.cs.uiuc.edu> Author: void Date: Tue Dec 2 00:22:04 2008 New Revision: 60402 URL: http://llvm.org/viewvc/llvm-project?rev=60402&view=rev Log: Merge two if-statements into one. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60402&r1=60401&r2=60402&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Tue Dec 2 00:22:04 2008 @@ -4443,14 +4443,10 @@ APInt Xor = CI1->getValue() ^ CI2->getValue(); if (!Xor.isAllOnesValue()) return 0; - if (V1 == B) { + if (V1 == A || V1 == B) Instruction *NewOp = - InsertNewInstBefore(BinaryOperator::CreateAnd(A, CI1), I); - return BinaryOperator::CreateOr(NewOp, B); - } else if (V1 == A) { - Instruction *NewOp = - InsertNewInstBefore(BinaryOperator::CreateAnd(B, CI1), I); - return BinaryOperator::CreateOr(NewOp, A); + InsertNewInstBefore(BinaryOperator::CreateAnd((V1 == A) ? B : A, CI1), I); + return BinaryOperator::CreateOr(NewOp, V1); } return 0; From isanbard at gmail.com Tue Dec 2 00:24:20 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 02 Dec 2008 06:24:20 -0000 Subject: [llvm-commits] [llvm] r60403 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200812020624.mB26OKKu002734@zion.cs.uiuc.edu> Author: void Date: Tue Dec 2 00:24:20 2008 New Revision: 60403 URL: http://llvm.org/viewvc/llvm-project?rev=60403&view=rev Log: Remove some errors that crept in. No functionality change. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=60403&r1=60402&r2=60403&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Tue Dec 2 00:24:20 2008 @@ -4437,13 +4437,14 @@ ConstantInt *CI1 = dyn_cast(C); if (!CI1) return 0; - Value *V1 = 0, *C2 = 0; - if (!match(Op, m_And(m_Value(V1), m_ConstantInt(C2)))) return 0; + Value *V1 = 0; + ConstantInt *CI2 = 0; + if (!match(Op, m_And(m_Value(V1), m_ConstantInt(CI2)))) return 0; APInt Xor = CI1->getValue() ^ CI2->getValue(); if (!Xor.isAllOnesValue()) return 0; - if (V1 == A || V1 == B) + if (V1 == A || V1 == B) { Instruction *NewOp = InsertNewInstBefore(BinaryOperator::CreateAnd((V1 == A) ? B : A, CI1), I); return BinaryOperator::CreateOr(NewOp, V1); From isanbard at gmail.com Tue Dec 2 00:24:29 2008 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 1 Dec 2008 22:24:29 -0800 Subject: [llvm-commits] [llvm] r60397 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp In-Reply-To: <14C59E60-219E-4EDC-ADBF-1099D3EA082C@apple.com> References: <200812020506.mB256jvO032631@zion.cs.uiuc.edu> <14C59E60-219E-4EDC-ADBF-1099D3EA082C@apple.com> Message-ID: <16e5fdf90812012224m50132077u8025c9d48f40edc2@mail.gmail.com> Others done. >> + if (V1 == B) { >> + Instruction *NewOp = >> + InsertNewInstBefore(BinaryOperator::CreateAnd(A, CI1), I); >> + return BinaryOperator::CreateOr(NewOp, B); >> + } else if (V1 == A) { >> + Instruction *NewOp = >> + InsertNewInstBefore(BinaryOperator::CreateAnd(B, CI1), I); >> + return BinaryOperator::CreateOr(NewOp, A); >> } > > Please merge these. > Maybe I'm just sleep deprived, but I don't know what you want here. :-) I took a stab at it. -bw From sabre at nondot.org Tue Dec 2 00:32:34 2008 From: sabre at nondot.org (Chris Lattner) Date: Tue, 02 Dec 2008 06:32:34 -0000 Subject: [llvm-commits] [llvm] r60404 - /llvm/trunk/lib/Target/README.txt Message-ID: <200812020632.mB26WY8j003132@zion.cs.uiuc.edu> Author: lattner Date: Tue Dec 2 00:32:34 2008 New Revision: 60404 URL: http://llvm.org/viewvc/llvm-project?rev=60404&view=rev Log: add a note Modified: llvm/trunk/lib/Target/README.txt Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=60404&r1=60403&r2=60404&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Tue Dec 2 00:32:34 2008 @@ -1252,3 +1252,24 @@ on overflow. //===---------------------------------------------------------------------===// + +This was noticed in the entryblock for grokdeclarator in 403.gcc: + + %tmp = icmp eq i32 %decl_context, 4 + %decl_context_addr.0 = select i1 %tmp, i32 3, i32 %decl_context + %tmp1 = icmp eq i32 %decl_context_addr.0, 1 + %decl_context_addr.1 = select i1 %tmp1, i32 0, i32 %decl_context_addr.0 + +tmp1 should be simplified to something like: + (!tmp || decl_context == 1) + +This allows recursive simplifications, tmp1 is used all over the place in +the function, e.g. by: + + %tmp23 = icmp eq i32 %decl_context_addr.1, 0 ; [#uses=1] + %tmp24 = xor i1 %tmp1, true ; [#uses=1] + %or.cond8 = and i1 %tmp23, %tmp24 ; [#uses=1] + +later. + + From clattner at apple.com Tue Dec 2 00:36:59 2008 From: clattner at apple.com (Chris Lattner) Date: Mon, 1 Dec 2008 22:36:59 -0800 Subject: [llvm-commits] [llvm] r60397 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp In-Reply-To: <16e5fdf90812012224m50132077u8025c9d48f40edc2@mail.gmail.com> References: <200812020506.mB256jvO032631@zion.cs.uiuc.edu> <14C59E60-219E-4EDC-ADBF-1099D3EA082C@apple.com> <16e5fdf90812012224m50132077u8025c9d48f40edc2@mail.gmail.com> Message-ID: <2C7CD4D9-4CBB-4A7A-9EB2-C6F3CB6ED6F4@apple.com> On Dec 1, 2008, at 10:24 PM, Bill Wendling wrote: > Others done. > >>> + if (V1 == B) { >>> + Instruction *NewOp = >>> + InsertNewInstBefore(BinaryOperator::CreateAnd(A, CI1), >>> I); >>> + return BinaryOperator::CreateOr(NewOp, B); >>> + } else if (V1 == A) { >>> + Instruction *NewOp = >>> + InsertNewInstBefore(BinaryOperator::CreateAnd(B, CI1), >>> I); >>> + return BinaryOperator::CreateOr(NewOp, A); >>> } >> >> Please merge these. >> > Maybe I'm just sleep deprived, but I don't know what you want here. > :-) I took a stab at it. Looks great, thanks! -chris From echeng at apple.com Tue Dec 2 00:58:51 2008 From: echeng at apple.com (Evan Cheng) Date: Mon, 1 Dec 2008 22:58:51 -0800 Subject: [llvm-commits] [Patch] Custom Lowering for TRUNCATE In-Reply-To: References: <4F419882-73CC-407C-800B-2C33CAB09DF7@apple.com> Message-ID: <7C2FE10F-495E-4363-9767-58E62D735B48@apple.com> This looks good. Can you commit? Thanks, Evan On Dec 1, 2008, at 12:59 PM, Tilmann Scheller wrote: > On Mon, Dec 1, 2008 at 7:35 PM, Evan Cheng > wrote: >> The code to custom lower TRUNCATE should be inside the getTypeAction >> Legal case, right? >> >> switch (getTypeAction(Node->getOperand(0).getValueType())) { >> case Legal: >> >> Evan > Yes, my bad. I've attached a new patch. > > Greetings, > > Tilmann > < > customLowerTruncate2 > .patch>_______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Tue Dec 2 01:16:47 2008 From: sabre at nondot.org (Chris Lattner) Date: Tue, 02 Dec 2008 07:16:47 -0000 Subject: [llvm-commits] [llvm] r60405 - in /llvm/trunk: include/llvm/Value.h lib/VMCore/Value.cpp Message-ID: <200812020716.mB27Glu4004750@zion.cs.uiuc.edu> Author: lattner Date: Tue Dec 2 01:16:45 2008 New Revision: 60405 URL: http://llvm.org/viewvc/llvm-project?rev=60405&view=rev Log: add a little helper function that does PHI translation. Modified: llvm/trunk/include/llvm/Value.h llvm/trunk/lib/VMCore/Value.cpp Modified: llvm/trunk/include/llvm/Value.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Value.h?rev=60405&r1=60404&r2=60405&view=diff ============================================================================== --- llvm/trunk/include/llvm/Value.h (original) +++ llvm/trunk/include/llvm/Value.h Tue Dec 2 01:16:45 2008 @@ -242,6 +242,17 @@ const Value *getUnderlyingObject() const { return const_cast(this)->getUnderlyingObject(); } + + /// DoPHITranslation - If this value is a PHI node with CurBB as a its parent, + /// return the value in the PHI node corresponding to PredBB. If not, return + /// ourself. This is useful if you want to know the value something has in a + /// predecessor block. + Value *DoPHITranslation(const BasicBlock *CurBB, const BasicBlock *PredBB); + + const Value *DoPHITranslation(const BasicBlock *CurBB, + const BasicBlock *PredBB) const{ + return const_cast(this)->DoPHITranslation(CurBB, PredBB); + } }; inline std::ostream &operator<<(std::ostream &OS, const Value &V) { Modified: llvm/trunk/lib/VMCore/Value.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Value.cpp?rev=60405&r1=60404&r2=60405&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Value.cpp (original) +++ llvm/trunk/lib/VMCore/Value.cpp Tue Dec 2 01:16:45 2008 @@ -358,6 +358,19 @@ return this; } +/// DoPHITranslation - If this value is a PHI node with CurBB as a its parent, +/// return the value in the PHI node corresponding to PredBB. If not, return +/// ourself. This is useful if you want to know the value something has in a +/// predecessor block. +Value *Value::DoPHITranslation(const BasicBlock *CurBB, + const BasicBlock *PredBB) { + PHINode *PN = dyn_cast(this); + if (PN && PN->getParent() == CurBB) + return PN->getIncomingValueForBlock(PredBB); + return this; +} + + //===----------------------------------------------------------------------===// // User Class //===----------------------------------------------------------------------===// From wangmp at apple.com Tue Dec 2 01:35:09 2008 From: wangmp at apple.com (Mon P Wang) Date: Tue, 02 Dec 2008 07:35:09 -0000 Subject: [llvm-commits] [llvm] r60406 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200812020735.mB27Z930005283@zion.cs.uiuc.edu> Author: wangmp Date: Tue Dec 2 01:35:08 2008 New Revision: 60406 URL: http://llvm.org/viewvc/llvm-project?rev=60406&view=rev Log: Removed some unnecessary code in widening. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=60406&r1=60405&r2=60406&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Dec 2 01:35:08 2008 @@ -7927,21 +7927,6 @@ Tmp1 = WidenVectorOp(Tmp1, TWidenVT); assert(Tmp1.getValueType().getVectorNumElements() == NewNumElts); Result = DAG.getNode(Node->getOpcode(), WidenVT, Tmp1); - - TargetLowering::LegalizeAction action = - TLI.getOperationAction(Node->getOpcode(), WidenVT); - switch (action) { - default: assert(0 && "action not supported"); - case TargetLowering::Legal: - break; - case TargetLowering::Promote: - // We defer the promotion to when we legalize the op - break; - case TargetLowering::Expand: - // Expand the operation into a bunch of nasty scalar code. - Result = LegalizeOp(UnrollVectorOp(Result)); - break; - } break; } @@ -7963,33 +7948,14 @@ case ISD::CTLZ: { // Unary op widening SDValue Tmp1; - TargetLowering::LegalizeAction action = - TLI.getOperationAction(Node->getOpcode(), WidenVT); - Tmp1 = WidenVectorOp(Node->getOperand(0), WidenVT); assert(Tmp1.getValueType() == WidenVT); Result = DAG.getNode(Node->getOpcode(), WidenVT, Tmp1); - switch (action) { - default: assert(0 && "action not supported"); - case TargetLowering::Legal: - break; - case TargetLowering::Promote: - // We defer the promotion to when we legalize the op - break; - case TargetLowering::Expand: - // Expand the operation into a bunch of nasty scalar code. - Result = LegalizeOp(UnrollVectorOp(Result)); - break; - } break; } case ISD::CONVERT_RNDSAT: { SDValue RndOp = Node->getOperand(3); SDValue SatOp = Node->getOperand(4); - - TargetLowering::LegalizeAction action = - TLI.getOperationAction(Node->getOpcode(), WidenVT); - SDValue SrcOp = Node->getOperand(0); // Converts between two different types so we need to determine @@ -8007,18 +7973,6 @@ Result = DAG.getConvertRndSat(WidenVT, SrcOp, DTyOp, STyOp, RndOp, SatOp, CvtCode); - switch (action) { - default: assert(0 && "action not supported"); - case TargetLowering::Legal: - break; - case TargetLowering::Promote: - // We defer the promotion to when we legalize the op - break; - case TargetLowering::Expand: - // Expand the operation into a bunch of nasty scalar code. - Result = LegalizeOp(UnrollVectorOp(Result)); - break; - } break; } case ISD::FPOW: @@ -8043,53 +7997,28 @@ case ISD::UREM: case ISD::BSWAP: { // Binary op widening - TargetLowering::LegalizeAction action = - TLI.getOperationAction(Node->getOpcode(), WidenVT); - SDValue Tmp1 = WidenVectorOp(Node->getOperand(0), WidenVT); SDValue Tmp2 = WidenVectorOp(Node->getOperand(1), WidenVT); assert(Tmp1.getValueType() == WidenVT && Tmp2.getValueType() == WidenVT); Result = DAG.getNode(Node->getOpcode(), WidenVT, Tmp1, Tmp2); - switch (action) { - default: assert(0 && "action not supported"); - case TargetLowering::Legal: - break; - case TargetLowering::Promote: - // We defer the promotion to when we legalize the op - break; - case TargetLowering::Expand: - // Expand the operation into a bunch of nasty scalar code by first - // Widening to the right type and then unroll the beast. - Result = LegalizeOp(UnrollVectorOp(Result)); - break; - } break; } case ISD::SHL: case ISD::SRA: case ISD::SRL: { - // Binary op with one non vector operand - TargetLowering::LegalizeAction action = - TLI.getOperationAction(Node->getOpcode(), WidenVT); - SDValue Tmp1 = WidenVectorOp(Node->getOperand(0), WidenVT); assert(Tmp1.getValueType() == WidenVT); - Result = DAG.getNode(Node->getOpcode(), WidenVT, Tmp1, Node->getOperand(1)); - switch (action) { - default: assert(0 && "action not supported"); - case TargetLowering::Legal: - break; - case TargetLowering::Promote: - // We defer the promotion to when we legalize the op - break; - case TargetLowering::Expand: - // Expand the operation into a bunch of nasty scalar code. - Result = LegalizeOp(UnrollVectorOp(Result)); - break; - } + SDValue ShOp = Node->getOperand(1); + MVT ShVT = ShOp.getValueType(); + MVT NewShVT = MVT::getVectorVT(ShVT.getVectorElementType(), + WidenVT.getVectorNumElements()); + ShOp = WidenVectorOp(ShOp, NewShVT); + assert(ShOp.getValueType() == NewShVT); + Result = DAG.getNode(Node->getOpcode(), WidenVT, Tmp1, ShOp); break; } + case ISD::EXTRACT_VECTOR_ELT: { SDValue Tmp1 = WidenVectorOp(Node->getOperand(0), WidenVT); assert(Tmp1.getValueType() == WidenVT); @@ -8101,10 +8030,7 @@ // We could widen on a multiple of the incoming operand if necessary. unsigned NumConcat = NewNumElts / NumElts; assert(NewNumElts % NumElts == 0 && "Can widen only a multiple of vector"); - std::vector UnOps(NumElts, DAG.getNode(ISD::UNDEF, - VT.getVectorElementType())); - SDValue UndefVal = DAG.getNode(ISD::BUILD_VECTOR, VT, - &UnOps[0], UnOps.size()); + SDValue UndefVal = DAG.getNode(ISD::UNDEF, VT); SmallVector MOps; MOps.push_back(Op); for (unsigned i = 1; i != NumConcat; ++i) { @@ -8151,9 +8077,6 @@ } case ISD::SELECT: { - TargetLowering::LegalizeAction action = - TLI.getOperationAction(Node->getOpcode(), WidenVT); - // Determine new condition widen type and widen SDValue Cond1 = Node->getOperand(0); MVT CondVT = Cond1.getValueType(); @@ -8167,26 +8090,10 @@ SDValue Tmp2 = WidenVectorOp(Node->getOperand(2), WidenVT); assert(Tmp1.getValueType() == WidenVT && Tmp2.getValueType() == WidenVT); Result = DAG.getNode(Node->getOpcode(), WidenVT, Cond1, Tmp1, Tmp2); - switch (action) { - default: assert(0 && "action not supported"); - case TargetLowering::Legal: - break; - case TargetLowering::Promote: - // We defer the promotion to when we legalize the op - break; - case TargetLowering::Expand: - // Expand the operation into a bunch of nasty scalar code by first - // Widening to the right type and then unroll the beast. - Result = LegalizeOp(UnrollVectorOp(Result)); - break; - } break; } case ISD::SELECT_CC: { - TargetLowering::LegalizeAction action = - TLI.getOperationAction(Node->getOpcode(), WidenVT); - // Determine new condition widen type and widen SDValue Cond1 = Node->getOperand(0); SDValue Cond2 = Node->getOperand(1); @@ -8206,19 +8113,6 @@ "operands not widen"); Result = DAG.getNode(Node->getOpcode(), WidenVT, Cond1, Cond2, Tmp1, Tmp2, Node->getOperand(4)); - switch (action) { - default: assert(0 && "action not supported"); - case TargetLowering::Legal: - break; - case TargetLowering::Promote: - // We defer the promotion to when we legalize the op - break; - case TargetLowering::Expand: - // Expand the operation into a bunch of nasty scalar code by first - // Widening to the right type and then unroll the beast. - Result = LegalizeOp(UnrollVectorOp(Result)); - break; - } break; } case ISD::VSETCC: { From nicholas at mxc.ca Tue Dec 2 02:05:49 2008 From: nicholas at mxc.ca (Nick Lewycky) Date: Tue, 02 Dec 2008 08:05:49 -0000 Subject: [llvm-commits] [llvm] r60407 - in /llvm/trunk: include/llvm/Analysis/ScalarEvolution.h include/llvm/Analysis/ScalarEvolutionExpander.h include/llvm/Analysis/ScalarEvolutionExpressions.h lib/Analysis/ScalarEvolution.cpp lib/Analysis/ScalarEvolutionExpander.cpp Message-ID: <200812020805.mB285n4P006299@zion.cs.uiuc.edu> Author: nicholas Date: Tue Dec 2 02:05:48 2008 New Revision: 60407 URL: http://llvm.org/viewvc/llvm-project?rev=60407&view=rev Log: Add a new SCEV representing signed division. Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h llvm/trunk/lib/Analysis/ScalarEvolution.cpp llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=60407&r1=60406&r2=60407&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original) +++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Tue Dec 2 02:05:48 2008 @@ -225,6 +225,7 @@ return getMulExpr(Ops); } SCEVHandle getUDivExpr(const SCEVHandle &LHS, const SCEVHandle &RHS); + SCEVHandle getSDivExpr(const SCEVHandle &LHS, const SCEVHandle &RHS); SCEVHandle getAddRecExpr(const SCEVHandle &Start, const SCEVHandle &Step, const Loop *L); SCEVHandle getAddRecExpr(std::vector &Operands, Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h?rev=60407&r1=60406&r2=60407&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h (original) +++ llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h Tue Dec 2 02:05:48 2008 @@ -104,6 +104,8 @@ Value *visitUDivExpr(SCEVUDivExpr *S); + Value *visitSDivExpr(SCEVSDivExpr *S); + Value *visitAddRecExpr(SCEVAddRecExpr *S); Value *visitSMaxExpr(SCEVSMaxExpr *S); Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h?rev=60407&r1=60406&r2=60407&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h (original) +++ llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h Tue Dec 2 02:05:48 2008 @@ -25,7 +25,7 @@ // These should be ordered in terms of increasing complexity to make the // folders simpler. scConstant, scTruncate, scZeroExtend, scSignExtend, scAddExpr, scMulExpr, - scUDivExpr, scAddRecExpr, scUMaxExpr, scSMaxExpr, scUnknown, + scUDivExpr, scSDivExpr, scAddRecExpr, scUMaxExpr, scSMaxExpr, scUnknown, scCouldNotCompute }; @@ -358,6 +358,55 @@ //===--------------------------------------------------------------------===// + /// SCEVSDivExpr - This class represents a binary signed division operation. + /// + class SCEVSDivExpr : public SCEV { + friend class ScalarEvolution; + + SCEVHandle LHS, RHS; + SCEVSDivExpr(const SCEVHandle &lhs, const SCEVHandle &rhs) + : SCEV(scSDivExpr), LHS(lhs), RHS(rhs) {} + + virtual ~SCEVSDivExpr(); + public: + const SCEVHandle &getLHS() const { return LHS; } + const SCEVHandle &getRHS() const { return RHS; } + + virtual bool isLoopInvariant(const Loop *L) const { + return LHS->isLoopInvariant(L) && RHS->isLoopInvariant(L); + } + + virtual bool hasComputableLoopEvolution(const Loop *L) const { + return LHS->hasComputableLoopEvolution(L) && + RHS->hasComputableLoopEvolution(L); + } + + SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, + const SCEVHandle &Conc, + ScalarEvolution &SE) const { + SCEVHandle L = LHS->replaceSymbolicValuesWithConcrete(Sym, Conc, SE); + SCEVHandle R = RHS->replaceSymbolicValuesWithConcrete(Sym, Conc, SE); + if (L == LHS && R == RHS) + return this; + else + return SE.getSDivExpr(L, R); + } + + + virtual const Type *getType() const; + + void print(std::ostream &OS) const; + void print(std::ostream *OS) const { if (OS) print(*OS); } + + /// Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const SCEVSDivExpr *S) { return true; } + static inline bool classof(const SCEV *S) { + return S->getSCEVType() == scSDivExpr; + } + }; + + + //===--------------------------------------------------------------------===// /// SCEVAddRecExpr - This node represents a polynomial recurrence on the trip /// count of the specified loop. /// @@ -550,6 +599,8 @@ return ((SC*)this)->visitMulExpr((SCEVMulExpr*)S); case scUDivExpr: return ((SC*)this)->visitUDivExpr((SCEVUDivExpr*)S); + case scSDivExpr: + return ((SC*)this)->visitSDivExpr((SCEVSDivExpr*)S); case scAddRecExpr: return ((SC*)this)->visitAddRecExpr((SCEVAddRecExpr*)S); case scSMaxExpr: Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=60407&r1=60406&r2=60407&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Tue Dec 2 02:05:48 2008 @@ -324,6 +324,26 @@ return LHS->getType(); } + +// SCEVSDivs - Only allow the creation of one SCEVSDivExpr for any particular +// input. Don't use a SCEVHandle here, or else the object will never be +// deleted! +static ManagedStatic, + SCEVSDivExpr*> > SCEVSDivs; + +SCEVSDivExpr::~SCEVSDivExpr() { + SCEVSDivs->erase(std::make_pair(LHS, RHS)); +} + +void SCEVSDivExpr::print(std::ostream &OS) const { + OS << "(" << *LHS << " /s " << *RHS << ")"; +} + +const Type *SCEVSDivExpr::getType() const { + return LHS->getType(); +} + + // SCEVAddRecExprs - Only allow the creation of one SCEVAddRecExpr for any // particular input. Don't use a SCEVHandle here, or else the object will never // be deleted! @@ -1109,9 +1129,12 @@ } SCEVHandle ScalarEvolution::getUDivExpr(const SCEVHandle &LHS, const SCEVHandle &RHS) { + if (LHS == RHS) + return getIntegerSCEV(1, LHS->getType()); // X udiv X --> 1 + if (SCEVConstant *RHSC = dyn_cast(RHS)) { if (RHSC->getValue()->equalsInt(1)) - return LHS; // X udiv 1 --> x + return LHS; // X udiv 1 --> X if (SCEVConstant *LHSC = dyn_cast(LHS)) { Constant *LHSCV = LHSC->getValue(); @@ -1120,13 +1143,34 @@ } } - // FIXME: implement folding of (X*4)/4 when we know X*4 doesn't overflow. - SCEVUDivExpr *&Result = (*SCEVUDivs)[std::make_pair(LHS, RHS)]; if (Result == 0) Result = new SCEVUDivExpr(LHS, RHS); return Result; } +SCEVHandle ScalarEvolution::getSDivExpr(const SCEVHandle &LHS, const SCEVHandle &RHS) { + if (LHS == RHS) + return getIntegerSCEV(1, LHS->getType()); // X sdiv X --> 1 + + if (SCEVConstant *RHSC = dyn_cast(RHS)) { + if (RHSC->getValue()->equalsInt(1)) + return LHS; // X sdiv 1 --> X + + if (RHSC->getValue()->isAllOnesValue()) + return getNegativeSCEV(LHS); // X sdiv -1 --> -X + + if (SCEVConstant *LHSC = dyn_cast(LHS)) { + Constant *LHSCV = LHSC->getValue(); + Constant *RHSCV = RHSC->getValue(); + return getUnknown(ConstantExpr::getSDiv(LHSCV, RHSCV)); + } + } + + SCEVSDivExpr *&Result = (*SCEVSDivs)[std::make_pair(LHS, RHS)]; + if (Result == 0) Result = new SCEVSDivExpr(LHS, RHS); + return Result; +} + /// SCEVAddRecExpr::get - Get a add recurrence expression for the /// specified loop. Simplify the expression as much as possible. @@ -1732,7 +1776,7 @@ return MinOpRes; } - // SCEVUDivExpr, SCEVUnknown + // SCEVUDivExpr, SCEVSDivExpr, SCEVUnknown return 0; } @@ -1762,6 +1806,9 @@ case Instruction::UDiv: return SE.getUDivExpr(getSCEV(U->getOperand(0)), getSCEV(U->getOperand(1))); + case Instruction::SDiv: + return SE.getSDivExpr(getSCEV(U->getOperand(0)), + getSCEV(U->getOperand(1))); case Instruction::Sub: return SE.getMinusSCEV(getSCEV(U->getOperand(0)), getSCEV(U->getOperand(1))); @@ -1805,7 +1852,7 @@ break; case Instruction::LShr: - // Turn logical shift right of a constant into a unsigned divide. + // Turn logical shift right of a constant into an unsigned divide. if (ConstantInt *SA = dyn_cast(U->getOperand(1))) { uint32_t BitWidth = cast(V->getType())->getBitWidth(); Constant *X = ConstantInt::get( @@ -2505,16 +2552,26 @@ return Comm; } - if (SCEVUDivExpr *Div = dyn_cast(V)) { - SCEVHandle LHS = getSCEVAtScope(Div->getLHS(), L); + if (SCEVUDivExpr *UDiv = dyn_cast(V)) { + SCEVHandle LHS = getSCEVAtScope(UDiv->getLHS(), L); if (LHS == UnknownValue) return LHS; - SCEVHandle RHS = getSCEVAtScope(Div->getRHS(), L); + SCEVHandle RHS = getSCEVAtScope(UDiv->getRHS(), L); if (RHS == UnknownValue) return RHS; - if (LHS == Div->getLHS() && RHS == Div->getRHS()) - return Div; // must be loop invariant + if (LHS == UDiv->getLHS() && RHS == UDiv->getRHS()) + return UDiv; // must be loop invariant return SE.getUDivExpr(LHS, RHS); } + if (SCEVSDivExpr *SDiv = dyn_cast(V)) { + SCEVHandle LHS = getSCEVAtScope(SDiv->getLHS(), L); + if (LHS == UnknownValue) return LHS; + SCEVHandle RHS = getSCEVAtScope(SDiv->getRHS(), L); + if (RHS == UnknownValue) return RHS; + if (LHS == SDiv->getLHS() && RHS == SDiv->getRHS()) + return SDiv; // must be loop invariant + return SE.getSDivExpr(LHS, RHS); + } + // If this is a loop recurrence for a loop that does not contain L, then we // are dealing with the final value computed by the loop. if (SCEVAddRecExpr *AddRec = dyn_cast(V)) { Modified: llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp?rev=60407&r1=60406&r2=60407&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp Tue Dec 2 02:05:48 2008 @@ -143,6 +143,15 @@ return InsertBinop(Instruction::UDiv, LHS, RHS, InsertPt); } +Value *SCEVExpander::visitSDivExpr(SCEVSDivExpr *S) { + // Do not fold sdiv into ashr, unless you know that LHS is positive. On + // negative values, it rounds the wrong way. + + Value *LHS = expand(S->getLHS()); + Value *RHS = expand(S->getRHS()); + return InsertBinop(Instruction::SDiv, LHS, RHS, InsertPt); +} + Value *SCEVExpander::visitAddRecExpr(SCEVAddRecExpr *S) { const Type *Ty = S->getType(); const Loop *L = S->getLoop(); From sabre at nondot.org Tue Dec 2 02:16:11 2008 From: sabre at nondot.org (Chris Lattner) Date: Tue, 02 Dec 2008 08:16:11 -0000 Subject: [llvm-commits] [llvm] r60408 - in /llvm/trunk: lib/Transforms/Scalar/GVN.cpp test/Transforms/GVN/pre-load.ll Message-ID: <200812020816.mB28GBa9006575@zion.cs.uiuc.edu> Author: lattner Date: Tue Dec 2 02:16:11 2008 New Revision: 60408 URL: http://llvm.org/viewvc/llvm-project?rev=60408&view=rev Log: Implement PRE of loads in the GVN pass with a pretty cheap and straight-forward implementation. This does not require any extra alias analysis queries beyond what we already do for non-local loads. Some programs really really like load PRE. For example, SPASS triggers this ~1000 times, ~300 times in 255.vortex, and ~1500 times on 403.gcc. The biggest limitation to the implementation is that it does not split critical edges. This is a huge killer on many programs and should be addressed after the initial patch is enabled by default. The implementation of this should incidentally speed up rejection of non-local loads because it avoids creating the repl densemap in cases when it won't be used for fully redundant loads. This is currently disabled by default. Before I turn this on, I need to fix a couple of miscompilations in the testsuite, look at compile time performance numbers, and look at perf impact. This is pretty close to ready though. Added: llvm/trunk/test/Transforms/GVN/pre-load.ll Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=60408&r1=60407&r2=60408&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Tue Dec 2 02:16:11 2008 @@ -43,9 +43,11 @@ STATISTIC(NumGVNLoad, "Number of loads deleted"); STATISTIC(NumGVNPRE, "Number of instructions PRE'd"); STATISTIC(NumGVNBlocks, "Number of blocks merged"); +STATISTIC(NumPRELoad, "Number of loads PRE'd"); static cl::opt EnablePRE("enable-pre", cl::init(true), cl::Hidden); +cl::opt EnableLoadPRE("enable-load-pre"); //===----------------------------------------------------------------------===// // ValueTable Class @@ -863,23 +865,46 @@ return v; } +/// IsValueFullyAvailableInBlock - Return true if we can prove that the value +/// we're analyzing is fully available in the specified block. As we go, keep +/// track of which blocks we know it is fully alive or not in +/// FullyAvailableBlocks. +static bool IsValueFullyAvailableInBlock(BasicBlock *BB, + DenseMap &FullyAvailableBlocks) { + // Optimistically assume that the block is fully available and check to see + // if we already know about this block in one lookup. + std::pair::iterator, bool> IV = + FullyAvailableBlocks.insert(std::make_pair(BB, true)); + + // If the entry already existed for this block, return the precomputed value. + if (!IV.second) + return IV.first->second; + + // Otherwise, see if it is fully available in all predecessors. + pred_iterator PI = pred_begin(BB), PE = pred_end(BB); + + // If this block has no predecessors, it isn't live-in here. + if (PI == PE) + return FullyAvailableBlocks[BB] = false; + + for (; PI != PE; ++PI) + // If the value isn't fully available in one of our predecessors, then it + // isn't fully available in this block either. Undo our previous + // optimistic assumption and bail out. + if (!IsValueFullyAvailableInBlock(*PI, FullyAvailableBlocks)) + return FullyAvailableBlocks[BB] = false; + + return true; +} + /// processNonLocalLoad - Attempt to eliminate a load whose dependencies are /// non-local by performing PHI construction. -bool GVN::processNonLocalLoad(LoadInst* L, +bool GVN::processNonLocalLoad(LoadInst *LI, SmallVectorImpl &toErase) { - // Find the non-local dependencies of the load + // Find the non-local dependencies of the load. const MemoryDependenceAnalysis::NonLocalDepInfo &deps = - MD->getNonLocalDependency(L); - DEBUG(cerr << "INVESTIGATING NONLOCAL LOAD: " << deps.size() << *L); -#if 0 - DEBUG(for (unsigned i = 0, e = deps.size(); i != e; ++i) { - cerr << " " << deps[i].first->getName(); - if (Instruction *I = deps[i].second.getInst()) - cerr << *I; - else - cerr << "\n"; - }); -#endif + MD->getNonLocalDependency(LI); + //DEBUG(cerr << "INVESTIGATING NONLOCAL LOAD: " << deps.size() << *LI); // If we had to process more than one hundred blocks to find the // dependencies, this load isn't worth worrying about. Optimizing @@ -887,11 +912,15 @@ if (deps.size() > 100) return false; - BasicBlock *EntryBlock = &L->getParent()->getParent()->getEntryBlock(); + BasicBlock *EntryBlock = &LI->getParent()->getParent()->getEntryBlock(); - DenseMap repl; + // Filter out useless results (non-locals, etc). Keep track of the blocks + // where we have a value available in repl, also keep track of whether we see + // dependencies that produce an unknown value for the load (such as a call + // that could potentially clobber the load). + SmallVector, 16> ValuesPerBlock; + SmallVector UnavailableBlocks; - // Filter out useless results (non-locals, etc) for (unsigned i = 0, e = deps.size(); i != e; ++i) { BasicBlock *DepBB = deps[i].first; MemDepResult DepInfo = deps[i].second; @@ -900,17 +929,14 @@ // If this is a non-local dependency in the entry block, then we depend on // the value live-in at the start of the function. We could insert a load // in the entry block to get this, but for now we'll just bail out. - // - // FIXME: Consider emitting a load in the entry block to catch this case! - // Tricky part is to sink so that it doesn't execute in places where it - // isn't needed. if (DepBB == EntryBlock) - return false; + UnavailableBlocks.push_back(DepBB); continue; } if (DepInfo.isNone()) { - repl[DepBB] = UndefValue::get(L->getType()); + ValuesPerBlock.push_back(std::make_pair(DepBB, + UndefValue::get(LI->getType()))); continue; } @@ -920,52 +946,165 @@ // NOTE: 403.gcc does have this case (e.g. in readonly_fields_p) because // of bitfield access, it would be interesting to optimize for it at some // point. - if (S->getOperand(0)->getType() != L->getType()) - return false; + if (S->getOperand(0)->getType() != LI->getType()) { + UnavailableBlocks.push_back(DepBB); + continue; + } - if (S->getPointerOperand() != L->getPointerOperand() && + if (S->getPointerOperand() != LI->getPointerOperand() && VN.getAliasAnalysis()->alias(S->getPointerOperand(), 1, - L->getPointerOperand(), 1) - != AliasAnalysis::MustAlias) - return false; - repl[DepBB] = S->getOperand(0); + LI->getPointerOperand(), 1) + != AliasAnalysis::MustAlias) { + UnavailableBlocks.push_back(DepBB); + continue; + } + ValuesPerBlock.push_back(std::make_pair(DepBB, S->getOperand(0))); + } else if (LoadInst* LD = dyn_cast(DepInfo.getInst())) { - if (LD->getType() != L->getType()) - return false; + if (LD->getType() != LI->getType()) { + UnavailableBlocks.push_back(DepBB); + continue; + } - if (LD->getPointerOperand() != L->getPointerOperand() && + if (LD->getPointerOperand() != LI->getPointerOperand() && VN.getAliasAnalysis()->alias(LD->getPointerOperand(), 1, - L->getPointerOperand(), 1) - != AliasAnalysis::MustAlias) - return false; - repl[DepBB] = LD; + LI->getPointerOperand(), 1) + != AliasAnalysis::MustAlias) { + UnavailableBlocks.push_back(DepBB); + continue; + } + ValuesPerBlock.push_back(std::make_pair(DepBB, LD)); } else { - return false; + UnavailableBlocks.push_back(DepBB); + continue; } } - // Use cached PHI construction information from previous runs - SmallPtrSet& p = phiMap[L->getPointerOperand()]; - for (SmallPtrSet::iterator I = p.begin(), E = p.end(); - I != E; ++I) { - if ((*I)->getParent() == L->getParent()) { - L->replaceAllUsesWith(*I); - toErase.push_back(L); - NumGVNLoad++; - return true; + // If we have no predecessors that produce a known value for this load, exit + // early. + if (ValuesPerBlock.empty()) return false; + + // If all of the instructions we depend on produce a known value for this + // load, then it is fully redundant and we can use PHI insertion to compute + // its value. Insert PHIs and remove the fully redundant value now. + if (UnavailableBlocks.empty()) { + // Use cached PHI construction information from previous runs + SmallPtrSet &p = phiMap[LI->getPointerOperand()]; + for (SmallPtrSet::iterator I = p.begin(), E = p.end(); + I != E; ++I) { + if ((*I)->getParent() == LI->getParent()) { + DEBUG(cerr << "GVN REMOVING NONLOCAL LOAD #1: " << *LI); + LI->replaceAllUsesWith(*I); + toErase.push_back(LI); + NumGVNLoad++; + return true; + } + + ValuesPerBlock.push_back(std::make_pair((*I)->getParent(), *I)); } - repl.insert(std::make_pair((*I)->getParent(), *I)); + DEBUG(cerr << "GVN REMOVING NONLOCAL LOAD: " << *LI); + + DenseMap BlockReplValues; + BlockReplValues.insert(ValuesPerBlock.begin(), ValuesPerBlock.end()); + // Perform PHI construction. + Value* v = GetValueForBlock(LI->getParent(), LI, BlockReplValues, true); + LI->replaceAllUsesWith(v); + toErase.push_back(LI); + NumGVNLoad++; + return true; } + + if (!EnablePRE || !EnableLoadPRE) + return false; - DEBUG(cerr << "GVN REMOVING NONLOCAL LOAD: " << *L); + // Okay, we have *some* definitions of the value. This means that the value + // is available in some of our (transitive) predecessors. Lets think about + // doing PRE of this load. This will involve inserting a new load into the + // predecessor when it's not available. We could do this in general, but + // prefer to not increase code size. As such, we only do this when we know + // that we only have to insert *one* load (which means we're basically moving + // the load, not inserting a new one). + + // Everything we do here is based on local predecessors of LI's block. If it + // only has one predecessor, bail now. + BasicBlock *LoadBB = LI->getParent(); + if (LoadBB->getSinglePredecessor()) + return false; + + // If we have a repl set with LI itself in it, this means we have a loop where + // at least one of the values is LI. Since this means that we won't be able + // to eliminate LI even if we insert uses in the other predecessors, we will + // end up increasing code size. Reject this by scanning for LI. + for (unsigned i = 0, e = ValuesPerBlock.size(); i != e; ++i) + if (ValuesPerBlock[i].second == LI) + return false; + + // Okay, we have some hope :). Check to see if the loaded value is fully + // available in all but one predecessor. + // FIXME: If we could restructure the CFG, we could make a common pred with + // all the preds that don't have an available LI and insert a new load into + // that one block. + BasicBlock *UnavailablePred = 0; + + DenseMap FullyAvailableBlocks; + for (unsigned i = 0, e = ValuesPerBlock.size(); i != e; ++i) + FullyAvailableBlocks[ValuesPerBlock[i].first] = true; + for (unsigned i = 0, e = UnavailableBlocks.size(); i != e; ++i) + FullyAvailableBlocks[UnavailableBlocks[i]] = false; + + for (pred_iterator PI = pred_begin(LoadBB), E = pred_end(LoadBB); + PI != E; ++PI) { + if (IsValueFullyAvailableInBlock(*PI, FullyAvailableBlocks)) + continue; + + // If this load is not available in multiple predecessors, reject it. + if (UnavailablePred && UnavailablePred != *PI) + return false; + UnavailablePred = *PI; + } + + assert(UnavailablePred != 0 && + "Fully available value should be eliminated above!"); + + // If the loaded pointer is PHI node defined in this block, do PHI translation + // to get its value in the predecessor. + Value *LoadPtr = LI->getOperand(0)->DoPHITranslation(LoadBB, UnavailablePred); + + // Make sure the value is live in the predecessor. If it was defined by a + // non-PHI instruction in this block, we don't know how to recompute it above. + if (Instruction *LPInst = dyn_cast(LoadPtr)) + if (!DT->dominates(LPInst->getParent(), UnavailablePred)) { + DEBUG(cerr << "COULDN'T PRE LOAD BECAUSE PTR IS UNAVAILABLE IN PRED: " + << *LPInst << *LI << "\n"); + return false; + } + + // We don't currently handle critical edges :( + if (UnavailablePred->getTerminator()->getNumSuccessors() != 1) { + DEBUG(cerr << "COULD NOT PRE LOAD BECAUSE OF CRITICAL EDGE '" + << UnavailablePred->getName() << "': " << *LI); + return false; + } - // Perform PHI construction - SmallPtrSet visited; - Value* v = GetValueForBlock(L->getParent(), L, repl, true); - L->replaceAllUsesWith(v); - toErase.push_back(L); - NumGVNLoad++; + // Okay, we can eliminate this load by inserting a reload in the predecessor + // and using PHI construction to get the value in the other predecessors, do + // it. + DEBUG(cerr << "GVN REMOVING PRE LOAD: " << *LI); + + Value *NewLoad = new LoadInst(LoadPtr, LI->getName()+".pre", false, + LI->getAlignment(), + UnavailablePred->getTerminator()); + + DenseMap BlockReplValues; + BlockReplValues.insert(ValuesPerBlock.begin(), ValuesPerBlock.end()); + BlockReplValues[UnavailablePred] = NewLoad; + + // Perform PHI construction. + Value* v = GetValueForBlock(LI->getParent(), LI, BlockReplValues, true); + LI->replaceAllUsesWith(v); + toErase.push_back(LI); + NumPRELoad++; return true; } Added: llvm/trunk/test/Transforms/GVN/pre-load.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/pre-load.ll?rev=60408&view=auto ============================================================================== --- llvm/trunk/test/Transforms/GVN/pre-load.ll (added) +++ llvm/trunk/test/Transforms/GVN/pre-load.ll Tue Dec 2 02:16:11 2008 @@ -0,0 +1,18 @@ +; RUN: llvm-as < %s | opt -gvn -enable-load-pre | llvm-dis | grep {%PRE.rle = phi} + +define i32 @test(i32* %p, i1 %C) { +block1: + br i1 %C, label %block2, label %block3 + +block2: + br label %block4 + +block3: + %b = bitcast i32 0 to i32 + store i32 %b, i32* %p + br label %block4 + +block4: + %PRE = load i32* %p + ret i32 %PRE +} From baldrick at free.fr Tue Dec 2 02:11:58 2008 From: baldrick at free.fr (Duncan Sands) Date: Tue, 2 Dec 2008 09:11:58 +0100 Subject: [llvm-commits] [llvm] r60399 - in /llvm/trunk/lib: Target/README.txt Transforms/Scalar/InstructionCombining.cpp In-Reply-To: <200812020512.mB25CmMp000446@zion.cs.uiuc.edu> References: <200812020512.mB25CmMp000446@zion.cs.uiuc.edu> Message-ID: <200812020911.59145.baldrick@free.fr> Hi, > - Remove the buggy -X/C -> X/-C transform. This isn't valid when X isn't a > constant. If X is a constant, then this is folded elsewhere. why isn't this valid if X isn't a constant? It is only invalid if X == minint as far as I can see (of course, it may be hard to tell if X == minint if X is not a constant). Even if you restrict X to being a constant for simplicity, C doesn't need to be a constant (you don't need to check anything about C). Ciao, Duncan. From baldrick at free.fr Tue Dec 2 02:16:08 2008 From: baldrick at free.fr (Duncan Sands) Date: Tue, 2 Dec 2008 09:16:08 +0100 Subject: [llvm-commits] [llvm] r60405 - in /llvm/trunk: include/llvm/Value.h lib/VMCore/Value.cpp In-Reply-To: <200812020716.mB27Glu4004750@zion.cs.uiuc.edu> References: <200812020716.mB27Glu4004750@zion.cs.uiuc.edu> Message-ID: <200812020916.09016.baldrick@free.fr> Hi Chris, > + /// DoPHITranslation - If this value is a PHI node with CurBB as a its parent, "as a its" -> as its > +/// DoPHITranslation - If this value is a PHI node with CurBB as a its parent, Likewise. Ciao, Duncan. From clattner at apple.com Tue Dec 2 02:18:11 2008 From: clattner at apple.com (Chris Lattner) Date: Tue, 2 Dec 2008 00:18:11 -0800 Subject: [llvm-commits] [llvm] r60399 - in /llvm/trunk/lib: Target/README.txt Transforms/Scalar/InstructionCombining.cpp In-Reply-To: <200812020911.59145.baldrick@free.fr> References: <200812020512.mB25CmMp000446@zion.cs.uiuc.edu> <200812020911.59145.baldrick@free.fr> Message-ID: On Dec 2, 2008, at 12:11 AM, Duncan Sands wrote: > Hi, > >> - Remove the buggy -X/C -> X/-C transform. This isn't valid when X >> isn't a >> constant. If X is a constant, then this is folded elsewhere. > > why isn't this valid if X isn't a constant? It is valid, but if X is a constant, "-X/C" should and does already constant fold. -Chris From baldrick at free.fr Tue Dec 2 02:24:15 2008 From: baldrick at free.fr (Duncan Sands) Date: Tue, 2 Dec 2008 09:24:15 +0100 Subject: [llvm-commits] [llvm] r60366 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp In-Reply-To: <200812011946.mB1JkSs4013946@zion.cs.uiuc.edu> References: <200812011946.mB1JkSs4013946@zion.cs.uiuc.edu> Message-ID: <200812020924.15619.baldrick@free.fr> Hi Bill, > Use a simple comparison. Overflow on integer negation can only occur when the > integer is "minint". to check whether X is "minint", regardless of whether X is constant or not, you can call ComputeMaskedBits. If any bit (except for the sign bit) is known to be 1, then X is not equal to minint. If the sign bit is known to be 0, then also X is not equal to minint. Ciao, Duncan. From baldrick at free.fr Tue Dec 2 02:30:42 2008 From: baldrick at free.fr (Duncan Sands) Date: Tue, 2 Dec 2008 09:30:42 +0100 Subject: [llvm-commits] [llvm] r60399 - in /llvm/trunk/lib: Target/README.txt Transforms/Scalar/InstructionCombining.cpp In-Reply-To: References: <200812020512.mB25CmMp000446@zion.cs.uiuc.edu> <200812020911.59145.baldrick@free.fr> Message-ID: <200812020930.42286.baldrick@free.fr> > > why isn't this valid if X isn't a constant? > > It is valid, but if X is a constant, "-X/C" should and does already > constant fold. But only if C is a constant too, right? Ciao, Duncan. From espindola at google.com Tue Dec 2 04:52:43 2008 From: espindola at google.com (Rafael Espindola) Date: Tue, 2 Dec 2008 10:52:43 +0000 Subject: [llvm-commits] [patch] print ".file" directives In-Reply-To: <38a0d8450812011512s149ecd1di8d382536b4876037@mail.gmail.com> References: <38a0d8450811280731r5ab0fcdn787e06fdfebf0b6d@mail.gmail.com> <23C4696E-E675-4BD2-84A8-BEDF2BF52B5D@apple.com> <38a0d8450812011512s149ecd1di8d382536b4876037@mail.gmail.com> Message-ID: <38a0d8450812020252g35351e0h27623d298152af19@mail.gmail.com> > How did I miss that!? In my new patch I added a hasDotFileDirective. > Will try with HasDotLocAndDotFile and post again. Attached. Tested on Linux X86-64 and darwin ppc. Cheers, -- Rafael Avila de Espindola Google | Gordon House | Barrow Street | Dublin 4 | Ireland Registered in Dublin, Ireland | Registration Number: 368047 -------------- next part -------------- A non-text attachment was scrubbed... Name: file.patch Type: text/x-diff Size: 1259 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081202/3ab32af1/attachment.bin From isanbard at gmail.com Tue Dec 2 06:06:20 2008 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 2 Dec 2008 04:06:20 -0800 Subject: [llvm-commits] [llvm] r60399 - in /llvm/trunk/lib: Target/README.txt Transforms/Scalar/InstructionCombining.cpp In-Reply-To: <200812020911.59145.baldrick@free.fr> References: <200812020512.mB25CmMp000446@zion.cs.uiuc.edu> <200812020911.59145.baldrick@free.fr> Message-ID: On Dec 2, 2008, at 12:11 AM, Duncan Sands wrote: >> - Remove the buggy -X/C -> X/-C transform. This isn't valid when X >> isn't a >> constant. If X is a constant, then this is folded elsewhere. > > why isn't this valid if X isn't a constant? It is only invalid if > X == minint as far as I can see (of course, it may be hard to tell > if X == minint if X is not a constant). Yes. That's it exactly. :-) -bw From tilmann.scheller at googlemail.com Tue Dec 2 06:12:28 2008 From: tilmann.scheller at googlemail.com (Tilmann Scheller) Date: Tue, 02 Dec 2008 12:12:28 -0000 Subject: [llvm-commits] [llvm] r60409 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200812021212.mB2CCSv3023621@zion.cs.uiuc.edu> Author: tilmann Date: Tue Dec 2 06:12:25 2008 New Revision: 60409 URL: http://llvm.org/viewvc/llvm-project?rev=60409&view=rev Log: make it possible to custom lower TRUNCATE (needed for the CellSPU target) Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=60409&r1=60408&r2=60409&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Dec 2 06:12:25 2008 @@ -3904,6 +3904,11 @@ case Legal: Tmp1 = LegalizeOp(Node->getOperand(0)); Result = DAG.UpdateNodeOperands(Result, Tmp1); + if (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0)) == + TargetLowering::Custom) { + Tmp1 = TLI.LowerOperation(Result, DAG); + if (Tmp1.getNode()) Result = Tmp1; + } break; case Expand: ExpandOp(Node->getOperand(0), Tmp1, Tmp2); From tilmann.scheller at googlemail.com Tue Dec 2 06:13:34 2008 From: tilmann.scheller at googlemail.com (Tilmann Scheller) Date: Tue, 2 Dec 2008 13:13:34 +0100 Subject: [llvm-commits] [Patch] Custom Lowering for TRUNCATE In-Reply-To: <7C2FE10F-495E-4363-9767-58E62D735B48@apple.com> References: <4F419882-73CC-407C-800B-2C33CAB09DF7@apple.com> <7C2FE10F-495E-4363-9767-58E62D735B48@apple.com> Message-ID: On Tue, Dec 2, 2008 at 7:58 AM, Evan Cheng wrote: > This looks good. Can you commit? Done Greetings, Tilmann From dpatel at apple.com Tue Dec 2 12:23:34 2008 From: dpatel at apple.com (Devang Patel) Date: Tue, 2 Dec 2008 10:23:34 -0800 Subject: [llvm-commits] [llvm] r60148 - in /llvm/trunk: lib/Transforms/Scalar/JumpThreading.cpp test/Transforms/JumpThreading/thread-loads.ll In-Reply-To: <200811270507.mAR57tCW004036@zion.cs.uiuc.edu> References: <200811270507.mAR57tCW004036@zion.cs.uiuc.edu> Message-ID: <109F20D4-D554-4CB0-9267-8A4F36180707@apple.com> On Nov 26, 2008, at 9:07 PM, Chris Lattner wrote: > +/// MergeBasicBlockIntoOnlyPred - DestBB is a block with one > predecessor and its > +/// predecessor is known to have one successor (DestBB!). > Eliminate the edge > +/// between them, moving the instructions in the predecessor into > DestBB and > +/// deleting the predecessor block. > +/// > +/// FIXME: Move to TransformUtils to share with simplifycfg and > codegenprepare. BasicBlockUtils.h:MergeBlockIntoPredecessor() is already available. - Devang From gohman at apple.com Tue Dec 2 12:27:44 2008 From: gohman at apple.com (Dan Gohman) Date: Tue, 2 Dec 2008 10:27:44 -0800 Subject: [llvm-commits] [patch] print ".file" directives In-Reply-To: <38a0d8450812020252g35351e0h27623d298152af19@mail.gmail.com> References: <38a0d8450811280731r5ab0fcdn787e06fdfebf0b6d@mail.gmail.com> <23C4696E-E675-4BD2-84A8-BEDF2BF52B5D@apple.com> <38a0d8450812011512s149ecd1di8d382536b4876037@mail.gmail.com> <38a0d8450812020252g35351e0h27623d298152af19@mail.gmail.com> Message-ID: <5A767DF1-1537-4C0F-BE05-5034BDD064B2@apple.com> On Dec 2, 2008, at 2:52 AM, Rafael Espindola wrote: >> How did I miss that!? In my new patch I added a hasDotFileDirective. >> Will try with HasDotLocAndDotFile and post again. > > Attached. Tested on Linux X86-64 and darwin ppc. The single-parameter .file is a completely different thing from the two-parameter .file. Please use a separate flag rather than reusing HasDotLocAndDotFile. Also, in this line: + O << "\t.file \"" << M.getModuleIdentifier() << "\"\n"; please use a tab instead of a space after ".file" for consistency with other directives. Dan From sabre at nondot.org Tue Dec 2 12:33:13 2008 From: sabre at nondot.org (Chris Lattner) Date: Tue, 02 Dec 2008 18:33:13 -0000 Subject: [llvm-commits] [llvm] r60429 - in /llvm/trunk: include/llvm/Value.h lib/VMCore/Value.cpp Message-ID: <200812021833.mB2IXDSE003094@zion.cs.uiuc.edu> Author: lattner Date: Tue Dec 2 12:33:11 2008 New Revision: 60429 URL: http://llvm.org/viewvc/llvm-project?rev=60429&view=rev Log: Comment typeo fix, thanks Duncan! Modified: llvm/trunk/include/llvm/Value.h llvm/trunk/lib/VMCore/Value.cpp Modified: llvm/trunk/include/llvm/Value.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Value.h?rev=60429&r1=60428&r2=60429&view=diff ============================================================================== --- llvm/trunk/include/llvm/Value.h (original) +++ llvm/trunk/include/llvm/Value.h Tue Dec 2 12:33:11 2008 @@ -243,7 +243,7 @@ return const_cast(this)->getUnderlyingObject(); } - /// DoPHITranslation - If this value is a PHI node with CurBB as a its parent, + /// DoPHITranslation - If this value is a PHI node with CurBB as its parent, /// return the value in the PHI node corresponding to PredBB. If not, return /// ourself. This is useful if you want to know the value something has in a /// predecessor block. Modified: llvm/trunk/lib/VMCore/Value.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Value.cpp?rev=60429&r1=60428&r2=60429&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Value.cpp (original) +++ llvm/trunk/lib/VMCore/Value.cpp Tue Dec 2 12:33:11 2008 @@ -358,7 +358,7 @@ return this; } -/// DoPHITranslation - If this value is a PHI node with CurBB as a its parent, +/// DoPHITranslation - If this value is a PHI node with CurBB as its parent, /// return the value in the PHI node corresponding to PredBB. If not, return /// ourself. This is useful if you want to know the value something has in a /// predecessor block. From clattner at apple.com Tue Dec 2 12:34:17 2008 From: clattner at apple.com (Chris Lattner) Date: Tue, 2 Dec 2008 10:34:17 -0800 Subject: [llvm-commits] [llvm] r60399 - in /llvm/trunk/lib: Target/README.txt Transforms/Scalar/InstructionCombining.cpp In-Reply-To: <200812020930.42286.baldrick@free.fr> References: <200812020512.mB25CmMp000446@zion.cs.uiuc.edu> <200812020911.59145.baldrick@free.fr> <200812020930.42286.baldrick@free.fr> Message-ID: <16533DE6-B3D2-4397-9C02-ED71938CEBD4@apple.com> On Dec 2, 2008, at 12:30 AM, Duncan Sands wrote: >>> why isn't this valid if X isn't a constant? >> >> It is valid, but if X is a constant, "-X/C" should and does already >> constant fold. > > But only if C is a constant too, right? If C isn't a constant, you wouldn't want to do this xform - it isn't profitable. -Chris From clattner at apple.com Tue Dec 2 12:35:20 2008 From: clattner at apple.com (Chris Lattner) Date: Tue, 2 Dec 2008 10:35:20 -0800 Subject: [llvm-commits] [llvm] r60148 - in /llvm/trunk: lib/Transforms/Scalar/JumpThreading.cpp test/Transforms/JumpThreading/thread-loads.ll In-Reply-To: <109F20D4-D554-4CB0-9267-8A4F36180707@apple.com> References: <200811270507.mAR57tCW004036@zion.cs.uiuc.edu> <109F20D4-D554-4CB0-9267-8A4F36180707@apple.com> Message-ID: On Dec 2, 2008, at 10:23 AM, Devang Patel wrote: > > On Nov 26, 2008, at 9:07 PM, Chris Lattner wrote: > >> +/// MergeBasicBlockIntoOnlyPred - DestBB is a block with one >> predecessor and its >> +/// predecessor is known to have one successor (DestBB!). >> Eliminate the edge >> +/// between them, moving the instructions in the predecessor into >> DestBB and >> +/// deleting the predecessor block. >> +/// >> +/// FIXME: Move to TransformUtils to share with simplifycfg and >> codegenprepare. > > BasicBlockUtils.h:MergeBlockIntoPredecessor() is already available. Yep, I already moved this code there. -Chris From dalej at apple.com Tue Dec 2 12:40:40 2008 From: dalej at apple.com (Dale Johannesen) Date: Tue, 02 Dec 2008 18:40:40 -0000 Subject: [llvm-commits] [llvm] r60432 - /llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200812021840.mB2Ief8g003392@zion.cs.uiuc.edu> Author: johannes Date: Tue Dec 2 12:40:40 2008 New Revision: 60432 URL: http://llvm.org/viewvc/llvm-project?rev=60432&view=rev Log: One more transformation. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=60432&r1=60431&r2=60432&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Dec 2 12:40:40 2008 @@ -1025,6 +1025,14 @@ return DAG.getNode(ISD::SUB, VT, N1.getOperand(0), N1.getOperand(1).getOperand(0)); } + // fold (A+((B-A)+-C)) to (B+-C) + if ((N1.getOpcode() == ISD::SUB || N1.getOpcode() == ISD::ADD) && + N1.getOperand(0).getOpcode() == ISD::SUB && + N0 == N1.getOperand(0).getOperand(1)) { + return DAG.getNode(N1.getOpcode(), VT, N1.getOperand(0).getOperand(0), + N1.getOperand(1)); + } + // fold (A-B)+(C-D) to (A+C)-(B+D) when A or C is constant if (N0.getOpcode() == ISD::SUB && N1.getOpcode() == ISD::SUB) { SDValue N00 = N0.getOperand(0); From resistor at mac.com Tue Dec 2 12:53:47 2008 From: resistor at mac.com (Owen Anderson) Date: Tue, 02 Dec 2008 18:53:47 -0000 Subject: [llvm-commits] [llvm] r60433 - /llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp Message-ID: <200812021853.mB2IrmgT003824@zion.cs.uiuc.edu> Author: resistor Date: Tue Dec 2 12:53:47 2008 New Revision: 60433 URL: http://llvm.org/viewvc/llvm-project?rev=60433&view=rev Log: Add support for folding spills into preceding defs when doing pre-alloc splitting. Modified: llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp Modified: llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp?rev=60433&r1=60432&r2=60433&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp (original) +++ llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp Tue Dec 2 12:53:47 2008 @@ -40,6 +40,7 @@ STATISTIC(NumSplits, "Number of intervals split"); STATISTIC(NumRemats, "Number of intervals split by rematerialization"); +STATISTIC(NumFolds, "Number of intervals split with spill folding"); namespace { class VISIBILITY_HIDDEN PreAllocSplitting : public MachineFunctionPass { @@ -159,6 +160,12 @@ MachineBasicBlock::iterator RestorePt, unsigned RestoreIdx, SmallPtrSet& RefsInMBB); + MachineInstr* FoldSpill(unsigned vreg, const TargetRegisterClass* RC, + MachineInstr* DefMI, + MachineInstr* Barrier, + MachineBasicBlock* MBB, + int& SS, + SmallPtrSet& RefsInMBB); }; } // end anonymous namespace @@ -713,8 +720,62 @@ ++NumSplits; ++NumRemats; - return true; + return true; +} + +MachineInstr* PreAllocSplitting::FoldSpill(unsigned vreg, + const TargetRegisterClass* RC, + MachineInstr* DefMI, + MachineInstr* Barrier, + MachineBasicBlock* MBB, + int& SS, + SmallPtrSet& RefsInMBB) { + MachineBasicBlock::iterator Pt = MBB->begin(); + + // Go top down if RefsInMBB is empty. + if (RefsInMBB.empty()) + return 0; + + MachineBasicBlock::iterator FoldPt = Barrier; + while (&*FoldPt != DefMI && FoldPt != MBB->begin() && + !RefsInMBB.count(FoldPt)) + --FoldPt; + + int OpIdx = FoldPt->findRegisterDefOperandIdx(vreg, false); + if (OpIdx == -1) + return 0; + + SmallVector Ops; + Ops.push_back(OpIdx); + + if (!TII->canFoldMemoryOperand(FoldPt, Ops)) + return 0; + + DenseMap::iterator I = IntervalSSMap.find(vreg); + if (I != IntervalSSMap.end()) { + SS = I->second; + } else { + SS = MFI->CreateStackObject(RC->getSize(), RC->getAlignment()); + + } + + MachineInstr* FMI = TII->foldMemoryOperand(*MBB->getParent(), + FoldPt, Ops, SS); + + if (FMI) { + LIs->ReplaceMachineInstrInMaps(FoldPt, FMI); + FMI = MBB->insert(MBB->erase(FoldPt), FMI); + ++NumFolds; + + IntervalSSMap[vreg] = SS; + CurrSLI = &LSs->getOrCreateInterval(SS); + if (CurrSLI->hasAtLeastOneValue()) + CurrSValNo = CurrSLI->getValNumInfo(0); + else + CurrSValNo = CurrSLI->getNextValue(~0U, 0, LSs->getVNInfoAllocator()); + } + return FMI; } /// SplitRegLiveInterval - Split (spill and restore) the given live interval @@ -770,40 +831,53 @@ int SS = -1; if (ValNo->def == ~0U) { // If it's defined by a phi, we must split just before the barrier. - MachineBasicBlock::iterator SpillPt = - findSpillPoint(BarrierMBB, Barrier, NULL, RefsInMBB, SpillIndex); - if (SpillPt == BarrierMBB->begin()) - return false; // No gap to insert spill. - // Add spill. - SS = CreateSpillStackSlot(CurrLI->reg, RC); - TII->storeRegToStackSlot(*BarrierMBB, SpillPt, CurrLI->reg, true, SS, RC); - SpillMI = prior(SpillPt); - LIs->InsertMachineInstrInMaps(SpillMI, SpillIndex); + if ((SpillMI = FoldSpill(LI->reg, RC, 0, Barrier, + BarrierMBB, SS, RefsInMBB))) { + SpillIndex = LIs->getInstructionIndex(SpillMI); + } else { + MachineBasicBlock::iterator SpillPt = + findSpillPoint(BarrierMBB, Barrier, NULL, RefsInMBB, SpillIndex); + if (SpillPt == BarrierMBB->begin()) + return false; // No gap to insert spill. + // Add spill. + + SS = CreateSpillStackSlot(CurrLI->reg, RC); + TII->storeRegToStackSlot(*BarrierMBB, SpillPt, CurrLI->reg, true, SS, RC); + SpillMI = prior(SpillPt); + LIs->InsertMachineInstrInMaps(SpillMI, SpillIndex); + } } else if (!IsAvailableInStack(DefMBB, CurrLI->reg, ValNo->def, RestoreIndex, SpillIndex, SS)) { // If it's already split, just restore the value. There is no need to spill // the def again. if (!DefMI) return false; // Def is dead. Do nothing. - // Check if it's possible to insert a spill after the def MI. - MachineBasicBlock::iterator SpillPt; - if (DefMBB == BarrierMBB) { - // Add spill after the def and the last use before the barrier. - SpillPt = findSpillPoint(BarrierMBB, Barrier, DefMI, RefsInMBB, SpillIndex); - if (SpillPt == DefMBB->begin()) - return false; // No gap to insert spill. + + if ((SpillMI = FoldSpill(LI->reg, RC, DefMI, Barrier, + BarrierMBB, SS, RefsInMBB))) { + SpillIndex = LIs->getInstructionIndex(SpillMI); } else { - SpillPt = findNextEmptySlot(DefMBB, DefMI, SpillIndex); - if (SpillPt == DefMBB->end()) - return false; // No gap to insert spill. + // Check if it's possible to insert a spill after the def MI. + MachineBasicBlock::iterator SpillPt; + if (DefMBB == BarrierMBB) { + // Add spill after the def and the last use before the barrier. + SpillPt = findSpillPoint(BarrierMBB, Barrier, DefMI, + RefsInMBB, SpillIndex); + if (SpillPt == DefMBB->begin()) + return false; // No gap to insert spill. + } else { + SpillPt = findNextEmptySlot(DefMBB, DefMI, SpillIndex); + if (SpillPt == DefMBB->end()) + return false; // No gap to insert spill. + } + // Add spill. The store instruction kills the register if def is before + // the barrier in the barrier block. + SS = CreateSpillStackSlot(CurrLI->reg, RC); + TII->storeRegToStackSlot(*DefMBB, SpillPt, CurrLI->reg, + DefMBB == BarrierMBB, SS, RC); + SpillMI = prior(SpillPt); + LIs->InsertMachineInstrInMaps(SpillMI, SpillIndex); } - // Add spill. The store instruction kills the register if def is before - // the barrier in the barrier block. - SS = CreateSpillStackSlot(CurrLI->reg, RC); - TII->storeRegToStackSlot(*DefMBB, SpillPt, CurrLI->reg, - DefMBB == BarrierMBB, SS, RC); - SpillMI = prior(SpillPt); - LIs->InsertMachineInstrInMaps(SpillMI, SpillIndex); } // Remember def instruction index to spill index mapping. From dalej at apple.com Tue Dec 2 12:40:09 2008 From: dalej at apple.com (Dale Johannesen) Date: Tue, 02 Dec 2008 18:40:09 -0000 Subject: [llvm-commits] [llvm] r60431 - /llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200812021840.mB2IeADd003368@zion.cs.uiuc.edu> Author: johannes Date: Tue Dec 2 12:40:09 2008 New Revision: 60431 URL: http://llvm.org/viewvc/llvm-project?rev=60431&view=rev Log: Make the code do what the comment says it does. Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=60431&r1=60430&r2=60431&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Tue Dec 2 12:40:09 2008 @@ -598,10 +598,11 @@ // If InsertLoop is not L, and InsertLoop is nested inside of L, figure out // the preheader of the outer-most loop where NewBase is not loop invariant. - while (InsertLoop && NewBase->isLoopInvariant(InsertLoop)) { - BaseInsertPt = InsertLoop->getLoopPreheader()->getTerminator(); - InsertLoop = InsertLoop->getParentLoop(); - } + if (L->contains(IP->getParent())) + while (InsertLoop && NewBase->isLoopInvariant(InsertLoop)) { + BaseInsertPt = InsertLoop->getLoopPreheader()->getTerminator(); + InsertLoop = InsertLoop->getParentLoop(); + } // If there is no immediate value, skip the next part. if (Imm->isZero()) From gohman at apple.com Tue Dec 2 13:27:21 2008 From: gohman at apple.com (Dan Gohman) Date: Tue, 02 Dec 2008 19:27:21 -0000 Subject: [llvm-commits] [llvm] r60434 - /llvm/trunk/lib/CodeGen/RegisterScavenging.cpp Message-ID: <200812021927.mB2JRLX6004957@zion.cs.uiuc.edu> Author: djg Date: Tue Dec 2 13:27:20 2008 New Revision: 60434 URL: http://llvm.org/viewvc/llvm-project?rev=60434&view=rev Log: Fix a typo in a comment. Modified: llvm/trunk/lib/CodeGen/RegisterScavenging.cpp Modified: llvm/trunk/lib/CodeGen/RegisterScavenging.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegisterScavenging.cpp?rev=60434&r1=60433&r2=60434&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegisterScavenging.cpp (original) +++ llvm/trunk/lib/CodeGen/RegisterScavenging.cpp Tue Dec 2 13:27:20 2008 @@ -257,7 +257,7 @@ continue; } - // Skip is this is merely redefining part of a super-register. + // Skip if this is merely redefining part of a super-register. if (RedefinesSuperRegPart(MI, MO, TRI)) continue; From scottm at aero.org Tue Dec 2 13:53:54 2008 From: scottm at aero.org (Scott Michel) Date: Tue, 02 Dec 2008 19:53:54 -0000 Subject: [llvm-commits] [llvm] r60438 - in /llvm/trunk: lib/Target/CellSPU/SPUCallingConv.td lib/Target/CellSPU/SPUISelLowering.cpp lib/Target/CellSPU/SPUInstrInfo.td test/CodeGen/CellSPU/trunc.ll Message-ID: <200812021953.mB2JrsJJ006070@zion.cs.uiuc.edu> Author: pingbak Date: Tue Dec 2 13:53:53 2008 New Revision: 60438 URL: http://llvm.org/viewvc/llvm-project?rev=60438&view=rev Log: CellSPU: - Incorporate Tilmann Scheller's ISD::TRUNCATE custom lowering patch - Update SPU calling convention info, even if it's not used yet (but can be at some point or another) - Ensure that any-extended f32 loads are custom lowered, especially when they're promoted for use in printf. Added: llvm/trunk/test/CodeGen/CellSPU/trunc.ll Modified: llvm/trunk/lib/Target/CellSPU/SPUCallingConv.td llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td Modified: llvm/trunk/lib/Target/CellSPU/SPUCallingConv.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUCallingConv.td?rev=60438&r1=60437&r2=60438&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUCallingConv.td (original) +++ llvm/trunk/lib/Target/CellSPU/SPUCallingConv.td Tue Dec 2 13:53:53 2008 @@ -21,6 +21,8 @@ // Return-value convention for Cell SPU: Everything can be passed back via $3: def RetCC_SPU : CallingConv<[ + CCIfType<[i8], CCAssignToReg<[R3]>>, + CCIfType<[i16], CCAssignToReg<[R3]>>, CCIfType<[i32], CCAssignToReg<[R3]>>, CCIfType<[i64], CCAssignToReg<[R3]>>, CCIfType<[f32, f64], CCAssignToReg<[R3]>>, @@ -30,30 +32,82 @@ //===----------------------------------------------------------------------===// // CellSPU Argument Calling Conventions -// FIXME +// (note: this isn't used, but presumably should be at some point when other +// targets do.) //===----------------------------------------------------------------------===// /* def CC_SPU : CallingConv<[ - // The first 8 integer arguments are passed in integer registers. - CCIfType<[i32], CCAssignToReg<[R3, R4, R5, R6, R7, R8, R9, R10]>>, - CCIfType<[i64], CCAssignToReg<[X3, X4, X5, X6, X7, X8, X9, X10]>>, + CCIfType<[i8], CCAssignToReg<[R3, R4, R5, R6, R7, R8, R9, R10, R11, + R12, R13, R14, R15, R16, R17, R18, R19, R20, + R21, R22, R23, R24, R25, R26, R27, R28, R29, + R30, R31, R32, R33, R34, R35, R36, R37, R38, + R39, R40, R41, R42, R43, R44, R45, R46, R47, + R48, R49, R50, R51, R52, R53, R54, R55, R56, + R57, R58, R59, R60, R61, R62, R63, R64, R65, + R66, R67, R68, R69, R70, R71, R72, R73, R74, + R75, R76, R77, R78, R79]>>, + CCIfType<[i16], CCAssignToReg<[R3, R4, R5, R6, R7, R8, R9, R10, R11, + R12, R13, R14, R15, R16, R17, R18, R19, R20, + R21, R22, R23, R24, R25, R26, R27, R28, R29, + R30, R31, R32, R33, R34, R35, R36, R37, R38, + R39, R40, R41, R42, R43, R44, R45, R46, R47, + R48, R49, R50, R51, R52, R53, R54, R55, R56, + R57, R58, R59, R60, R61, R62, R63, R64, R65, + R66, R67, R68, R69, R70, R71, R72, R73, R74, + R75, R76, R77, R78, R79]>>, + CCIfType<[i32], CCAssignToReg<[R3, R4, R5, R6, R7, R8, R9, R10, R11, + R12, R13, R14, R15, R16, R17, R18, R19, R20, + R21, R22, R23, R24, R25, R26, R27, R28, R29, + R30, R31, R32, R33, R34, R35, R36, R37, R38, + R39, R40, R41, R42, R43, R44, R45, R46, R47, + R48, R49, R50, R51, R52, R53, R54, R55, R56, + R57, R58, R59, R60, R61, R62, R63, R64, R65, + R66, R67, R68, R69, R70, R71, R72, R73, R74, + R75, R76, R77, R78, R79]>>, + CCIfType<[f32], CCAssignToReg<[R3, R4, R5, R6, R7, R8, R9, R10, R11, + R12, R13, R14, R15, R16, R17, R18, R19, R20, + R21, R22, R23, R24, R25, R26, R27, R28, R29, + R30, R31, R32, R33, R34, R35, R36, R37, R38, + R39, R40, R41, R42, R43, R44, R45, R46, R47, + R48, R49, R50, R51, R52, R53, R54, R55, R56, + R57, R58, R59, R60, R61, R62, R63, R64, R65, + R66, R67, R68, R69, R70, R71, R72, R73, R74, + R75, R76, R77, R78, R79]>>, + CCIfType<[i64], CCAssignToReg<[R3, R4, R5, R6, R7, R8, R9, R10, R11, + R12, R13, R14, R15, R16, R17, R18, R19, R20, + R21, R22, R23, R24, R25, R26, R27, R28, R29, + R30, R31, R32, R33, R34, R35, R36, R37, R38, + R39, R40, R41, R42, R43, R44, R45, R46, R47, + R48, R49, R50, R51, R52, R53, R54, R55, R56, + R57, R58, R59, R60, R61, R62, R63, R64, R65, + R66, R67, R68, R69, R70, R71, R72, R73, R74, + R75, R76, R77, R78, R79]>>, + CCIfType<[f64], CCAssignToReg<[R3, R4, R5, R6, R7, R8, R9, R10, R11, + R12, R13, R14, R15, R16, R17, R18, R19, R20, + R21, R22, R23, R24, R25, R26, R27, R28, R29, + R30, R31, R32, R33, R34, R35, R36, R37, R38, + R39, R40, R41, R42, R43, R44, R45, R46, R47, + R48, R49, R50, R51, R52, R53, R54, R55, R56, + R57, R58, R59, R60, R61, R62, R63, R64, R65, + R66, R67, R68, R69, R70, R71, R72, R73, R74, + R75, R76, R77, R78, R79]>>, + CCIfType<[v16i8, v8i16, v4i32, v4f32, v2i64, v2f64], + CCAssignToReg<[R3, R4, R5, R6, R7, R8, R9, R10, R11, + R12, R13, R14, R15, R16, R17, R18, R19, R20, + R21, R22, R23, R24, R25, R26, R27, R28, R29, + R30, R31, R32, R33, R34, R35, R36, R37, R38, + R39, R40, R41, R42, R43, R44, R45, R46, R47, + R48, R49, R50, R51, R52, R53, R54, R55, R56, + R57, R58, R59, R60, R61, R62, R63, R64, R65, + R66, R67, R68, R69, R70, R71, R72, R73, R74, + R75, R76, R77, R78, R79]>>, - // SPU can pass back arguments in all - CCIfType<[f32, f64], CCIfSubtarget<"isMachoABI()", - CCAssignToReg<[F1, F2, F3, F4, F5, F6, F7, F8,F9,F10,F11,F12,F13]>>>, - // Other sub-targets pass FP values in F1-10. - CCIfType<[f32, f64], CCAssignToReg<[F1, F2, F3, F4, F5, F6, F7, F8, F9,F10]>>, - - // The first 12 Vector arguments are passed in altivec registers. - CCIfType<[v16i8, v8i16, v4i32, v4f32], - CCAssignToReg<[V2, V3, V4, V5, V6, V7, V8, V9, V10,V11,V12,V13]>> -/* // Integer/FP values get stored in stack slots that are 8 bytes in size and // 8-byte aligned if there are no more registers to hold them. CCIfType<[i32, i64, f32, f64], CCAssignToStack<8, 8>>, // Vectors get 16-byte stack slots that are 16-byte aligned. CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], - CCAssignToStack<16, 16>>*/ + CCAssignToStack<16, 16>> ]>; - */ +*/ Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=60438&r1=60437&r2=60438&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Tue Dec 2 13:53:53 2008 @@ -151,6 +151,8 @@ setLoadExtAction(ISD::SEXTLOAD, MVT::i16, Custom); setLoadExtAction(ISD::ZEXTLOAD, MVT::i16, Custom); + setLoadExtAction(ISD::EXTLOAD, MVT::f32, Custom); + // SPU constant load actions are custom lowered: setOperationAction(ISD::Constant, MVT::i64, Custom); setOperationAction(ISD::ConstantFP, MVT::f32, Legal); @@ -277,6 +279,12 @@ setOperationAction(ISD::SIGN_EXTEND, MVT::i64, Custom); setOperationAction(ISD::ANY_EXTEND, MVT::i64, Custom); + // Custom lower truncates + setOperationAction(ISD::TRUNCATE, MVT::i8, Custom); + setOperationAction(ISD::TRUNCATE, MVT::i16, Custom); + setOperationAction(ISD::TRUNCATE, MVT::i32, Custom); + setOperationAction(ISD::TRUNCATE, MVT::i64, Custom); + // SPU has a legal FP -> signed INT instruction setOperationAction(ISD::FP_TO_SINT, MVT::i32, Legal); setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom); @@ -782,7 +790,7 @@ DAG.setRoot(currentRoot); } #endif - + return result; /*UNREACHED*/ } @@ -2759,6 +2767,102 @@ return DAG.getNode(SPUISD::SELB, VT, trueval, falseval, compare); } +//! Custom lower ISD::TRUNCATE +static SDValue LowerTRUNCATE(SDValue Op, SelectionDAG &DAG) +{ + MVT VT = Op.getValueType(); + MVT::SimpleValueType simpleVT = VT.getSimpleVT(); + MVT VecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits())); + + SDValue Op0 = Op.getOperand(0); + MVT Op0VT = Op0.getValueType(); + MVT Op0VecVT = MVT::getVectorVT(Op0VT, (128 / Op0VT.getSizeInBits())); + + SDValue PromoteScalar = DAG.getNode(SPUISD::PROMOTE_SCALAR, Op0VecVT, Op0); + + unsigned maskLow; + unsigned maskHigh; + + // Create shuffle mask + switch (Op0VT.getSimpleVT()) { + case MVT::i128: + switch (simpleVT) { + case MVT::i64: + // least significant doubleword of quadword + maskHigh = 0x08090a0b; + maskLow = 0x0c0d0e0f; + break; + case MVT::i32: + // least significant word of quadword + maskHigh = maskLow = 0x0c0d0e0f; + break; + case MVT::i16: + // least significant halfword of quadword + maskHigh = maskLow = 0x0e0f0e0f; + break; + case MVT::i8: + // least significant byte of quadword + maskHigh = maskLow = 0x0f0f0f0f; + break; + default: + cerr << "Truncation to illegal type!"; + abort(); + } + break; + case MVT::i64: + switch (simpleVT) { + case MVT::i32: + // least significant word of doubleword + maskHigh = maskLow = 0x04050607; + break; + case MVT::i16: + // least significant halfword of doubleword + maskHigh = maskLow = 0x06070607; + break; + case MVT::i8: + // least significant byte of doubleword + maskHigh = maskLow = 0x07070707; + break; + default: + cerr << "Truncation to illegal type!"; + abort(); + } + break; + case MVT::i32: + case MVT::i16: + switch (simpleVT) { + case MVT::i16: + // least significant halfword of word + maskHigh = maskLow = 0x02030203; + break; + case MVT::i8: + // least significant byte of word/halfword + maskHigh = maskLow = 0x03030303; + break; + default: + cerr << "Truncation to illegal type!"; + abort(); + } + break; + default: + cerr << "Trying to lower truncation from illegal type!"; + abort(); + } + + // Use a shuffle to perform the truncation + SDValue shufMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, + DAG.getConstant(maskHigh, MVT::i32), + DAG.getConstant(maskLow, MVT::i32), + DAG.getConstant(maskHigh, MVT::i32), + DAG.getConstant(maskLow, MVT::i32)); + + SDValue truncShuffle = DAG.getNode(SPUISD::SHUFB, Op0VecVT, + PromoteScalar, PromoteScalar, shufMask); + + return DAG.getNode(SPUISD::VEC2PREFSLOT, VT, + DAG.getNode(ISD::BIT_CONVERT, VecVT, truncShuffle)); +} + //! Custom (target-specific) lowering entry point /*! This is where LLVM's DAG selection process calls to do target-specific @@ -2779,6 +2883,7 @@ abort(); } case ISD::LOAD: + case ISD::EXTLOAD: case ISD::SEXTLOAD: case ISD::ZEXTLOAD: return LowerLOAD(Op, DAG, SPUTM.getSubtargetImpl()); @@ -2865,6 +2970,9 @@ case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); + + case ISD::TRUNCATE: + return LowerTRUNCATE(Op, DAG); } return SDValue(); Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td?rev=60438&r1=60437&r2=60438&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td (original) +++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td Tue Dec 2 13:53:53 2008 @@ -1371,13 +1371,6 @@ defm ORBI : BitwiseOrByteImm; -// Truncate i16 -> i8 -def ORBItrunc : ORBIInst<(outs R8C:$rT), (ins R16C:$rA, u10imm:$val), - [/* empty */]>; - -def : Pat<(trunc R16C:$rSrc), - (ORBItrunc R16C:$rSrc, 0)>; - // OR halfword immediate class ORHIInst pattern>: RI10Form<0b10100000, OOL, IOL, "orhi\t$rT, $rA, $val", @@ -1403,13 +1396,6 @@ defm ORHI : BitwiseOrHalfwordImm; -// Truncate i32 -> i16 -def ORHItrunc : ORHIInst<(outs R16C:$rT), (ins R32C:$rA, u10imm:$val), - [/* empty */]>; - -def : Pat<(trunc R32C:$rSrc), - (ORHItrunc R32C:$rSrc, 0)>; - class ORIInst pattern>: RI10Form<0b00100000, OOL, IOL, "ori\t$rT, $rA, $val", IntegerOp, pattern>; @@ -1444,13 +1430,6 @@ defm ORI : BitwiseOrImm; -// Truncate i64 -> i32 -def ORItrunc : ORIInst<(outs R32C:$rT), (ins R64C:$rA, u10imm_i32:$val), - [/* empty */]>; - -def : Pat<(trunc R64C:$rSrc), - (ORItrunc R64C:$rSrc, 0)>; - // ORX: "or" across the vector: or's $rA's word slots leaving the result in // $rT[0], slots 1-3 are zeroed. // @@ -2014,13 +1993,6 @@ defm SHLQBYI : ShiftLeftQuadBytesImm; -// Special form for truncating i64 to i32: -def SHLQBYItrunc64: SHLQBYIInst<(outs R32C:$rT), (ins R64C:$rA, u7imm_i32:$val), - [/* no pattern, see below */]>; - -def : Pat<(trunc R64C:$rSrc), - (SHLQBYItrunc64 R64C:$rSrc, 4)>; - //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ // Rotate halfword: //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ Added: llvm/trunk/test/CodeGen/CellSPU/trunc.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/trunc.ll?rev=60438&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/trunc.ll (added) +++ llvm/trunk/test/CodeGen/CellSPU/trunc.ll Tue Dec 2 13:53:53 2008 @@ -0,0 +1,81 @@ +; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s +; RUN: grep shufb %t1.s | count 9 +; RUN: grep {ilhu.*1799} %t1.s | count 1 +; RUN: grep {ilhu.*771} %t1.s | count 3 +; RUN: grep {ilhu.*1543} %t1.s | count 1 +; RUN: grep {ilhu.*1029} %t1.s | count 1 +; RUN: grep {ilhu.*515} %t1.s | count 1 +; RUN: grep {iohl.*1799} %t1.s | count 1 +; RUN: grep {iohl.*771} %t1.s | count 3 +; RUN: grep {iohl.*1543} %t1.s | count 2 +; RUN: grep {iohl.*515} %t1.s | count 1 +; RUN: grep xsbh %t1.s | count 6 +; RUN: grep sfh %t1.s | count 5 + +; ModuleID = 'trunc.bc' +target datalayout = "E-p:32:32:128-i1:8:128-i8:8:128-i16:16:128-i32:32:128-i64:32:128-f32:32:128-f64:64:128-v64:64:64-v128:128:128-a0:0:128-s0:128:128" +target triple = "spu" + +; codegen for i128 arguments is not implemented yet on CellSPU +; once this changes uncomment the functions below +; and update the expected results accordingly + +;define i8 @trunc_i128_i8(i128 %u) nounwind readnone { +;entry: +; %0 = trunc i128 %u to i8 +; ret i8 %0 +;} +;define i16 @trunc_i128_i16(i128 %u) nounwind readnone { +;entry: +; %0 = trunc i128 %u to i16 +; ret i16 %0 +;} +;define i32 @trunc_i128_i32(i128 %u) nounwind readnone { +;entry: +; %0 = trunc i128 %u to i32 +; ret i32 %0 +;} +;define i64 @trunc_i128_i64(i128 %u) nounwind readnone { +;entry: +; %0 = trunc i128 %u to i64 +; ret i64 %0 +;} + +define i8 @trunc_i64_i8(i64 %u, i8 %v) nounwind readnone { +entry: + %0 = trunc i64 %u to i8 + %1 = sub i8 %0, %v + ret i8 %1 +} +define i16 @trunc_i64_i16(i64 %u, i16 %v) nounwind readnone { +entry: + %0 = trunc i64 %u to i16 + %1 = sub i16 %0, %v + ret i16 %1 +} +define i32 @trunc_i64_i32(i64 %u, i32 %v) nounwind readnone { +entry: + %0 = trunc i64 %u to i32 + %1 = sub i32 %0, %v + ret i32 %1 +} + +define i8 @trunc_i32_i8(i32 %u, i8 %v) nounwind readnone { +entry: + %0 = trunc i32 %u to i8 + %1 = sub i8 %0, %v + ret i8 %1 +} +define i16 @trunc_i32_i16(i32 %u, i16 %v) nounwind readnone { +entry: + %0 = trunc i32 %u to i16 + %1 = sub i16 %0, %v + ret i16 %1 +} + +define i8 @trunc_i16_i8(i16 %u, i8 %v) nounwind readnone { +entry: + %0 = trunc i16 %u to i8 + %1 = sub i8 %0, %v + ret i8 %1 +} From scottm at aero.org Tue Dec 2 13:55:08 2008 From: scottm at aero.org (Scott Michel) Date: Tue, 02 Dec 2008 19:55:08 -0000 Subject: [llvm-commits] [llvm] r60439 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200812021955.mB2Jt8AO006143@zion.cs.uiuc.edu> Author: pingbak Date: Tue Dec 2 13:55:08 2008 New Revision: 60439 URL: http://llvm.org/viewvc/llvm-project?rev=60439&view=rev Log: Non-functional change: make custom lowering for truncate stylistically consistent with the way it's generally done in other places. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=60439&r1=60438&r2=60439&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Dec 2 13:55:08 2008 @@ -3903,11 +3903,18 @@ switch (getTypeAction(Node->getOperand(0).getValueType())) { case Legal: Tmp1 = LegalizeOp(Node->getOperand(0)); - Result = DAG.UpdateNodeOperands(Result, Tmp1); - if (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0)) == - TargetLowering::Custom) { - Tmp1 = TLI.LowerOperation(Result, DAG); - if (Tmp1.getNode()) Result = Tmp1; + switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) { + default: assert(0 && "Unknown TRUNCATE legalization operation action!"); + case TargetLowering::Custom: + isCustom = true; + // FALLTHROUGH + case TargetLowering::Legal: + Result = DAG.UpdateNodeOperands(Result, Tmp1); + if (isCustom) { + Tmp1 = TLI.LowerOperation(Result, DAG); + if (Tmp1.getNode()) Result = Tmp1; + } + break; } break; case Expand: From dalej at apple.com Tue Dec 2 15:17:13 2008 From: dalej at apple.com (Dale Johannesen) Date: Tue, 02 Dec 2008 21:17:13 -0000 Subject: [llvm-commits] [llvm] r60442 - /llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200812022117.mB2LHDxf008691@zion.cs.uiuc.edu> Author: johannes Date: Tue Dec 2 15:17:11 2008 New Revision: 60442 URL: http://llvm.org/viewvc/llvm-project?rev=60442&view=rev Log: Minor rewrite per review feedback. Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=60442&r1=60441&r2=60442&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Tue Dec 2 15:17:11 2008 @@ -996,9 +996,14 @@ // Otherwise, remove all of the CSE's we found from each of the base values. for (unsigned i = 0; i != NumUses; ++i) { - // For this purpose, consider only uses that are inside the loop. - if (!L->contains(Uses[i].Inst->getParent())) + // Uses outside the loop don't necessarily include the common base, but + // the final IV value coming into those uses does. Instead of trying to + // remove the pieces of the common base, which might not be there, + // subtract off the base to compensate for this. + if (!L->contains(Uses[i].Inst->getParent())) { + Uses[i].Base = SE->getMinusSCEV(Uses[i].Base, Result); continue; + } // Split the expression into subexprs. SeparateSubExprs(SubExprs, Uses[i].Base, SE); @@ -1476,12 +1481,6 @@ // Add BaseV to the PHI value if needed. RewriteExpr = SE->getAddExpr(RewriteExpr, SE->getUnknown(BaseV)); - // If this reference is not in the loop and we have a Common base, - // that has been added into the induction variable and must be - // subtracted off here. - if (HaveCommonExprs && !L->contains(User.Inst->getParent())) - RewriteExpr = SE->getMinusSCEV(RewriteExpr, CommonExprs); - User.RewriteInstructionToUseNewBase(RewriteExpr, NewBasePt, Rewriter, L, this, DeadInsts); From evan.cheng at apple.com Tue Dec 2 15:57:14 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 02 Dec 2008 21:57:14 -0000 Subject: [llvm-commits] [llvm] r60443 - in /llvm/trunk: lib/CodeGen/SelectionDAG/LegalizeTypes.cpp test/CodeGen/PowerPC/2008-12-02-LegalizeTypeAssert.ll Message-ID: <200812022157.mB2LvEl9010483@zion.cs.uiuc.edu> Author: evancheng Date: Tue Dec 2 15:57:09 2008 New Revision: 60443 URL: http://llvm.org/viewvc/llvm-project?rev=60443&view=rev Log: Remove a (what appears to be) overly strict assertion. Here is what happened: 1. ppcf128 select is expanded to f64 select's. 2. f64 select operand 0 is an i1 truncate, it's promoted to i32 zero_extend. 3. f64 select is updated. It's changed back to a "NewNode" and being re-analyzed. 4. f64 select operands are being processed. Operand 0 is a "NewNode". It's being expunged out of ReplacedValues map. 5. ExpungeNode tries to remap f64 select and notice it's a "NewNode" and assert. Duncan, please take a look. Thanks. Added: llvm/trunk/test/CodeGen/PowerPC/2008-12-02-LegalizeTypeAssert.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp?rev=60443&r1=60442&r2=60443&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp Tue Dec 2 15:57:09 2008 @@ -386,7 +386,6 @@ RemapValue(I->second); N = I->second; } - assert(N.getNode()->getNodeId() != NewNode && "Mapped to unanalyzed node!"); } /// ExpungeNode - If N has a bogus mapping in ReplacedValues, eliminate it. Added: llvm/trunk/test/CodeGen/PowerPC/2008-12-02-LegalizeTypeAssert.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/2008-12-02-LegalizeTypeAssert.ll?rev=60443&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/PowerPC/2008-12-02-LegalizeTypeAssert.ll (added) +++ llvm/trunk/test/CodeGen/PowerPC/2008-12-02-LegalizeTypeAssert.ll Tue Dec 2 15:57:09 2008 @@ -0,0 +1,18 @@ +; RUN: llvm-as < %s | llc -mtriple=powerpc64-apple-darwin9.5 + +define void @__multc3({ ppc_fp128, ppc_fp128 }* noalias sret %agg.result, ppc_fp128 %a, ppc_fp128 %b, ppc_fp128 %c, ppc_fp128 %d) nounwind { +entry: + %.pre139 = and i1 false, false ; [#uses=1] + br i1 false, label %bb6, label %bb21 + +bb6: ; preds = %entry + %0 = tail call ppc_fp128 @copysignl(ppc_fp128 0xM00000000000000000000000000000000, ppc_fp128 %a) nounwind readnone ; [#uses=0] + %iftmp.1.0 = select i1 %.pre139, ppc_fp128 0xM3FF00000000000000000000000000000, ppc_fp128 0xM00000000000000000000000000000000 ; [#uses=1] + %1 = tail call ppc_fp128 @copysignl(ppc_fp128 %iftmp.1.0, ppc_fp128 %b) nounwind readnone ; [#uses=0] + unreachable + +bb21: ; preds = %entry + unreachable +} + +declare ppc_fp128 @copysignl(ppc_fp128, ppc_fp128) nounwind readnone From clattner at apple.com Tue Dec 2 16:12:10 2008 From: clattner at apple.com (Chris Lattner) Date: Tue, 2 Dec 2008 14:12:10 -0800 Subject: [llvm-commits] [llvm] r60442 - /llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp In-Reply-To: <200812022117.mB2LHDxf008691@zion.cs.uiuc.edu> References: <200812022117.mB2LHDxf008691@zion.cs.uiuc.edu> Message-ID: On Dec 2, 2008, at 1:17 PM, Dale Johannesen wrote: > Author: johannes > Date: Tue Dec 2 15:17:11 2008 > New Revision: 60442 > > URL: http://llvm.org/viewvc/llvm-project?rev=60442&view=rev > Log: > Minor rewrite per review feedback. Thanks Dale! -Chris From sabre at nondot.org Tue Dec 2 17:33:30 2008 From: sabre at nondot.org (Chris Lattner) Date: Tue, 02 Dec 2008 23:33:30 -0000 Subject: [llvm-commits] [llvm] r60446 - /llvm/trunk/include/llvm/ADT/APInt.h Message-ID: <200812022333.mB2NXUJ2013402@zion.cs.uiuc.edu> Author: lattner Date: Tue Dec 2 17:33:29 2008 New Revision: 60446 URL: http://llvm.org/viewvc/llvm-project?rev=60446&view=rev Log: Fix isIntN to work with APInts > 64 bits. This method is only used by clang apparently. Modified: llvm/trunk/include/llvm/ADT/APInt.h Modified: llvm/trunk/include/llvm/ADT/APInt.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APInt.h?rev=60446&r1=60445&r2=60446&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/APInt.h (original) +++ llvm/trunk/include/llvm/ADT/APInt.h Tue Dec 2 17:33:29 2008 @@ -333,12 +333,14 @@ /// @brief Check if this APInt has an N-bits unsigned integer value. bool isIntN(uint32_t N) const { assert(N && "N == 0 ???"); - if (isSingleWord()) { + if (N >= getBitWidth()) + return true; + + if (isSingleWord()) return VAL == (VAL & (~0ULL >> (64 - N))); - } else { - APInt Tmp(N, getNumWords(), pVal); - return Tmp == (*this); - } + APInt Tmp(N, getNumWords(), pVal); + Tmp.zext(getBitWidth()); + return Tmp == (*this); } /// @brief Check if this APInt has an N-bits signed integer value. From dalej at apple.com Tue Dec 2 18:52:41 2008 From: dalej at apple.com (Dale Johannesen) Date: Wed, 03 Dec 2008 00:52:41 -0000 Subject: [llvm-commits] [llvm] r60449 - in /llvm/trunk/test/CodeGen/X86: 2008-12-02-dagcombine-1.ll 2008-12-02-dagcombine-2.ll 2008-12-02-dagcombine-3.ll Message-ID: <200812030052.mB30qfuo015721@zion.cs.uiuc.edu> Author: johannes Date: Tue Dec 2 18:52:41 2008 New Revision: 60449 URL: http://llvm.org/viewvc/llvm-project?rev=60449&view=rev Log: testcases for recent dag combiner changes Added: llvm/trunk/test/CodeGen/X86/2008-12-02-dagcombine-1.ll llvm/trunk/test/CodeGen/X86/2008-12-02-dagcombine-2.ll llvm/trunk/test/CodeGen/X86/2008-12-02-dagcombine-3.ll Added: llvm/trunk/test/CodeGen/X86/2008-12-02-dagcombine-1.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2008-12-02-dagcombine-1.ll?rev=60449&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2008-12-02-dagcombine-1.ll (added) +++ llvm/trunk/test/CodeGen/X86/2008-12-02-dagcombine-1.ll Tue Dec 2 18:52:41 2008 @@ -0,0 +1,19 @@ +; RUN: llvm-as < %s | llc -march=x86 | grep "(%esp)" | count 2 +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin9.5" +; a - a should be found and removed, leaving refs to only L and P +define i8* @test(i8* %a, i8* %L, i8* %P) nounwind { +entry: + %0 = ptrtoint i8* %a to i32 + %1 = sub i32 -2, %0 + %2 = ptrtoint i8* %P to i32 + %3 = sub i32 0, %2 + %4 = ptrtoint i8* %L to i32 + %5 = add i32 %4, %3 + %6 = add i32 %5, %1 ; [#uses=1] + %7 = getelementptr i8* %a, i32 %6 ; [#uses=1] + br label %return + +return: ; preds = %bb3 + ret i8* %7 +} Added: llvm/trunk/test/CodeGen/X86/2008-12-02-dagcombine-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2008-12-02-dagcombine-2.ll?rev=60449&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2008-12-02-dagcombine-2.ll (added) +++ llvm/trunk/test/CodeGen/X86/2008-12-02-dagcombine-2.ll Tue Dec 2 18:52:41 2008 @@ -0,0 +1,17 @@ +; RUN: llvm-as < %s | llc -march=x86 | grep "(%esp)" | count 2 +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin9.5" +; a - a should be found and removed, leaving refs to only L and P +define i8* @test(i8* %a, i8* %L, i8* %P) nounwind { +entry: + %0 = ptrtoint i8* %a to i32 + %1 = ptrtoint i8* %P to i32 + %2 = sub i32 %1, %0 + %3 = ptrtoint i8* %L to i32 + %4 = sub i32 %2, %3 ; [#uses=1] + %5 = getelementptr i8* %a, i32 %4 ; [#uses=1] + br label %return + +return: ; preds = %bb3 + ret i8* %5 +} Added: llvm/trunk/test/CodeGen/X86/2008-12-02-dagcombine-3.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2008-12-02-dagcombine-3.ll?rev=60449&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2008-12-02-dagcombine-3.ll (added) +++ llvm/trunk/test/CodeGen/X86/2008-12-02-dagcombine-3.ll Tue Dec 2 18:52:41 2008 @@ -0,0 +1,18 @@ +; RUN: llvm-as < %s | llc -march=x86 | grep add | count 2 +; RUN: llvm-as < %s | llc -march=x86 | grep sub | grep -v subsections | count 1 +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin9.5" +; this should be rearranged to have two +s and one - +define i32 @test(i8* %a, i8* %L, i8* %P) nounwind { +entry: + %0 = ptrtoint i8* %P to i32 + %1 = sub i32 -2, %0 + %2 = ptrtoint i8* %L to i32 + %3 = ptrtoint i8* %a to i32 + %4 = sub i32 %2, %3 ; [#uses=1] + %5 = add i32 %1, %4 ; [#uses=1] + br label %return + +return: ; preds = %bb3 + ret i32 %5 +} From gohman at apple.com Tue Dec 2 19:10:18 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 03 Dec 2008 01:10:18 -0000 Subject: [llvm-commits] [llvm] r60451 - /llvm/trunk/test/CodeGen/X86/tailcallbyval.ll Message-ID: <200812030110.mB31AIXp016447@zion.cs.uiuc.edu> Author: djg Date: Tue Dec 2 19:10:18 2008 New Revision: 60451 URL: http://llvm.org/viewvc/llvm-project?rev=60451&view=rev Log: Add nounwind attributes to this test. Modified: llvm/trunk/test/CodeGen/X86/tailcallbyval.ll Modified: llvm/trunk/test/CodeGen/X86/tailcallbyval.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tailcallbyval.ll?rev=60451&r1=60450&r2=60451&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/tailcallbyval.ll (original) +++ llvm/trunk/test/CodeGen/X86/tailcallbyval.ll Tue Dec 2 19:10:18 2008 @@ -5,14 +5,14 @@ i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } -define fastcc i32 @tailcallee(%struct.s* byval %a) { +define fastcc i32 @tailcallee(%struct.s* byval %a) nounwind { entry: %tmp2 = getelementptr %struct.s* %a, i32 0, i32 0 %tmp3 = load i32* %tmp2 ret i32 %tmp3 } -define fastcc i32 @tailcaller(%struct.s* byval %a) { +define fastcc i32 @tailcaller(%struct.s* byval %a) nounwind { entry: %tmp4 = tail call fastcc i32 @tailcallee(%struct.s* %a byval) ret i32 %tmp4 From gohman at apple.com Tue Dec 2 19:28:05 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 03 Dec 2008 01:28:05 -0000 Subject: [llvm-commits] [llvm] r60453 - in /llvm/trunk: lib/Target/X86/X86CallingConv.td test/CodeGen/X86/fastcc-byval.ll test/CodeGen/X86/tailcallbyval.ll Message-ID: <200812030128.mB31S5Rc017072@zion.cs.uiuc.edu> Author: djg Date: Tue Dec 2 19:28:04 2008 New Revision: 60453 URL: http://llvm.org/viewvc/llvm-project?rev=60453&view=rev Log: Fix byval arguments in the fastcc calling convention. The fastcc convention delegates to the regular x86-32 convention which handles byval, but only after it handles a few cases, and it's necessary to handle byval before handling those cases. This fixes PR3122 (and rdar://6400815), llvm-gcc miscompiling LLVM. Added: llvm/trunk/test/CodeGen/X86/fastcc-byval.ll Modified: llvm/trunk/lib/Target/X86/X86CallingConv.td llvm/trunk/test/CodeGen/X86/tailcallbyval.ll Modified: llvm/trunk/lib/Target/X86/X86CallingConv.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CallingConv.td?rev=60453&r1=60452&r2=60453&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86CallingConv.td (original) +++ llvm/trunk/lib/Target/X86/X86CallingConv.td Tue Dec 2 19:28:04 2008 @@ -321,6 +321,11 @@ ]>; def CC_X86_32_FastCC : CallingConv<[ + // Handles byval parameters. Note that we can't rely on the delegation + // to CC_X86_32_Common for this because that happens after code that + // handles i32 arguments. + CCIfByVal>, + // Promote i8/i16 arguments to i32. CCIfType<[i8, i16], CCPromoteToType>, Added: llvm/trunk/test/CodeGen/X86/fastcc-byval.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fastcc-byval.ll?rev=60453&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/fastcc-byval.ll (added) +++ llvm/trunk/test/CodeGen/X86/fastcc-byval.ll Tue Dec 2 19:28:04 2008 @@ -0,0 +1,20 @@ +; RUN: llvm-as < %s | llc | grep {movl\[\[:space:\]\]*8(%esp), %eax} | count 2 +; PR3122 +; rdar://6400815 + +; byval requires a copy, even with fastcc. + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin9.5" + %struct.MVT = type { i32 } + +define fastcc i32 @bar() nounwind { + %V = alloca %struct.MVT + %a = getelementptr %struct.MVT* %V, i32 0, i32 0 + store i32 1, i32* %a + call fastcc void @foo(%struct.MVT* byval %V) nounwind + %t = load i32* %a + ret i32 %t +} + +declare fastcc void @foo(%struct.MVT* byval) Modified: llvm/trunk/test/CodeGen/X86/tailcallbyval.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tailcallbyval.ll?rev=60453&r1=60452&r2=60453&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/tailcallbyval.ll (original) +++ llvm/trunk/test/CodeGen/X86/tailcallbyval.ll Tue Dec 2 19:28:04 2008 @@ -1,6 +1,5 @@ ; RUN: llvm-as < %s | llc -march=x86 -tailcallopt | grep TAILCALL -; check for the 2 byval moves -; RUN: llvm-as < %s | llc -march=x86 -tailcallopt | grep movl | grep ecx | grep eax | wc -l | grep 1 +; RUN: llvm-as < %s | llc -march=x86 -tailcallopt | grep {movl\[\[:space:\]\]*4(%esp), %eax} | count 1 %struct.s = type {i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } From dpatel at apple.com Tue Dec 2 19:32:32 2008 From: dpatel at apple.com (Devang Patel) Date: Wed, 03 Dec 2008 01:32:32 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60454 - /llvm-gcc-4.2/trunk/build_gcc Message-ID: <200812030132.mB31WWqF017213@zion.cs.uiuc.edu> Author: dpatel Date: Tue Dec 2 19:32:32 2008 New Revision: 60454 URL: http://llvm.org/viewvc/llvm-project?rev=60454&view=rev Log: Create links for special purpose. Modified: llvm-gcc-4.2/trunk/build_gcc Modified: llvm-gcc-4.2/trunk/build_gcc URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/build_gcc?rev=60454&r1=60453&r2=60454&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/build_gcc (original) +++ llvm-gcc-4.2/trunk/build_gcc Tue Dec 2 19:32:32 2008 @@ -618,6 +618,13 @@ rm libllvmgcc.dylib ln -s ../../libllvmgcc.dylib done + +if [ "x$LLVM_BUILT_ROOTS" == "x" ]; then + mkdir -p $DEST_DIR/usr/bin + cd $DEST_DIR/usr/bin + ln -s /Developer/usr/bin/llvm-gcc llvm-gcc + ln -s /Developer/usr/bin/llvm-g++ llvm-g++ +fi # LLVM LOCAL end find $DEST_DIR -name \*.dSYM -print | xargs rm -r || exit 1 From gohman at apple.com Tue Dec 2 19:39:44 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 03 Dec 2008 01:39:44 -0000 Subject: [llvm-commits] [llvm] r60455 - /llvm/trunk/lib/Target/X86/X86CallingConv.td Message-ID: <200812030139.mB31disN017382@zion.cs.uiuc.edu> Author: djg Date: Tue Dec 2 19:39:44 2008 New Revision: 60455 URL: http://llvm.org/viewvc/llvm-project?rev=60455&view=rev Log: Fix this comment to reflect that it applies to types other than just i32. Modified: llvm/trunk/lib/Target/X86/X86CallingConv.td Modified: llvm/trunk/lib/Target/X86/X86CallingConv.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CallingConv.td?rev=60455&r1=60454&r2=60455&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86CallingConv.td (original) +++ llvm/trunk/lib/Target/X86/X86CallingConv.td Tue Dec 2 19:39:44 2008 @@ -323,7 +323,7 @@ def CC_X86_32_FastCC : CallingConv<[ // Handles byval parameters. Note that we can't rely on the delegation // to CC_X86_32_Common for this because that happens after code that - // handles i32 arguments. + // puts arguments in registers. CCIfByVal>, // Promote i8/i16 arguments to i32. From gohman at apple.com Tue Dec 2 19:53:18 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 03 Dec 2008 01:53:18 -0000 Subject: [llvm-commits] [llvm] r60456 - /llvm/trunk/include/llvm/CodeGen/MachineConstantPool.h Message-ID: <200812030153.mB31rIGX018000@zion.cs.uiuc.edu> Author: djg Date: Tue Dec 2 19:53:18 2008 New Revision: 60456 URL: http://llvm.org/viewvc/llvm-project?rev=60456&view=rev Log: Replace a #include with a forward-declaration. Modified: llvm/trunk/include/llvm/CodeGen/MachineConstantPool.h Modified: llvm/trunk/include/llvm/CodeGen/MachineConstantPool.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineConstantPool.h?rev=60456&r1=60455&r2=60456&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineConstantPool.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineConstantPool.h Tue Dec 2 19:53:18 2008 @@ -15,7 +15,6 @@ #ifndef LLVM_CODEGEN_MACHINECONSTANTPOOL_H #define LLVM_CODEGEN_MACHINECONSTANTPOOL_H -#include "llvm/ADT/FoldingSet.h" #include #include @@ -23,6 +22,7 @@ class AsmPrinter; class Constant; +class FoldingSetNodeID; class TargetData; class TargetMachine; class Type; From gohman at apple.com Tue Dec 2 19:55:48 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 03 Dec 2008 01:55:48 -0000 Subject: [llvm-commits] [llvm] r60457 - /llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h Message-ID: <200812030155.mB31tmWw018150@zion.cs.uiuc.edu> Author: djg Date: Tue Dec 2 19:55:47 2008 New Revision: 60457 URL: http://llvm.org/viewvc/llvm-project?rev=60457&view=rev Log: Add an explicit keyword. Modified: llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h Modified: llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h?rev=60457&r1=60456&r2=60457&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h Tue Dec 2 19:55:47 2008 @@ -178,7 +178,7 @@ /// const TargetFrameInfo &TFI; public: - MachineFrameInfo(const TargetFrameInfo &tfi) : TFI(tfi) { + explicit MachineFrameInfo(const TargetFrameInfo &tfi) : TFI(tfi) { StackSize = NumFixedObjects = OffsetAdjustment = MaxAlignment = 0; HasVarSizedObjects = false; FrameAddressTaken = false; From gohman at apple.com Tue Dec 2 20:10:00 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 03 Dec 2008 02:10:00 -0000 Subject: [llvm-commits] [llvm] r60458 - /llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.h Message-ID: <200812030210.mB32A0Ta018651@zion.cs.uiuc.edu> Author: djg Date: Tue Dec 2 20:10:00 2008 New Revision: 60458 URL: http://llvm.org/viewvc/llvm-project?rev=60458&view=rev Log: Fix a missing #include. Modified: llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.h Modified: llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.h?rev=60458&r1=60457&r2=60458&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.h (original) +++ llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.h Tue Dec 2 20:10:00 2008 @@ -15,6 +15,7 @@ #define LLVM_TARGET_ARM_CONSTANTPOOLVALUE_H #include "llvm/CodeGen/MachineConstantPool.h" +#include namespace llvm { From gohman at apple.com Tue Dec 2 20:30:18 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 03 Dec 2008 02:30:18 -0000 Subject: [llvm-commits] [llvm] r60459 - in /llvm/trunk: lib/CodeGen/BranchFolding.cpp lib/Target/ARM/ARMRegisterInfo.cpp lib/Target/Alpha/AlphaInstrInfo.td lib/Target/PowerPC/PPCHazardRecognizers.cpp lib/Target/PowerPC/PPCInstr64Bit.td lib/Target/PowerPC/PPCInstrInfo.td utils/TableGen/CodeGenDAGPatterns.cpp utils/TableGen/DAGISelEmitter.cpp Message-ID: <200812030230.mB32UIdj019209@zion.cs.uiuc.edu> Author: djg Date: Tue Dec 2 20:30:17 2008 New Revision: 60459 URL: http://llvm.org/viewvc/llvm-project?rev=60459&view=rev Log: Add a sanity-check to tablegen to catch the case where isSimpleLoad is set but mayLoad is not set. Fix all the problems this turned up. Change code to not use isSimpleLoad instead of mayLoad unless it really wants isSimpleLoad. Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.td llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp llvm/trunk/utils/TableGen/DAGISelEmitter.cpp Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.cpp?rev=60459&r1=60458&r2=60459&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/BranchFolding.cpp (original) +++ llvm/trunk/lib/CodeGen/BranchFolding.cpp Tue Dec 2 20:30:17 2008 @@ -414,7 +414,7 @@ const TargetInstrDesc &TID = I->getDesc(); if (TID.isCall()) Time += 10; - else if (TID.isSimpleLoad() || TID.mayStore()) + else if (TID.mayLoad() || TID.mayStore()) Time += 2; else ++Time; Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp?rev=60459&r1=60458&r2=60459&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp Tue Dec 2 20:30:17 2008 @@ -834,7 +834,7 @@ assert(Offset && "This code isn't needed if offset already handled!"); if (isThumb) { - if (Desc.isSimpleLoad()) { + if (Desc.mayLoad()) { // Use the destination register to materialize sp + offset. unsigned TmpReg = MI.getOperand(0).getReg(); bool UseRR = false; Modified: llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.td?rev=60459&r1=60458&r2=60459&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.td (original) +++ llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.td Tue Dec 2 20:30:17 2008 @@ -570,7 +570,9 @@ //load address, rellocated gpdist form -let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s16imm:$DISP, GPRC:$RB, s16imm:$NUM) in { +let OutOperandList = (ops GPRC:$RA), + InOperandList = (ops s16imm:$DISP, GPRC:$RB, s16imm:$NUM), + mayLoad = 1 in { def LDAg : MForm<0x08, 1, "lda $RA,0($RB)\t\t!gpdisp!$NUM", [], s_lda>; //Load address def LDAHg : MForm<0x09, 1, "ldah $RA,0($RB)\t\t!gpdisp!$NUM", [], s_lda>; //Load address } @@ -589,7 +591,9 @@ def STQ_C : MForm<0x2F, 0, "stq_l $RA,$DISP($RB)", [], s_ist>; def STL_C : MForm<0x2E, 0, "stl_l $RA,$DISP($RB)", [], s_ist>; } -let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in { +let OutOperandList = (ops GPRC:$RA), + InOperandList = (ops s64imm:$DISP, GPRC:$RB), + mayLoad = 1 in { def LDQ_L : MForm<0x2B, 1, "ldq_l $RA,$DISP($RB)", [], s_ild>; def LDL_L : MForm<0x2A, 1, "ldl_l $RA,$DISP($RB)", [], s_ild>; } Modified: llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp?rev=60459&r1=60458&r2=60459&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCHazardRecognizers.cpp Tue Dec 2 20:30:17 2008 @@ -72,7 +72,7 @@ const TargetInstrDesc &TID = TII.get(Opcode); - isLoad = TID.isSimpleLoad(); + isLoad = TID.mayLoad(); isStore = TID.mayStore(); unsigned TSFlags = TID.TSFlags; Modified: llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td?rev=60459&r1=60458&r2=60459&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td (original) +++ llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td Tue Dec 2 20:30:17 2008 @@ -487,6 +487,7 @@ PPC970_DGroup_Cracked; // Update forms. +let mayLoad = 1 in def LHAU8 : DForm_1<43, (outs G8RC:$rD, ptr_rc:$ea_result), (ins symbolLo:$disp, ptr_rc:$rA), "lhau $rD, $disp($rA)", LdStGeneral, @@ -520,6 +521,7 @@ // Update forms. +let mayLoad = 1 in { def LBZU8 : DForm_1<35, (outs G8RC:$rD, ptr_rc:$ea_result), (ins memri:$addr), "lbzu $rD, $addr", LdStGeneral, []>, RegConstraint<"$addr.reg = $ea_result">, @@ -533,6 +535,7 @@ []>, RegConstraint<"$addr.reg = $ea_result">, NoEncode<"$ea_result">; } +} // Full 8-byte loads. @@ -544,6 +547,7 @@ "ldx $rD, $src", LdStLD, [(set G8RC:$rD, (load xaddr:$src))]>, isPPC64; +let mayLoad = 1 in def LDU : DSForm_1<58, 1, (outs G8RC:$rD, ptr_rc:$ea_result), (ins memrix:$addr), "ldu $rD, $addr", LdStLD, []>, RegConstraint<"$addr.reg = $ea_result">, isPPC64, Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td?rev=60459&r1=60458&r2=60459&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td (original) +++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td Tue Dec 2 20:30:17 2008 @@ -683,6 +683,7 @@ // Unindexed (r+i) Loads with Update (preinc). +let mayLoad = 1 in { def LBZU : DForm_1<35, (outs GPRC:$rD, ptr_rc:$ea_result), (ins memri:$addr), "lbzu $rD, $addr", LdStGeneral, []>, RegConstraint<"$addr.reg = $ea_result">, @@ -713,6 +714,7 @@ []>, RegConstraint<"$addr.reg = $ea_result">, NoEncode<"$ea_result">; } +} // Indexed (r+r) Loads. // Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp?rev=60459&r1=60458&r2=60459&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp (original) +++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp Tue Dec 2 20:30:17 2008 @@ -1759,6 +1759,15 @@ MayLoad = true; } + // Sanity-check the isSimpleLoad flag. + if (Inst.isSimpleLoad) { + if (!MayLoad) + fprintf(stderr, + "Warning: mayLoad flag not set or inferred for instruction '%s'" + " which has isSimpleLoad set.\n", + Inst.TheDef->getName().c_str()); + } + if (Inst.neverHasSideEffects) { if (HadPattern) fprintf(stderr, "Warning: neverHasSideEffects set on instruction '%s' " Modified: llvm/trunk/utils/TableGen/DAGISelEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelEmitter.cpp?rev=60459&r1=60458&r2=60459&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/DAGISelEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/DAGISelEmitter.cpp Tue Dec 2 20:30:17 2008 @@ -1097,7 +1097,7 @@ // Generate MemOperandSDNodes nodes for each memory accesses covered by // this pattern. - if (II.isSimpleLoad | II.mayLoad | II.mayStore) { + if (II.mayLoad | II.mayStore) { std::vector::const_iterator mi, mie; for (mi = LSI.begin(), mie = LSI.end(); mi != mie; ++mi) { std::string LSIName = "LSI_" + *mi; From isanbard at gmail.com Tue Dec 2 20:43:13 2008 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 03 Dec 2008 02:43:13 -0000 Subject: [llvm-commits] [llvm] r60460 - /llvm/trunk/test/CodeGen/X86/add-with-overflow.ll Message-ID: <200812030243.mB32hDwb019537@zion.cs.uiuc.edu> Author: void Date: Tue Dec 2 20:43:12 2008 New Revision: 60460 URL: http://llvm.org/viewvc/llvm-project?rev=60460&view=rev Log: Change label to 'carry' for unsigned adds. Modified: llvm/trunk/test/CodeGen/X86/add-with-overflow.ll Modified: llvm/trunk/test/CodeGen/X86/add-with-overflow.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/add-with-overflow.ll?rev=60460&r1=60459&r2=60460&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/add-with-overflow.ll (original) +++ llvm/trunk/test/CodeGen/X86/add-with-overflow.ll Tue Dec 2 20:43:12 2008 @@ -25,13 +25,13 @@ %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2) %sum = extractvalue {i32, i1} %t, 0 %obit = extractvalue {i32, i1} %t, 1 - br i1 %obit, label %overflow, label %normal + br i1 %obit, label %carry, label %normal normal: %t1 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @ok, i32 0, i32 0), i32 %sum ) nounwind ret i1 true -overflow: +carry: %t2 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @no, i32 0, i32 0) ) nounwind ret i1 false } From gohman at apple.com Tue Dec 2 23:21:26 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 03 Dec 2008 05:21:26 -0000 Subject: [llvm-commits] [llvm] r60461 - in /llvm/trunk: include/llvm/Target/Target.td include/llvm/Target/TargetInstrDesc.h lib/Target/X86/X86InstrInfo.cpp lib/Target/X86/X86InstrSSE.td test/CodeGen/X86/fold-pcmpeqd-0.ll test/CodeGen/X86/fold-pcmpeqd-1.ll utils/TableGen/CodeGenDAGPatterns.cpp Message-ID: <200812030521.mB35LReU024052@zion.cs.uiuc.edu> Author: djg Date: Tue Dec 2 23:21:24 2008 New Revision: 60461 URL: http://llvm.org/viewvc/llvm-project?rev=60461&view=rev Log: Mark x86's V_SET0 and V_SETALLONES with isSimpleLoad, and teach X86's foldMemoryOperand how to "fold" them, by converting them into constant-pool loads. When they aren't folded, they use xorps/cmpeqd, but for example when register pressure is high, they may now be folded as memory operands, which reduces register pressure. Also, mark V_SET0 isAsCheapAsAMove so that two-address-elimination will remat it instead of copying zeros around (V_SETALLONES was already marked). Added: llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-0.ll llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-1.ll Modified: llvm/trunk/include/llvm/Target/Target.td llvm/trunk/include/llvm/Target/TargetInstrDesc.h llvm/trunk/lib/Target/X86/X86InstrInfo.cpp llvm/trunk/lib/Target/X86/X86InstrSSE.td llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp Modified: llvm/trunk/include/llvm/Target/Target.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=60461&r1=60460&r2=60461&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/Target.td (original) +++ llvm/trunk/include/llvm/Target/Target.td Tue Dec 2 23:21:24 2008 @@ -189,7 +189,7 @@ bit isIndirectBranch = 0; // Is this instruction an indirect branch? bit isBarrier = 0; // Can control flow fall through this instruction? bit isCall = 0; // Is this instruction a call instruction? - bit isSimpleLoad = 0; // Is this just a load instruction? + bit isSimpleLoad = 0; // Can this be folded as a memory operand? bit mayLoad = 0; // Is it possible for this inst to read memory? bit mayStore = 0; // Is it possible for this inst to write memory? bit isTwoAddress = 0; // Is this a two address instruction? Modified: llvm/trunk/include/llvm/Target/TargetInstrDesc.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrDesc.h?rev=60461&r1=60460&r2=60461&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetInstrDesc.h (original) +++ llvm/trunk/include/llvm/Target/TargetInstrDesc.h Tue Dec 2 23:21:24 2008 @@ -301,11 +301,14 @@ return Flags & (1 << TID::DelaySlot); } - /// isSimpleLoad - Return true for instructions that are simple loads from - /// memory. This should only be set on instructions that load a value from - /// memory and return it in their only virtual register definition. - /// Instructions that return a value loaded from memory and then modified in - /// some way should not return true for this. + /// isSimpleLoad - Return true for instructions that can be folded as + /// memory operands in other instructions. The most common use for this + /// is instructions that are simple loads from memory that don't modify + /// the loaded value in any way, but it can also be used for instructions + /// that can be expressed as constant-pool loads, such as V_SETALLONES + /// on x86, to allow them to be folded when it is beneficial. + /// This should only be set on instructions that return a value in their + /// only virtual register definition. bool isSimpleLoad() const { return Flags & (1 << TID::SimpleLoad); } Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=60461&r1=60460&r2=60461&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Tue Dec 2 23:21:24 2008 @@ -19,6 +19,7 @@ #include "X86Subtarget.h" #include "X86TargetMachine.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" @@ -2127,9 +2128,36 @@ return NULL; SmallVector MOs; - unsigned NumOps = LoadMI->getDesc().getNumOperands(); - for (unsigned i = NumOps - 4; i != NumOps; ++i) - MOs.push_back(LoadMI->getOperand(i)); + if (LoadMI->getOpcode() == X86::V_SET0 || + LoadMI->getOpcode() == X86::V_SETALLONES) { + // Folding a V_SET0 or V_SETALLONES as a load, to ease register pressure. + // Create a constant-pool entry and operands to load from it. + + // x86-32 PIC requires a PIC base register for constant pools. + unsigned PICBase = 0; + if (TM.getRelocationModel() == Reloc::PIC_ && + !TM.getSubtarget().is64Bit()) + PICBase = TM.getInstrInfo()->getGlobalBaseReg(&MF); + + // Create a v4i32 constant-pool entry. + MachineConstantPool &MCP = *MF.getConstantPool(); + const VectorType *Ty = VectorType::get(Type::Int32Ty, 4); + Constant *C = LoadMI->getOpcode() == X86::V_SET0 ? + ConstantVector::getNullValue(Ty) : + ConstantVector::getAllOnesValue(Ty); + unsigned CPI = MCP.getConstantPoolIndex(C, /*AlignmentLog2=*/4); + + // Create operands to load from the constant pool entry. + MOs.push_back(MachineOperand::CreateReg(PICBase, false)); + MOs.push_back(MachineOperand::CreateImm(1)); + MOs.push_back(MachineOperand::CreateReg(0, false)); + MOs.push_back(MachineOperand::CreateCPI(CPI, 0)); + } else { + // Folding a normal load. Just copy the load's address operands. + unsigned NumOps = LoadMI->getDesc().getNumOperands(); + for (unsigned i = NumOps - 4; i != NumOps; ++i) + MOs.push_back(LoadMI->getOperand(i)); + } return foldMemoryOperand(MF, MI, Ops[0], MOs); } Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=60461&r1=60460&r2=60461&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Tue Dec 2 23:21:24 2008 @@ -987,7 +987,9 @@ "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)]>; // Alias instructions that map zero vector to pxor / xorp* for sse. -let isReMaterializable = 1 in +// We set isSimpleLoad because this can be converted to a constant-pool +// load of an all-zeros value if folding it would be beneficial. +let isReMaterializable = 1, isAsCheapAsAMove = 1, isSimpleLoad = 1 in def V_SET0 : PSI<0x57, MRMInitReg, (outs VR128:$dst), (ins), "xorps\t$dst, $dst", [(set VR128:$dst, (v4i32 immAllZerosV))]>; @@ -2253,7 +2255,9 @@ (i8 1)), (MFENCE)>; // Alias instructions that map zero vector to pxor / xorp* for sse. -let isReMaterializable = 1, isAsCheapAsAMove = 1 in +// We set isSimpleLoad because this can be converted to a constant-pool +// load of an all-ones value if folding it would be beneficial. +let isReMaterializable = 1, isAsCheapAsAMove = 1, isSimpleLoad = 1 in def V_SETALLONES : PDI<0x76, MRMInitReg, (outs VR128:$dst), (ins), "pcmpeqd\t$dst, $dst", [(set VR128:$dst, (v4i32 immAllOnesV))]>; Added: llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-0.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-0.ll?rev=60461&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-0.ll (added) +++ llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-0.ll Tue Dec 2 23:21:24 2008 @@ -0,0 +1,107 @@ +; RUN: llvm-as < %s | llc | not grep pcmpeqd +; RUN: llvm-as < %s | llc -march=x86-64 | grep pcmpeqd | count 1 + +; On x86-64, this testcase shouldn't need to spill the -1 value, +; so it should just use pcmpeqd to materialize an all-ones vector. +; On x86-32, there aren't enough registers, so an all-ones +; constant pool should be created so it can be folded. + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" +target triple = "i686-apple-cl.1.0" + %struct.__ImageExecInfo = type <{ <4 x i32>, <4 x float>, <2 x i64>, i8*, i8*, i8*, i32, i32, i32, i32, i32 }> + %struct._cl_image_format_t = type <{ i32, i32, i32 }> + %struct._image2d_t = type <{ i8*, %struct._cl_image_format_t, i32, i32, i32, i32, i32, i32 }> + +define void @program_1(%struct._image2d_t* %dest, %struct._image2d_t* %t0, <4 x float> %p0, <4 x float> %p1, <4 x float> %p4, <4 x float> %p5, <4 x float> %p6) nounwind { +entry: + %tmp3.i = load i32* null ; [#uses=1] + %cmp = icmp sgt i32 %tmp3.i, 200 ; [#uses=1] + br i1 %cmp, label %forcond, label %ifthen + +ifthen: ; preds = %entry + ret void + +forcond: ; preds = %entry + %tmp3.i536 = load i32* null ; [#uses=1] + %cmp12 = icmp slt i32 0, %tmp3.i536 ; [#uses=1] + br i1 %cmp12, label %forbody, label %afterfor + +forbody: ; preds = %forcond + %bitcast204.i313 = bitcast <4 x i32> zeroinitializer to <4 x float> ; <<4 x float>> [#uses=1] + %mul233 = mul <4 x float> %bitcast204.i313, zeroinitializer ; <<4 x float>> [#uses=1] + %mul257 = mul <4 x float> %mul233, zeroinitializer ; <<4 x float>> [#uses=1] + %mul275 = mul <4 x float> %mul257, zeroinitializer ; <<4 x float>> [#uses=1] + %tmp51 = call <4 x float> @llvm.x86.sse.max.ps(<4 x float> %mul275, <4 x float> zeroinitializer) nounwind ; <<4 x float>> [#uses=1] + %bitcast198.i182 = bitcast <4 x float> zeroinitializer to <4 x i32> ; <<4 x i32>> [#uses=0] + %bitcast204.i185 = bitcast <4 x i32> zeroinitializer to <4 x float> ; <<4 x float>> [#uses=1] + %tmp69 = call <4 x i32> @llvm.x86.sse2.cvttps2dq(<4 x float> zeroinitializer) nounwind ; <<4 x i32>> [#uses=1] + %tmp70 = call <4 x float> @llvm.x86.sse2.cvtdq2ps(<4 x i32> %tmp69) nounwind ; <<4 x float>> [#uses=1] + %sub140.i78 = sub <4 x float> zeroinitializer, %tmp70 ; <<4 x float>> [#uses=2] + %mul166.i86 = mul <4 x float> zeroinitializer, %sub140.i78 ; <<4 x float>> [#uses=1] + %add167.i87 = add <4 x float> %mul166.i86, < float 0x3FE62ACB60000000, float 0x3FE62ACB60000000, float 0x3FE62ACB60000000, float 0x3FE62ACB60000000 > ; <<4 x float>> [#uses=1] + %mul171.i88 = mul <4 x float> %add167.i87, %sub140.i78 ; <<4 x float>> [#uses=1] + %add172.i89 = add <4 x float> %mul171.i88, < float 0x3FF0000A40000000, float 0x3FF0000A40000000, float 0x3FF0000A40000000, float 0x3FF0000A40000000 > ; <<4 x float>> [#uses=1] + %bitcast176.i90 = bitcast <4 x float> %add172.i89 to <4 x i32> ; <<4 x i32>> [#uses=1] + %andnps178.i92 = and <4 x i32> %bitcast176.i90, zeroinitializer ; <<4 x i32>> [#uses=1] + %bitcast179.i93 = bitcast <4 x i32> %andnps178.i92 to <4 x float> ; <<4 x float>> [#uses=1] + %mul186.i96 = mul <4 x float> %bitcast179.i93, zeroinitializer ; <<4 x float>> [#uses=1] + %bitcast190.i98 = bitcast <4 x float> %mul186.i96 to <4 x i32> ; <<4 x i32>> [#uses=1] + %andnps192.i100 = and <4 x i32> %bitcast190.i98, zeroinitializer ; <<4 x i32>> [#uses=1] + %xorps.i102 = xor <4 x i32> zeroinitializer, < i32 -1, i32 -1, i32 -1, i32 -1 > ; <<4 x i32>> [#uses=1] + %orps203.i103 = or <4 x i32> %andnps192.i100, %xorps.i102 ; <<4 x i32>> [#uses=1] + %bitcast204.i104 = bitcast <4 x i32> %orps203.i103 to <4 x float> ; <<4 x float>> [#uses=1] + %cmple.i = call <4 x float> @llvm.x86.sse.cmp.ps(<4 x float> zeroinitializer, <4 x float> %tmp51, i8 2) nounwind ; <<4 x float>> [#uses=1] + %tmp80 = call <4 x float> @llvm.x86.sse2.cvtdq2ps(<4 x i32> zeroinitializer) nounwind ; <<4 x float>> [#uses=1] + %sub140.i = sub <4 x float> zeroinitializer, %tmp80 ; <<4 x float>> [#uses=1] + %bitcast148.i = bitcast <4 x float> zeroinitializer to <4 x i32> ; <<4 x i32>> [#uses=1] + %andnps150.i = and <4 x i32> %bitcast148.i, < i32 -2139095041, i32 -2139095041, i32 -2139095041, i32 -2139095041 > ; <<4 x i32>> [#uses=0] + %mul171.i = mul <4 x float> zeroinitializer, %sub140.i ; <<4 x float>> [#uses=1] + %add172.i = add <4 x float> %mul171.i, < float 0x3FF0000A40000000, float 0x3FF0000A40000000, float 0x3FF0000A40000000, float 0x3FF0000A40000000 > ; <<4 x float>> [#uses=1] + %bitcast176.i = bitcast <4 x float> %add172.i to <4 x i32> ; <<4 x i32>> [#uses=1] + %andnps178.i = and <4 x i32> %bitcast176.i, zeroinitializer ; <<4 x i32>> [#uses=1] + %bitcast179.i = bitcast <4 x i32> %andnps178.i to <4 x float> ; <<4 x float>> [#uses=1] + %mul186.i = mul <4 x float> %bitcast179.i, zeroinitializer ; <<4 x float>> [#uses=1] + %bitcast189.i = bitcast <4 x float> zeroinitializer to <4 x i32> ; <<4 x i32>> [#uses=0] + %bitcast190.i = bitcast <4 x float> %mul186.i to <4 x i32> ; <<4 x i32>> [#uses=1] + %andnps192.i = and <4 x i32> %bitcast190.i, zeroinitializer ; <<4 x i32>> [#uses=1] + %bitcast198.i = bitcast <4 x float> %cmple.i to <4 x i32> ; <<4 x i32>> [#uses=1] + %xorps.i = xor <4 x i32> %bitcast198.i, < i32 -1, i32 -1, i32 -1, i32 -1 > ; <<4 x i32>> [#uses=1] + %orps203.i = or <4 x i32> %andnps192.i, %xorps.i ; <<4 x i32>> [#uses=1] + %bitcast204.i = bitcast <4 x i32> %orps203.i to <4 x float> ; <<4 x float>> [#uses=1] + %mul307 = mul <4 x float> %bitcast204.i185, zeroinitializer ; <<4 x float>> [#uses=1] + %mul310 = mul <4 x float> %bitcast204.i104, zeroinitializer ; <<4 x float>> [#uses=2] + %mul313 = mul <4 x float> %bitcast204.i, zeroinitializer ; <<4 x float>> [#uses=1] + %tmp82 = call <4 x float> @llvm.x86.sse.min.ps(<4 x float> %mul307, <4 x float> zeroinitializer) nounwind ; <<4 x float>> [#uses=1] + %bitcast11.i15 = bitcast <4 x float> %tmp82 to <4 x i32> ; <<4 x i32>> [#uses=1] + %andnps.i17 = and <4 x i32> %bitcast11.i15, zeroinitializer ; <<4 x i32>> [#uses=1] + %orps.i18 = or <4 x i32> %andnps.i17, zeroinitializer ; <<4 x i32>> [#uses=1] + %bitcast17.i19 = bitcast <4 x i32> %orps.i18 to <4 x float> ; <<4 x float>> [#uses=1] + %tmp83 = call <4 x float> @llvm.x86.sse.min.ps(<4 x float> %mul310, <4 x float> zeroinitializer) nounwind ; <<4 x float>> [#uses=1] + %bitcast.i3 = bitcast <4 x float> %mul310 to <4 x i32> ; <<4 x i32>> [#uses=1] + %bitcast6.i4 = bitcast <4 x float> zeroinitializer to <4 x i32> ; <<4 x i32>> [#uses=2] + %andps.i5 = and <4 x i32> %bitcast.i3, %bitcast6.i4 ; <<4 x i32>> [#uses=1] + %bitcast11.i6 = bitcast <4 x float> %tmp83 to <4 x i32> ; <<4 x i32>> [#uses=1] + %not.i7 = xor <4 x i32> %bitcast6.i4, < i32 -1, i32 -1, i32 -1, i32 -1 > ; <<4 x i32>> [#uses=1] + %andnps.i8 = and <4 x i32> %bitcast11.i6, %not.i7 ; <<4 x i32>> [#uses=1] + %orps.i9 = or <4 x i32> %andnps.i8, %andps.i5 ; <<4 x i32>> [#uses=1] + %bitcast17.i10 = bitcast <4 x i32> %orps.i9 to <4 x float> ; <<4 x float>> [#uses=1] + %bitcast.i = bitcast <4 x float> %mul313 to <4 x i32> ; <<4 x i32>> [#uses=1] + %andps.i = and <4 x i32> %bitcast.i, zeroinitializer ; <<4 x i32>> [#uses=1] + %orps.i = or <4 x i32> zeroinitializer, %andps.i ; <<4 x i32>> [#uses=1] + %bitcast17.i = bitcast <4 x i32> %orps.i to <4 x float> ; <<4 x float>> [#uses=1] + call void null(<4 x float> %bitcast17.i19, <4 x float> %bitcast17.i10, <4 x float> %bitcast17.i, <4 x float> zeroinitializer, %struct.__ImageExecInfo* null, <4 x i32> zeroinitializer) nounwind + unreachable + +afterfor: ; preds = %forcond + ret void +} + +declare <4 x float> @llvm.x86.sse.cmp.ps(<4 x float>, <4 x float>, i8) nounwind readnone + +declare <4 x float> @llvm.x86.sse2.cvtdq2ps(<4 x i32>) nounwind readnone + +declare <4 x i32> @llvm.x86.sse2.cvttps2dq(<4 x float>) nounwind readnone + +declare <4 x float> @llvm.x86.sse.max.ps(<4 x float>, <4 x float>) nounwind readnone + +declare <4 x float> @llvm.x86.sse.min.ps(<4 x float>, <4 x float>) nounwind readnone Added: llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-1.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-1.ll?rev=60461&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-1.ll (added) +++ llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-1.ll Tue Dec 2 23:21:24 2008 @@ -0,0 +1,11 @@ +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 > %t +; RUN: grep pcmpeqd %t | count 1 +; RUN: grep xor %t | count 1 +; RUN: not grep LCP %t + +define <2 x double> @foo() nounwind { + ret <2 x double> bitcast (<2 x i64> to <2 x double>) +} +define <2 x double> @bar() nounwind { + ret <2 x double> bitcast (<2 x i64> to <2 x double>) +} Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp?rev=60461&r1=60460&r2=60461&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp (original) +++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp Tue Dec 2 23:21:24 2008 @@ -1759,15 +1759,6 @@ MayLoad = true; } - // Sanity-check the isSimpleLoad flag. - if (Inst.isSimpleLoad) { - if (!MayLoad) - fprintf(stderr, - "Warning: mayLoad flag not set or inferred for instruction '%s'" - " which has isSimpleLoad set.\n", - Inst.TheDef->getName().c_str()); - } - if (Inst.neverHasSideEffects) { if (HadPattern) fprintf(stderr, "Warning: neverHasSideEffects set on instruction '%s' " From sabre at nondot.org Wed Dec 3 00:37:44 2008 From: sabre at nondot.org (Chris Lattner) Date: Wed, 03 Dec 2008 06:37:44 -0000 Subject: [llvm-commits] [llvm] r60463 - in /llvm/trunk: include/llvm/Transforms/Utils/BasicBlockUtils.h lib/Transforms/Utils/BasicBlockUtils.cpp lib/Transforms/Utils/SimplifyCFG.cpp Message-ID: <200812030637.mB36birV026267@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 3 00:37:44 2008 New Revision: 60463 URL: http://llvm.org/viewvc/llvm-project?rev=60463&view=rev Log: Factor some code out of SimplifyCFG, forming a new DeleteBlockIfDead method. Modified: llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Modified: llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h?rev=60463&r1=60462&r2=60463&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h (original) +++ llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h Wed Dec 3 00:37:44 2008 @@ -26,6 +26,11 @@ class Pass; class AliasAnalysis; +/// DeleteBlockIfDead - If the specified basic block is trivially dead (has no +/// predecessors and not the entry block), delete it and return true. Otherwise +/// return false. +bool DeleteBlockIfDead(BasicBlock *BB); + /// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor, /// if possible. The return value indicates success or failure. bool MergeBlockIntoPredecessor(BasicBlock* BB, Pass* P = 0); Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp?rev=60463&r1=60462&r2=60463&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Wed Dec 3 00:37:44 2008 @@ -24,6 +24,39 @@ #include using namespace llvm; +/// DeleteBlockIfDead - If the specified basic block is trivially dead (has no +/// predecessors and not the entry block), delete it and return true. Otherwise +/// return false. +bool llvm::DeleteBlockIfDead(BasicBlock *BB) { + if (pred_begin(BB) != pred_end(BB) || + BB == &BB->getParent()->getEntryBlock()) + return false; + + TerminatorInst *BBTerm = BB->getTerminator(); + + // Loop through all of our successors and make sure they know that one + // of their predecessors is going away. + for (unsigned i = 0, e = BBTerm->getNumSuccessors(); i != e; ++i) + BBTerm->getSuccessor(i)->removePredecessor(BB); + + // Zap all the instructions in the block. + while (!BB->empty()) { + Instruction &I = BB->back(); + // If this instruction is used, replace uses with an arbitrary value. + // Because control flow can't get here, we don't care what we replace the + // value with. Note that since this block is unreachable, and all values + // contained within it must dominate their uses, that all uses will + // eventually be removed (they are themselves dead). + if (!I.use_empty()) + I.replaceAllUsesWith(UndefValue::get(I.getType())); + BB->getInstList().pop_back(); + } + + // Zap the block! + BB->eraseFromParent(); + return true; +} + /// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor, /// if possible. The return value indicates success or failure. bool llvm::MergeBlockIntoPredecessor(BasicBlock* BB, Pass* P) { Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=60463&r1=60462&r2=60463&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Wed Dec 3 00:37:44 2008 @@ -1681,27 +1681,7 @@ // as a predecessor. These are unreachable. if (pred_begin(BB) == pred_end(BB) || BB->getSinglePredecessor() == BB) { DOUT << "Removing BB: \n" << *BB; - - // Loop through all of our successors and make sure they know that one - // of their predecessors is going away. - for (succ_iterator SI = succ_begin(BB), E = succ_end(BB); SI != E; ++SI) - SI->removePredecessor(BB); - - while (!BB->empty()) { - Instruction &I = BB->back(); - // If this instruction is used, replace uses with an arbitrary - // value. Because control flow can't get here, we don't care - // what we replace the value with. Note that since this block is - // unreachable, and all values contained within it must dominate their - // uses, that all uses will eventually be removed. - if (!I.use_empty()) - // Make all users of this instruction use undef instead - I.replaceAllUsesWith(UndefValue::get(I.getType())); - - // Remove the instruction from the basic block - BB->getInstList().pop_back(); - } - BB->eraseFromParent(); + DeleteBlockIfDead(BB); return true; } From sabre at nondot.org Wed Dec 3 00:40:52 2008 From: sabre at nondot.org (Chris Lattner) Date: Wed, 03 Dec 2008 06:40:52 -0000 Subject: [llvm-commits] [llvm] r60464 - in /llvm/trunk: include/llvm/Transforms/Utils/BasicBlockUtils.h lib/Transforms/Utils/BasicBlockUtils.cpp lib/Transforms/Utils/SimplifyCFG.cpp Message-ID: <200812030640.mB36eqH9026371@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 3 00:40:52 2008 New Revision: 60464 URL: http://llvm.org/viewvc/llvm-project?rev=60464&view=rev Log: Rename DeleteBlockIfDead to DeleteDeadBlock and make it unconditionally delete the block. All likely clients will do the checking anyway. Modified: llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Modified: llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h?rev=60464&r1=60463&r2=60464&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h (original) +++ llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h Wed Dec 3 00:40:52 2008 @@ -26,10 +26,9 @@ class Pass; class AliasAnalysis; -/// DeleteBlockIfDead - If the specified basic block is trivially dead (has no -/// predecessors and not the entry block), delete it and return true. Otherwise -/// return false. -bool DeleteBlockIfDead(BasicBlock *BB); +/// DeleteDeadBlock - Delete the specified block, which must have no +/// predecessors. +void DeleteDeadBlock(BasicBlock *BB); /// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor, /// if possible. The return value indicates success or failure. Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp?rev=60464&r1=60463&r2=60464&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Wed Dec 3 00:40:52 2008 @@ -24,14 +24,10 @@ #include using namespace llvm; -/// DeleteBlockIfDead - If the specified basic block is trivially dead (has no -/// predecessors and not the entry block), delete it and return true. Otherwise -/// return false. -bool llvm::DeleteBlockIfDead(BasicBlock *BB) { - if (pred_begin(BB) != pred_end(BB) || - BB == &BB->getParent()->getEntryBlock()) - return false; - +/// DeleteDeadBlock - Delete the specified block, which must have no +/// predecessors. +void llvm::DeleteDeadBlock(BasicBlock *BB) { + assert(pred_begin(BB) != pred_end(BB) && "Block is not dead!"); TerminatorInst *BBTerm = BB->getTerminator(); // Loop through all of our successors and make sure they know that one @@ -54,7 +50,6 @@ // Zap the block! BB->eraseFromParent(); - return true; } /// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor, Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=60464&r1=60463&r2=60464&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Wed Dec 3 00:40:52 2008 @@ -1681,7 +1681,7 @@ // as a predecessor. These are unreachable. if (pred_begin(BB) == pred_end(BB) || BB->getSinglePredecessor() == BB) { DOUT << "Removing BB: \n" << *BB; - DeleteBlockIfDead(BB); + DeleteDeadBlock(BB); return true; } From sabre at nondot.org Wed Dec 3 00:41:50 2008 From: sabre at nondot.org (Chris Lattner) Date: Wed, 03 Dec 2008 06:41:50 -0000 Subject: [llvm-commits] [llvm] r60465 - /llvm/trunk/test/Transforms/LoopDeletion/2008-05-06-Phi.ll Message-ID: <200812030641.mB36fooQ026403@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 3 00:41:50 2008 New Revision: 60465 URL: http://llvm.org/viewvc/llvm-project?rev=60465&view=rev Log: don't spew tons of stuff to the output. This testcase is *not* for loop deletion (it is for a ton of passes), which is very bad. Modified: llvm/trunk/test/Transforms/LoopDeletion/2008-05-06-Phi.ll Modified: llvm/trunk/test/Transforms/LoopDeletion/2008-05-06-Phi.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopDeletion/2008-05-06-Phi.ll?rev=60465&r1=60464&r2=60465&view=diff ============================================================================== --- llvm/trunk/test/Transforms/LoopDeletion/2008-05-06-Phi.ll (original) +++ llvm/trunk/test/Transforms/LoopDeletion/2008-05-06-Phi.ll Wed Dec 3 00:41:50 2008 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | opt -inline -tailduplicate -instcombine -jump-threading -licm -loop-unswitch -instcombine -indvars -loop-deletion -gvn -simplifycfg -verify +; RUN: llvm-as < %s | opt -inline -tailduplicate -instcombine -jump-threading -licm -loop-unswitch -instcombine -indvars -loop-deletion -gvn -simplifycfg -verify -disable-output target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" target triple = "i386-apple-darwin9" From isanbard at gmail.com Wed Dec 3 01:04:51 2008 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 03 Dec 2008 07:04:51 -0000 Subject: [llvm-commits] [llvm] r60466 - /llvm/tags/Apple/llvmCore-2086/ Message-ID: <200812030704.mB374pJm027049@zion.cs.uiuc.edu> Author: void Date: Wed Dec 3 01:04:51 2008 New Revision: 60466 URL: http://llvm.org/viewvc/llvm-project?rev=60466&view=rev Log: Creating llvmCore-2086 branch Added: llvm/tags/Apple/llvmCore-2086/ - copied from r60465, llvm/trunk/ From isanbard at gmail.com Wed Dec 3 01:04:58 2008 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 03 Dec 2008 07:04:58 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60467 - /llvm-gcc-4.2/tags/Apple/llvmgcc42-2086/ Message-ID: <200812030704.mB374wvg027063@zion.cs.uiuc.edu> Author: void Date: Wed Dec 3 01:04:58 2008 New Revision: 60467 URL: http://llvm.org/viewvc/llvm-project?rev=60467&view=rev Log: Creating llvmgcc42-2086 branch Added: llvm-gcc-4.2/tags/Apple/llvmgcc42-2086/ - copied from r60466, llvm-gcc-4.2/trunk/ From evan.cheng at apple.com Wed Dec 3 01:20:04 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 2 Dec 2008 23:20:04 -0800 Subject: [llvm-commits] [llvm] r60461 - in /llvm/trunk: include/llvm/Target/Target.td include/llvm/Target/TargetInstrDesc.h lib/Target/X86/X86InstrInfo.cpp lib/Target/X86/X86InstrSSE.td test/CodeGen/X86/fold-pcmpeqd-0.ll test/CodeGen/X86/fold-pcmpeqd-1.ll utils/TableGen/CodeGenDAGPatterns.cpp In-Reply-To: <200812030521.mB35LReU024052@zion.cs.uiuc.edu> References: <200812030521.mB35LReU024052@zion.cs.uiuc.edu> Message-ID: <3D688597-4F63-43BA-9BEE-7D42EA15AA7D@apple.com> Hi Dan, You are changing the meaning of isSimpleLoad to something that's not at all obvious form the name. Perhaps we should add a new TargetInstrDesc flag (canChangeIntoSimpleLoad?). BranchFolding also uses isSimpleLoad. Evan On Dec 2, 2008, at 9:21 PM, Dan Gohman wrote: > Author: djg > Date: Tue Dec 2 23:21:24 2008 > New Revision: 60461 > > URL: http://llvm.org/viewvc/llvm-project?rev=60461&view=rev > Log: > Mark x86's V_SET0 and V_SETALLONES with isSimpleLoad, and teach X86's > foldMemoryOperand how to "fold" them, by converting them into > constant-pool > loads. When they aren't folded, they use xorps/cmpeqd, but for > example when > register pressure is high, they may now be folded as memory > operands, which > reduces register pressure. > > Also, mark V_SET0 isAsCheapAsAMove so that two-address-elimination > will > remat it instead of copying zeros around (V_SETALLONES was already > marked). > > Added: > llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-0.ll > llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-1.ll > Modified: > llvm/trunk/include/llvm/Target/Target.td > llvm/trunk/include/llvm/Target/TargetInstrDesc.h > llvm/trunk/lib/Target/X86/X86InstrInfo.cpp > llvm/trunk/lib/Target/X86/X86InstrSSE.td > llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp > > Modified: llvm/trunk/include/llvm/Target/Target.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=60461&r1=60460&r2=60461&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/Target/Target.td (original) > +++ llvm/trunk/include/llvm/Target/Target.td Tue Dec 2 23:21:24 2008 > @@ -189,7 +189,7 @@ > bit isIndirectBranch = 0; // Is this instruction an indirect branch? > bit isBarrier = 0; // Can control flow fall through this > instruction? > bit isCall = 0; // Is this instruction a call instruction? > - bit isSimpleLoad = 0; // Is this just a load instruction? > + bit isSimpleLoad = 0; // Can this be folded as a memory > operand? > bit mayLoad = 0; // Is it possible for this inst to read > memory? > bit mayStore = 0; // Is it possible for this inst to write > memory? > bit isTwoAddress = 0; // Is this a two address instruction? > > Modified: llvm/trunk/include/llvm/Target/TargetInstrDesc.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrDesc.h?rev=60461&r1=60460&r2=60461&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/Target/TargetInstrDesc.h (original) > +++ llvm/trunk/include/llvm/Target/TargetInstrDesc.h Tue Dec 2 > 23:21:24 2008 > @@ -301,11 +301,14 @@ > return Flags & (1 << TID::DelaySlot); > } > > - /// isSimpleLoad - Return true for instructions that are simple > loads from > - /// memory. This should only be set on instructions that load a > value from > - /// memory and return it in their only virtual register definition. > - /// Instructions that return a value loaded from memory and then > modified in > - /// some way should not return true for this. > + /// isSimpleLoad - Return true for instructions that can be > folded as > + /// memory operands in other instructions. The most common use > for this > + /// is instructions that are simple loads from memory that don't > modify > + /// the loaded value in any way, but it can also be used for > instructions > + /// that can be expressed as constant-pool loads, such as > V_SETALLONES > + /// on x86, to allow them to be folded when it is beneficial. > + /// This should only be set on instructions that return a value > in their > + /// only virtual register definition. > bool isSimpleLoad() const { > return Flags & (1 << TID::SimpleLoad); > } > > Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=60461&r1=60460&r2=60461&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) > +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Tue Dec 2 23:21:24 > 2008 > @@ -19,6 +19,7 @@ > #include "X86Subtarget.h" > #include "X86TargetMachine.h" > #include "llvm/ADT/STLExtras.h" > +#include "llvm/CodeGen/MachineConstantPool.h" > #include "llvm/CodeGen/MachineFrameInfo.h" > #include "llvm/CodeGen/MachineInstrBuilder.h" > #include "llvm/CodeGen/MachineRegisterInfo.h" > @@ -2127,9 +2128,36 @@ > return NULL; > > SmallVector MOs; > - unsigned NumOps = LoadMI->getDesc().getNumOperands(); > - for (unsigned i = NumOps - 4; i != NumOps; ++i) > - MOs.push_back(LoadMI->getOperand(i)); > + if (LoadMI->getOpcode() == X86::V_SET0 || > + LoadMI->getOpcode() == X86::V_SETALLONES) { > + // Folding a V_SET0 or V_SETALLONES as a load, to ease register > pressure. > + // Create a constant-pool entry and operands to load from it. > + > + // x86-32 PIC requires a PIC base register for constant pools. > + unsigned PICBase = 0; > + if (TM.getRelocationModel() == Reloc::PIC_ && > + !TM.getSubtarget().is64Bit()) > + PICBase = TM.getInstrInfo()->getGlobalBaseReg(&MF); > + > + // Create a v4i32 constant-pool entry. > + MachineConstantPool &MCP = *MF.getConstantPool(); > + const VectorType *Ty = VectorType::get(Type::Int32Ty, 4); > + Constant *C = LoadMI->getOpcode() == X86::V_SET0 ? > + ConstantVector::getNullValue(Ty) : > + ConstantVector::getAllOnesValue(Ty); > + unsigned CPI = MCP.getConstantPoolIndex(C, /*AlignmentLog2=*/4); > + > + // Create operands to load from the constant pool entry. > + MOs.push_back(MachineOperand::CreateReg(PICBase, false)); > + MOs.push_back(MachineOperand::CreateImm(1)); > + MOs.push_back(MachineOperand::CreateReg(0, false)); > + MOs.push_back(MachineOperand::CreateCPI(CPI, 0)); > + } else { > + // Folding a normal load. Just copy the load's address operands. > + unsigned NumOps = LoadMI->getDesc().getNumOperands(); > + for (unsigned i = NumOps - 4; i != NumOps; ++i) > + MOs.push_back(LoadMI->getOperand(i)); > + } > return foldMemoryOperand(MF, MI, Ops[0], MOs); > } > > > Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=60461&r1=60460&r2=60461&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) > +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Tue Dec 2 23:21:24 2008 > @@ -987,7 +987,9 @@ > "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)]>; > > // Alias instructions that map zero vector to pxor / xorp* for sse. > -let isReMaterializable = 1 in > +// We set isSimpleLoad because this can be converted to a constant- > pool > +// load of an all-zeros value if folding it would be beneficial. > +let isReMaterializable = 1, isAsCheapAsAMove = 1, isSimpleLoad = 1 in > def V_SET0 : PSI<0x57, MRMInitReg, (outs VR128:$dst), (ins), > "xorps\t$dst, $dst", > [(set VR128:$dst, (v4i32 immAllZerosV))]>; > @@ -2253,7 +2255,9 @@ > (i8 1)), (MFENCE)>; > > // Alias instructions that map zero vector to pxor / xorp* for sse. > -let isReMaterializable = 1, isAsCheapAsAMove = 1 in > +// We set isSimpleLoad because this can be converted to a constant- > pool > +// load of an all-ones value if folding it would be beneficial. > +let isReMaterializable = 1, isAsCheapAsAMove = 1, isSimpleLoad = 1 in > def V_SETALLONES : PDI<0x76, MRMInitReg, (outs VR128:$dst), (ins), > "pcmpeqd\t$dst, $dst", > [(set VR128:$dst, (v4i32 immAllOnesV))]>; > > Added: llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-0.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-0.ll?rev=60461&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-0.ll (added) > +++ llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-0.ll Tue Dec 2 > 23:21:24 2008 > @@ -0,0 +1,107 @@ > +; RUN: llvm-as < %s | llc | not grep pcmpeqd > +; RUN: llvm-as < %s | llc -march=x86-64 | grep pcmpeqd | count 1 > + > +; On x86-64, this testcase shouldn't need to spill the -1 value, > +; so it should just use pcmpeqd to materialize an all-ones vector. > +; On x86-32, there aren't enough registers, so an all-ones > +; constant pool should be created so it can be folded. > + > +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32- > i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64- > f80:32:32" > +target triple = "i686-apple-cl.1.0" > + %struct.__ImageExecInfo = type <{ <4 x i32>, <4 x float>, <2 x > i64>, i8*, i8*, i8*, i32, i32, i32, i32, i32 }> > + %struct._cl_image_format_t = type <{ i32, i32, i32 }> > + %struct._image2d_t = type <{ i8*, %struct._cl_image_format_t, i32, > i32, i32, i32, i32, i32 }> > + > +define void @program_1(%struct._image2d_t* %dest, > %struct._image2d_t* %t0, <4 x float> %p0, <4 x float> %p1, <4 x > float> %p4, <4 x float> %p5, <4 x float> %p6) nounwind { > +entry: > + %tmp3.i = load i32* null ; [#uses=1] > + %cmp = icmp sgt i32 %tmp3.i, 200 ; [#uses=1] > + br i1 %cmp, label %forcond, label %ifthen > + > +ifthen: ; preds = %entry > + ret void > + > +forcond: ; preds = %entry > + %tmp3.i536 = load i32* null ; [#uses=1] > + %cmp12 = icmp slt i32 0, %tmp3.i536 ; [#uses=1] > + br i1 %cmp12, label %forbody, label %afterfor > + > +forbody: ; preds = %forcond > + %bitcast204.i313 = bitcast <4 x i32> zeroinitializer to <4 x > float> ; <<4 x float>> [#uses=1] > + %mul233 = mul <4 x float> %bitcast204.i313, zeroinitializer ; <<4 > x float>> [#uses=1] > + %mul257 = mul <4 x float> %mul233, zeroinitializer ; <<4 x > float>> [#uses=1] > + %mul275 = mul <4 x float> %mul257, zeroinitializer ; <<4 x > float>> [#uses=1] > + %tmp51 = call <4 x float> @llvm.x86.sse.max.ps(<4 x float> > %mul275, <4 x float> zeroinitializer) nounwind ; <<4 x float>> > [#uses=1] > + %bitcast198.i182 = bitcast <4 x float> zeroinitializer to <4 x > i32> ; <<4 x i32>> [#uses=0] > + %bitcast204.i185 = bitcast <4 x i32> zeroinitializer to <4 x > float> ; <<4 x float>> [#uses=1] > + %tmp69 = call <4 x i32> @llvm.x86.sse2.cvttps2dq(<4 x float> > zeroinitializer) nounwind ; <<4 x i32>> [#uses=1] > + %tmp70 = call <4 x float> @llvm.x86.sse2.cvtdq2ps(<4 x i32> > %tmp69) nounwind ; <<4 x float>> [#uses=1] > + %sub140.i78 = sub <4 x float> zeroinitializer, %tmp70 ; <<4 x > float>> [#uses=2] > + %mul166.i86 = mul <4 x float> zeroinitializer, %sub140.i78 ; <<4 > x float>> [#uses=1] > + %add167.i87 = add <4 x float> %mul166.i86, < float > 0x3FE62ACB60000000, float 0x3FE62ACB60000000, float > 0x3FE62ACB60000000, float 0x3FE62ACB60000000 > ; <<4 x float>> > [#uses=1] > + %mul171.i88 = mul <4 x float> %add167.i87, %sub140.i78 ; <<4 x > float>> [#uses=1] > + %add172.i89 = add <4 x float> %mul171.i88, < float > 0x3FF0000A40000000, float 0x3FF0000A40000000, float > 0x3FF0000A40000000, float 0x3FF0000A40000000 > ; <<4 x float>> > [#uses=1] > + %bitcast176.i90 = bitcast <4 x float> %add172.i89 to <4 x i32> ; > <<4 x i32>> [#uses=1] > + %andnps178.i92 = and <4 x i32> %bitcast176.i90, zeroinitializer ; > <<4 x i32>> [#uses=1] > + %bitcast179.i93 = bitcast <4 x i32> %andnps178.i92 to <4 x > float> ; <<4 x float>> [#uses=1] > + %mul186.i96 = mul <4 x float> %bitcast179.i93, zeroinitializer ; > <<4 x float>> [#uses=1] > + %bitcast190.i98 = bitcast <4 x float> %mul186.i96 to <4 x i32> ; > <<4 x i32>> [#uses=1] > + %andnps192.i100 = and <4 x i32> %bitcast190.i98, > zeroinitializer ; <<4 x i32>> [#uses=1] > + %xorps.i102 = xor <4 x i32> zeroinitializer, < i32 -1, i32 -1, i32 > -1, i32 -1 > ; <<4 x i32>> [#uses=1] > + %orps203.i103 = or <4 x i32> %andnps192.i100, %xorps.i102 ; <<4 x > i32>> [#uses=1] > + %bitcast204.i104 = bitcast <4 x i32> %orps203.i103 to <4 x > float> ; <<4 x float>> [#uses=1] > + %cmple.i = call <4 x float> @llvm.x86.sse.cmp.ps(<4 x float> > zeroinitializer, <4 x float> %tmp51, i8 2) nounwind ; <<4 x float>> > [#uses=1] > + %tmp80 = call <4 x float> @llvm.x86.sse2.cvtdq2ps(<4 x i32> > zeroinitializer) nounwind ; <<4 x float>> [#uses=1] > + %sub140.i = sub <4 x float> zeroinitializer, %tmp80 ; <<4 x > float>> [#uses=1] > + %bitcast148.i = bitcast <4 x float> zeroinitializer to <4 x > i32> ; <<4 x i32>> [#uses=1] > + %andnps150.i = and <4 x i32> %bitcast148.i, < i32 -2139095041, i32 > -2139095041, i32 -2139095041, i32 -2139095041 > ; <<4 x i32>> > [#uses=0] > + %mul171.i = mul <4 x float> zeroinitializer, %sub140.i ; <<4 x > float>> [#uses=1] > + %add172.i = add <4 x float> %mul171.i, < float 0x3FF0000A40000000, > float 0x3FF0000A40000000, float 0x3FF0000A40000000, float > 0x3FF0000A40000000 > ; <<4 x float>> [#uses=1] > + %bitcast176.i = bitcast <4 x float> %add172.i to <4 x i32> ; <<4 > x i32>> [#uses=1] > + %andnps178.i = and <4 x i32> %bitcast176.i, zeroinitializer ; <<4 > x i32>> [#uses=1] > + %bitcast179.i = bitcast <4 x i32> %andnps178.i to <4 x float> ; > <<4 x float>> [#uses=1] > + %mul186.i = mul <4 x float> %bitcast179.i, zeroinitializer ; <<4 > x float>> [#uses=1] > + %bitcast189.i = bitcast <4 x float> zeroinitializer to <4 x > i32> ; <<4 x i32>> [#uses=0] > + %bitcast190.i = bitcast <4 x float> %mul186.i to <4 x i32> ; <<4 > x i32>> [#uses=1] > + %andnps192.i = and <4 x i32> %bitcast190.i, zeroinitializer ; <<4 > x i32>> [#uses=1] > + %bitcast198.i = bitcast <4 x float> %cmple.i to <4 x i32> ; <<4 x > i32>> [#uses=1] > + %xorps.i = xor <4 x i32> %bitcast198.i, < i32 -1, i32 -1, i32 -1, > i32 -1 > ; <<4 x i32>> [#uses=1] > + %orps203.i = or <4 x i32> %andnps192.i, %xorps.i ; <<4 x i32>> > [#uses=1] > + %bitcast204.i = bitcast <4 x i32> %orps203.i to <4 x float> ; <<4 > x float>> [#uses=1] > + %mul307 = mul <4 x float> %bitcast204.i185, zeroinitializer ; <<4 > x float>> [#uses=1] > + %mul310 = mul <4 x float> %bitcast204.i104, zeroinitializer ; <<4 > x float>> [#uses=2] > + %mul313 = mul <4 x float> %bitcast204.i, zeroinitializer ; <<4 x > float>> [#uses=1] > + %tmp82 = call <4 x float> @llvm.x86.sse.min.ps(<4 x float> > %mul307, <4 x float> zeroinitializer) nounwind ; <<4 x float>> > [#uses=1] > + %bitcast11.i15 = bitcast <4 x float> %tmp82 to <4 x i32> ; <<4 x > i32>> [#uses=1] > + %andnps.i17 = and <4 x i32> %bitcast11.i15, zeroinitializer ; <<4 > x i32>> [#uses=1] > + %orps.i18 = or <4 x i32> %andnps.i17, zeroinitializer ; <<4 x > i32>> [#uses=1] > + %bitcast17.i19 = bitcast <4 x i32> %orps.i18 to <4 x float> ; <<4 > x float>> [#uses=1] > + %tmp83 = call <4 x float> @llvm.x86.sse.min.ps(<4 x float> > %mul310, <4 x float> zeroinitializer) nounwind ; <<4 x float>> > [#uses=1] > + %bitcast.i3 = bitcast <4 x float> %mul310 to <4 x i32> ; <<4 x > i32>> [#uses=1] > + %bitcast6.i4 = bitcast <4 x float> zeroinitializer to <4 x i32> ; > <<4 x i32>> [#uses=2] > + %andps.i5 = and <4 x i32> %bitcast.i3, %bitcast6.i4 ; <<4 x i32>> > [#uses=1] > + %bitcast11.i6 = bitcast <4 x float> %tmp83 to <4 x i32> ; <<4 x > i32>> [#uses=1] > + %not.i7 = xor <4 x i32> %bitcast6.i4, < i32 -1, i32 -1, i32 -1, > i32 -1 > ; <<4 x i32>> [#uses=1] > + %andnps.i8 = and <4 x i32> %bitcast11.i6, %not.i7 ; <<4 x i32>> > [#uses=1] > + %orps.i9 = or <4 x i32> %andnps.i8, %andps.i5 ; <<4 x i32>> > [#uses=1] > + %bitcast17.i10 = bitcast <4 x i32> %orps.i9 to <4 x float> ; <<4 > x float>> [#uses=1] > + %bitcast.i = bitcast <4 x float> %mul313 to <4 x i32> ; <<4 x > i32>> [#uses=1] > + %andps.i = and <4 x i32> %bitcast.i, zeroinitializer ; <<4 x > i32>> [#uses=1] > + %orps.i = or <4 x i32> zeroinitializer, %andps.i ; <<4 x i32>> > [#uses=1] > + %bitcast17.i = bitcast <4 x i32> %orps.i to <4 x float> ; <<4 x > float>> [#uses=1] > + call void null(<4 x float> %bitcast17.i19, <4 x float> > %bitcast17.i10, <4 x float> %bitcast17.i, <4 x float> > zeroinitializer, %struct.__ImageExecInfo* null, <4 x i32> > zeroinitializer) nounwind > + unreachable > + > +afterfor: ; preds = %forcond > + ret void > +} > + > +declare <4 x float> @llvm.x86.sse.cmp.ps(<4 x float>, <4 x float>, > i8) nounwind readnone > + > +declare <4 x float> @llvm.x86.sse2.cvtdq2ps(<4 x i32>) nounwind > readnone > + > +declare <4 x i32> @llvm.x86.sse2.cvttps2dq(<4 x float>) nounwind > readnone > + > +declare <4 x float> @llvm.x86.sse.max.ps(<4 x float>, <4 x float>) > nounwind readnone > + > +declare <4 x float> @llvm.x86.sse.min.ps(<4 x float>, <4 x float>) > nounwind readnone > > Added: llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-1.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-1.ll?rev=60461&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-1.ll (added) > +++ llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-1.ll Tue Dec 2 > 23:21:24 2008 > @@ -0,0 +1,11 @@ > +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 > %t > +; RUN: grep pcmpeqd %t | count 1 > +; RUN: grep xor %t | count 1 > +; RUN: not grep LCP %t > + > +define <2 x double> @foo() nounwind { > + ret <2 x double> bitcast (<2 x i64> to <2 x > double>) > +} > +define <2 x double> @bar() nounwind { > + ret <2 x double> bitcast (<2 x i64> to <2 x double>) > +} > > Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp?rev=60461&r1=60460&r2=60461&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp (original) > +++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp Tue Dec 2 > 23:21:24 2008 > @@ -1759,15 +1759,6 @@ > MayLoad = true; > } > > - // Sanity-check the isSimpleLoad flag. > - if (Inst.isSimpleLoad) { > - if (!MayLoad) > - fprintf(stderr, > - "Warning: mayLoad flag not set or inferred for > instruction '%s'" > - " which has isSimpleLoad set.\n", > - Inst.TheDef->getName().c_str()); > - } > - > if (Inst.neverHasSideEffects) { > if (HadPattern) > fprintf(stderr, "Warning: neverHasSideEffects set on > instruction '%s' " > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From evan.cheng at apple.com Wed Dec 3 01:27:55 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 2 Dec 2008 23:27:55 -0800 Subject: [llvm-commits] [llvm] r60388 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h test/CodeGen/X86/add-with-overflow.ll In-Reply-To: <200812020106.mB216dUK025251@zion.cs.uiuc.edu> References: <200812020106.mB216dUK025251@zion.cs.uiuc.edu> Message-ID: <422E6392-715E-49C0-9D13-491A2CCDA070@apple.com> On Dec 1, 2008, at 5:06 PM, Bill Wendling wrote: > Author: void > Date: Mon Dec 1 19:06:39 2008 > New Revision: 60388 > > URL: http://llvm.org/viewvc/llvm-project?rev=60388&view=rev > Log: > Second stab at target-dependent lowering of everyone's favorite > nodes: [SU]ADDO > > - LowerXADDO lowers [SU]ADDO into an ADD with an implicit EFLAGS > define. The > EFLAGS are fed into a SETCC node which has the conditional COND_O > or COND_C, > depending on the type of ADDO requested. > > - LowerBRCOND now recognizes if it's coming from a SETCC node with > COND_O or > COND_C set. > > Modified: > llvm/trunk/lib/Target/X86/X86ISelLowering.cpp > llvm/trunk/lib/Target/X86/X86ISelLowering.h > llvm/trunk/test/CodeGen/X86/add-with-overflow.ll > > Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=60388&r1=60387&r2=60388&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) > +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Dec 1 > 19:06:39 2008 > @@ -5186,6 +5186,8 @@ > > if (Cond.getOpcode() == ISD::SETCC) > Cond = LowerSETCC(Cond, DAG); > + else if (Cond.getOpcode() == ISD::SADDO || Cond.getOpcode() == > ISD::UADDO) > + Cond = LowerXADDO(Cond, DAG); > > // If condition flag is set by a X86ISD::CMP, then use it as the > condition > // setting operand in place of the X86ISD::SETCC. > @@ -5199,6 +5201,17 @@ > Opc == X86ISD::UCOMI) { > Cond = Cmp; > addTest = false; > + } else { > + if (ConstantSDNode *CSDN = > dyn_cast(CC.getNode())) { Is it possible for CC not to be a constsdnode here? Should it be an assertion instead? Evan > > + switch (CSDN->getZExtValue()) { > + default: break; > + case X86::COND_O: > + case X86::COND_C: > + Cond = Cond.getNode()->getOperand(1); > + addTest = false; > + break; > + } > + } > } > // Also, recognize the pattern generated by an FCMP_UNE. We can emit > // two branches instead of an explicit OR instruction with a > @@ -6102,31 +6115,27 @@ > return Op; > } > > -SDValue X86TargetLowering::LowerXADDO(SDValue Op, SelectionDAG &DAG, > - ISD::NodeType NTy) { > -#if 0 > - // FIXME: Lowering XADDO should use BRCOND as well. > +SDValue X86TargetLowering::LowerXADDO(SDValue Op, SelectionDAG > &DAG) { > + // Lower the "add with overflow" instruction into a regular "add" > plus a > + // "setcc" instruction that checks the overflow flag. The > "brcond" lowering > + // looks for this combo and may remove the "setcc" instruction if > the "setcc" > + // has only one use. > SDNode *N = Op.getNode(); > + SDValue LHS = N->getOperand(0); > + SDValue RHS = N->getOperand(1); > > - for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); > I != E; ++I) { > - SDNode *UseNode = *I; > + // Also sets EFLAGS. > + SDVTList VTs = DAG.getVTList(N->getValueType(0), MVT::i32); > + SDValue Sum = DAG.getNode(ISD::ADD, VTs, LHS, RHS); > + > + SDValue SetCC = > + DAG.getNode(X86ISD::SETCC, N->getValueType(1), > + DAG.getConstant((Op.getOpcode() == ISD::SADDO) ? > + X86::COND_O : X86::COND_C, > + MVT::i32), SDValue(Sum.getNode(), > 1)); > > - if (UseNode->getOpcode() == ISD::BRCOND) { > - // Lower a branch on the overflow/carry flag into a "JO"/"JC" > - // instruction. Convert the addition into an actual addition, > not just a > - // pseudo node. > - SDValue LHS = N->getOperand(0); > - SDValue RHS = N->getOperand(1); > - SDValue Sum = DAG.getNode(ISD::ADD, LHS.getValueType(), LHS, > RHS); > - > - SDValue Ops[] = { UseNode->getOperand(2), UseNode- > >getOperand(0) }; > - DAG.SelectNodeTo(UseNode, (NTy == ISD::SADDO) ? X86::JO : > X86::JC, > - MVT::Other, Ops, 2); > - return Sum; > - } > - } > -#endif > - return SDValue(); > + DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1), SetCC); > + return Sum; > } > > SDValue X86TargetLowering::LowerCMP_SWAP(SDValue Op, SelectionDAG > &DAG) { > @@ -6143,7 +6152,7 @@ > assert(Subtarget->is64Bit() && "Node not type legal!"); > Reg = X86::RAX; size = 8; > break; > - }; > + } > SDValue cpIn = DAG.getCopyToReg(Op.getOperand(0), Reg, > Op.getOperand(2), SDValue()); > SDValue Ops[] = { cpIn.getValue(0), > @@ -6247,8 +6256,8 @@ > case ISD::FLT_ROUNDS_: return LowerFLT_ROUNDS_(Op, DAG); > case ISD::CTLZ: return LowerCTLZ(Op, DAG); > case ISD::CTTZ: return LowerCTTZ(Op, DAG); > - case ISD::SADDO: return LowerXADDO(Op, DAG, > ISD::SADDO); > - case ISD::UADDO: return LowerXADDO(Op, DAG, > ISD::UADDO); > + case ISD::SADDO: return LowerXADDO(Op, DAG); > + case ISD::UADDO: return LowerXADDO(Op, DAG); > case ISD::READCYCLECOUNTER: return LowerREADCYCLECOUNTER(Op, DAG); > } > } > > Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=60388&r1=60387&r2=60388&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) > +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Mon Dec 1 19:06:39 > 2008 > @@ -593,7 +593,7 @@ > SDValue LowerFLT_ROUNDS_(SDValue Op, SelectionDAG &DAG); > SDValue LowerCTLZ(SDValue Op, SelectionDAG &DAG); > SDValue LowerCTTZ(SDValue Op, SelectionDAG &DAG); > - SDValue LowerXADDO(SDValue Op, SelectionDAG &DAG, ISD::NodeType > NTy); > + SDValue LowerXADDO(SDValue Op, SelectionDAG &DAG); > > SDValue LowerCMP_SWAP(SDValue Op, SelectionDAG &DAG); > SDValue LowerLOAD_SUB(SDValue Op, SelectionDAG &DAG); > > Modified: llvm/trunk/test/CodeGen/X86/add-with-overflow.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/add-with-overflow.ll?rev=60388&r1=60387&r2=60388&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/X86/add-with-overflow.ll (original) > +++ llvm/trunk/test/CodeGen/X86/add-with-overflow.ll Mon Dec 1 > 19:06:39 2008 > @@ -1,6 +1,5 @@ > ; RUN: llvm-as < %s | llc -march=x86 | grep {jo} | count 1 > ; RUN: llvm-as < %s | llc -march=x86 | grep {jc} | count 1 > -; XFAIL: * > > @ok = internal constant [4 x i8] c"%d\0A\00" > @no = internal constant [4 x i8] c"no\0A\00" > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Wed Dec 3 01:43:06 2008 From: sabre at nondot.org (Chris Lattner) Date: Wed, 03 Dec 2008 07:43:06 -0000 Subject: [llvm-commits] [llvm] r60468 - /llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Message-ID: <200812030743.mB37h6Za028006@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 3 01:43:05 2008 New Revision: 60468 URL: http://llvm.org/viewvc/llvm-project?rev=60468&view=rev Log: fix assertion. Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp?rev=60468&r1=60467&r2=60468&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Wed Dec 3 01:43:05 2008 @@ -27,7 +27,7 @@ /// DeleteDeadBlock - Delete the specified block, which must have no /// predecessors. void llvm::DeleteDeadBlock(BasicBlock *BB) { - assert(pred_begin(BB) != pred_end(BB) && "Block is not dead!"); + assert(pred_begin(BB) == pred_end(BB) && "Block is not dead!"); TerminatorInst *BBTerm = BB->getTerminator(); // Loop through all of our successors and make sure they know that one From sabre at nondot.org Wed Dec 3 01:45:16 2008 From: sabre at nondot.org (Chris Lattner) Date: Wed, 03 Dec 2008 07:45:16 -0000 Subject: [llvm-commits] [llvm] r60469 - /llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Message-ID: <200812030745.mB37jGnn028067@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 3 01:45:15 2008 New Revision: 60469 URL: http://llvm.org/viewvc/llvm-project?rev=60469&view=rev Log: third time is the charm. Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp?rev=60469&r1=60468&r2=60469&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Wed Dec 3 01:45:15 2008 @@ -27,7 +27,9 @@ /// DeleteDeadBlock - Delete the specified block, which must have no /// predecessors. void llvm::DeleteDeadBlock(BasicBlock *BB) { - assert(pred_begin(BB) == pred_end(BB) && "Block is not dead!"); + assert((pred_begin(BB) == pred_end(BB) || + // Can delete self loop. + BB->getSinglePredecessor() == BB) && "Block is not dead!"); TerminatorInst *BBTerm = BB->getTerminator(); // Loop through all of our successors and make sure they know that one From sabre at nondot.org Wed Dec 3 01:48:08 2008 From: sabre at nondot.org (Chris Lattner) Date: Wed, 03 Dec 2008 07:48:08 -0000 Subject: [llvm-commits] [llvm] r60470 - in /llvm/trunk: lib/Transforms/Scalar/JumpThreading.cpp test/Transforms/JumpThreading/basic.ll Message-ID: <200812030748.mB37m8Ru028140@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 3 01:48:08 2008 New Revision: 60470 URL: http://llvm.org/viewvc/llvm-project?rev=60470&view=rev Log: Teach jump threading some more simple tricks: 1) have it fold "br undef", which does occur with surprising frequency as jump threading iterates. 2) teach j-t to delete dead blocks. This removes the successor edges, reducing the in-edges of other blocks, allowing recursive simplification. 3) Fold things like: br COND, BBX, BBY BBX: br COND, BBZ, BBW which also happens because jump threading iterates. Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp llvm/trunk/test/Transforms/JumpThreading/basic.ll Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=60470&r1=60469&r2=60470&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Wed Dec 3 01:48:08 2008 @@ -67,6 +67,7 @@ bool ProcessBlock(BasicBlock *BB); void ThreadEdge(BasicBlock *BB, BasicBlock *PredBB, BasicBlock *SuccBB); BasicBlock *FactorCommonPHIPreds(PHINode *PN, Constant *CstVal); + bool ProcessBranchOnDuplicateCond(BasicBlock *PredBB, BasicBlock *DestBB); bool ProcessJumpOnPHI(PHINode *PN); bool ProcessBranchOnLogical(Value *V, BasicBlock *BB, bool isAnd); @@ -93,9 +94,23 @@ while (AnotherIteration) { AnotherIteration = false; bool Changed = false; - for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) - while (ProcessBlock(I)) + for (Function::iterator I = F.begin(), E = F.end(); I != E;) { + BasicBlock *BB = I; + while (ProcessBlock(BB)) Changed = true; + + ++I; + + // If the block is trivially dead, zap it. This eliminates the successor + // edges which simplifies the CFG. + if (pred_begin(BB) == pred_end(BB) && + BB != &BB->getParent()->getEntryBlock()) { + DOUT << " JT: Deleting dead block '" << BB->getNameStart() + << "' with terminator: " << *BB->getTerminator(); + DeleteDeadBlock(BB); + Changed = true; + } + } AnotherIteration = Changed; EverChanged |= Changed; } @@ -209,29 +224,80 @@ return true; } + // If the terminator is branching on an undef, we can pick any of the + // successors to branch to. Since this is arbitrary, we pick the successor + // with the fewest predecessors. This should reduce the in-degree of the + // others. + if (isa(Condition)) { + TerminatorInst *BBTerm = BB->getTerminator(); + unsigned MinSucc = 0; + BasicBlock *TestBB = BBTerm->getSuccessor(MinSucc); + // Compute the successor with the minimum number of predecessors. + unsigned MinNumPreds = std::distance(pred_begin(TestBB), pred_end(TestBB)); + for (unsigned i = 1, e = BBTerm->getNumSuccessors(); i != e; ++i) { + TestBB = BBTerm->getSuccessor(i); + unsigned NumPreds = std::distance(pred_begin(TestBB), pred_end(TestBB)); + if (NumPreds < MinNumPreds) + MinSucc = i; + } + + // Fold the branch/switch. + for (unsigned i = 0, e = BBTerm->getNumSuccessors(); i != e; ++i) { + if (i == MinSucc) continue; + BBTerm->getSuccessor(i)->removePredecessor(BB); + } + + DOUT << " In block '" << BB->getNameStart() + << "' folding undef terminator: " << *BBTerm; + BranchInst::Create(BBTerm->getSuccessor(MinSucc), BBTerm); + BBTerm->eraseFromParent(); + return true; + } + + Instruction *CondInst = dyn_cast(Condition); + + // If the condition is an instruction defined in another block, see if a + // predecessor has the same condition: + // br COND, BBX, BBY + // BBX: + // br COND, BBZ, BBW + if (!Condition->hasOneUse() && // Multiple uses. + (CondInst == 0 || CondInst->getParent() != BB)) { // Non-local definition. + pred_iterator PI = pred_begin(BB), E = pred_end(BB); + if (isa(BB->getTerminator())) { + for (; PI != E; ++PI) + if (BranchInst *PBI = dyn_cast((*PI)->getTerminator())) + if (PBI->isConditional() && PBI->getCondition() == Condition && + ProcessBranchOnDuplicateCond(*PI, BB)) + return true; + } + } + // If there is only a single predecessor of this block, nothing to fold. if (BB->getSinglePredecessor()) return false; - + + // All the rest of our checks depend on the condition being an instruction. + if (CondInst == 0) + return false; + // See if this is a phi node in the current block. - PHINode *PN = dyn_cast(Condition); - if (PN && PN->getParent() == BB) - return ProcessJumpOnPHI(PN); + if (PHINode *PN = dyn_cast(CondInst)) + if (PN->getParent() == BB) + return ProcessJumpOnPHI(PN); // If this is a conditional branch whose condition is and/or of a phi, try to // simplify it. - if (BinaryOperator *CondI = dyn_cast(Condition)) { - if ((CondI->getOpcode() == Instruction::And || - CondI->getOpcode() == Instruction::Or) && - isa(BB->getTerminator()) && - ProcessBranchOnLogical(CondI, BB, - CondI->getOpcode() == Instruction::And)) - return true; - } + if ((CondInst->getOpcode() == Instruction::And || + CondInst->getOpcode() == Instruction::Or) && + isa(BB->getTerminator()) && + ProcessBranchOnLogical(CondInst, BB, + CondInst->getOpcode() == Instruction::And)) + return true; // If we have "br (phi != 42)" and the phi node has any constant values as // operands, we can thread through this block. - if (CmpInst *CondCmp = dyn_cast(Condition)) + if (CmpInst *CondCmp = dyn_cast(CondInst)) if (isa(CondCmp->getOperand(0)) && isa(CondCmp->getOperand(1)) && ProcessBranchOnCompare(CondCmp, BB)) @@ -244,7 +310,7 @@ // // This is particularly important because reg2mem inserts loads and stores all // over the place, and this blocks jump threading if we don't zap them. - Value *SimplifyValue = Condition; + Value *SimplifyValue = CondInst; if (CmpInst *CondCmp = dyn_cast(SimplifyValue)) if (isa(CondCmp->getOperand(1))) SimplifyValue = CondCmp->getOperand(0); @@ -259,6 +325,80 @@ return false; } +/// ProcessBranchOnDuplicateCond - We found a block and a predecessor of that +/// block that jump on exactly the same condition. This means that we almost +/// always know the direction of the edge in the DESTBB: +/// PREDBB: +/// br COND, DESTBB, BBY +/// DESTBB: +/// br COND, BBZ, BBW +/// +/// If DESTBB has multiple predecessors, we can't just constant fold the branch +/// in DESTBB, we have to thread over it. +bool JumpThreading::ProcessBranchOnDuplicateCond(BasicBlock *PredBB, + BasicBlock *BB) { + BranchInst *PredBI = cast(PredBB->getTerminator()); + + // If both successors of PredBB go to DESTBB, we don't know anything. We can + // fold the branch to an unconditional one, which allows other recursive + // simplifications. + bool BranchDir; + if (PredBI->getSuccessor(1) != BB) + BranchDir = true; + else if (PredBI->getSuccessor(0) != BB) + BranchDir = false; + else { + DOUT << " In block '" << PredBB->getNameStart() + << "' folding terminator: " << *PredBB->getTerminator(); + ++NumFolds; + ConstantFoldTerminator(PredBB); + return true; + } + + BranchInst *DestBI = cast(BB->getTerminator()); + + // If the dest block has one predecessor, just fix the branch condition to a + // constant and fold it. + if (BB->getSinglePredecessor()) { + DOUT << " In block '" << BB->getNameStart() + << "' folding condition to '" << BranchDir << "': " + << *BB->getTerminator(); + ++NumFolds; + DestBI->setCondition(ConstantInt::get(Type::Int1Ty, BranchDir)); + ConstantFoldTerminator(BB); + return true; + } + + // Otherwise we need to thread from PredBB to DestBB's successor which + // involves code duplication. Check to see if it is worth it. + unsigned JumpThreadCost = getJumpThreadDuplicationCost(BB); + if (JumpThreadCost > Threshold) { + DOUT << " Not threading BB '" << BB->getNameStart() + << "' - Cost is too high: " << JumpThreadCost << "\n"; + return false; + } + + // Next, figure out which successor we are threading to. + BasicBlock *SuccBB = DestBI->getSuccessor(!BranchDir); + + // If threading to the same block as we come from, we would infinite loop. + if (SuccBB == BB) { + DOUT << " Not threading BB '" << BB->getNameStart() + << "' - would thread to self!\n"; + return false; + } + + // And finally, do it! + DOUT << " Threading edge from '" << PredBB->getNameStart() << "' to '" + << SuccBB->getNameStart() << "' with cost: " << JumpThreadCost + << ", across block:\n " + << *BB << "\n"; + + ThreadEdge(BB, PredBB, SuccBB); + ++NumThreads; + return true; +} + /// SimplifyPartiallyRedundantLoad - If LI is an obviously partially redundant /// load instruction, eliminate it by replacing it with a PHI node. This is an /// important optimization that encourages jump threading, and needs to be run Modified: llvm/trunk/test/Transforms/JumpThreading/basic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/JumpThreading/basic.ll?rev=60470&r1=60469&r2=60470&view=diff ============================================================================== --- llvm/trunk/test/Transforms/JumpThreading/basic.ll (original) +++ llvm/trunk/test/Transforms/JumpThreading/basic.ll Wed Dec 3 01:48:08 2008 @@ -29,3 +29,25 @@ F2: ret i32 %B } + + +;; cond is known false on Entry -> F1 edge! +define i32 @test2(i1 %cond) { +Entry: + br i1 %cond, label %T1, label %F1 + +T1: + %v1 = call i32 @f1() + br label %Merge + +F1: + br i1 %cond, label %Merge, label %F2 + +Merge: + %B = phi i32 [47, %T1], [192, %F1] + ret i32 %B + +F2: + call void @f3() + ret i32 12 +} From sabre at nondot.org Wed Dec 3 01:48:27 2008 From: sabre at nondot.org (Chris Lattner) Date: Wed, 03 Dec 2008 07:48:27 -0000 Subject: [llvm-commits] [llvm] r60471 - /llvm/trunk/test/Transforms/JumpThreading/undef.ll Message-ID: <200812030748.mB37mRgp028164@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 3 01:48:27 2008 New Revision: 60471 URL: http://llvm.org/viewvc/llvm-project?rev=60471&view=rev Log: testcase for br undef folding. Added: llvm/trunk/test/Transforms/JumpThreading/undef.ll Added: llvm/trunk/test/Transforms/JumpThreading/undef.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/JumpThreading/undef.ll?rev=60471&view=auto ============================================================================== --- llvm/trunk/test/Transforms/JumpThreading/undef.ll (added) +++ llvm/trunk/test/Transforms/JumpThreading/undef.ll Wed Dec 3 01:48:27 2008 @@ -0,0 +1,12 @@ +; RUN: llvm-as < %s | opt -jump-threading | llvm-dis | not grep {br } +; RUN: llvm-as < %s | opt -jump-threading | llvm-dis | grep {ret i32} | count 1 + +define i32 @test(i1 %cond) { + br i1 undef, label %T1, label %F1 + +T1: + ret i32 42 + +F1: + ret i32 17 +} From isanbard at gmail.com Wed Dec 3 01:49:21 2008 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 03 Dec 2008 07:49:21 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60472 - /llvm-gcc-4.2/tags/Apple/llvmgcc42-2086/ Message-ID: <200812030749.mB37nLb8028208@zion.cs.uiuc.edu> Author: void Date: Wed Dec 3 01:49:21 2008 New Revision: 60472 URL: http://llvm.org/viewvc/llvm-project?rev=60472&view=rev Log: Deleting buggy tag. Removed: llvm-gcc-4.2/tags/Apple/llvmgcc42-2086/ From isanbard at gmail.com Wed Dec 3 01:50:14 2008 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 03 Dec 2008 07:50:14 -0000 Subject: [llvm-commits] [llvm] r60473 - /llvm/tags/Apple/llvmCore-2086/ Message-ID: <200812030750.mB37oEiP028246@zion.cs.uiuc.edu> Author: void Date: Wed Dec 3 01:50:14 2008 New Revision: 60473 URL: http://llvm.org/viewvc/llvm-project?rev=60473&view=rev Log: Deleting buggy tag. Removed: llvm/tags/Apple/llvmCore-2086/ From isanbard at gmail.com Wed Dec 3 01:52:34 2008 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 03 Dec 2008 07:52:34 -0000 Subject: [llvm-commits] [llvm] r60474 - /llvm/tags/Apple/llvmCore-2086/ Message-ID: <200812030752.mB37qY9n028314@zion.cs.uiuc.edu> Author: void Date: Wed Dec 3 01:52:34 2008 New Revision: 60474 URL: http://llvm.org/viewvc/llvm-project?rev=60474&view=rev Log: Creating llvmCore-2086 branch Added: llvm/tags/Apple/llvmCore-2086/ - copied from r60473, llvm/trunk/ From isanbard at gmail.com Wed Dec 3 01:52:43 2008 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 03 Dec 2008 07:52:43 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60475 - /llvm-gcc-4.2/tags/Apple/llvmgcc42-2086/ Message-ID: <200812030752.mB37qhIx028329@zion.cs.uiuc.edu> Author: void Date: Wed Dec 3 01:52:42 2008 New Revision: 60475 URL: http://llvm.org/viewvc/llvm-project?rev=60475&view=rev Log: Creating llvmgcc42-2086 branch Added: llvm-gcc-4.2/tags/Apple/llvmgcc42-2086/ - copied from r60474, llvm-gcc-4.2/trunk/ From evan.cheng at apple.com Wed Dec 3 02:20:45 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 03 Dec 2008 08:20:45 -0000 Subject: [llvm-commits] [llvm] r60476 - /llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-0.ll Message-ID: <200812030820.mB38KjnJ029095@zion.cs.uiuc.edu> Author: evancheng Date: Wed Dec 3 02:20:45 2008 New Revision: 60476 URL: http://llvm.org/viewvc/llvm-project?rev=60476&view=rev Log: Fix test. Modified: llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-0.ll Modified: llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-0.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-0.ll?rev=60476&r1=60475&r2=60476&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-0.ll (original) +++ llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-0.ll Wed Dec 3 02:20:45 2008 @@ -1,13 +1,11 @@ -; RUN: llvm-as < %s | llc | not grep pcmpeqd -; RUN: llvm-as < %s | llc -march=x86-64 | grep pcmpeqd | count 1 +; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin | not grep pcmpeqd +; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin | grep pcmpeqd | count 1 ; On x86-64, this testcase shouldn't need to spill the -1 value, ; so it should just use pcmpeqd to materialize an all-ones vector. ; On x86-32, there aren't enough registers, so an all-ones ; constant pool should be created so it can be folded. -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" -target triple = "i686-apple-cl.1.0" %struct.__ImageExecInfo = type <{ <4 x i32>, <4 x float>, <2 x i64>, i8*, i8*, i8*, i32, i32, i32, i32, i32 }> %struct._cl_image_format_t = type <{ i32, i32, i32 }> %struct._image2d_t = type <{ i8*, %struct._cl_image_format_t, i32, i32, i32, i32, i32, i32 }> From isanbard at gmail.com Wed Dec 3 02:31:26 2008 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 3 Dec 2008 00:31:26 -0800 Subject: [llvm-commits] [llvm] r60388 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h test/CodeGen/X86/add-with-overflow.ll In-Reply-To: <422E6392-715E-49C0-9D13-491A2CCDA070@apple.com> References: <200812020106.mB216dUK025251@zion.cs.uiuc.edu> <422E6392-715E-49C0-9D13-491A2CCDA070@apple.com> Message-ID: On Dec 2, 2008, at 11:27 PM, Evan Cheng wrote: > On Dec 1, 2008, at 5:06 PM, Bill Wendling wrote: > >> Author: void >> Date: Mon Dec 1 19:06:39 2008 >> New Revision: 60388 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=60388&view=rev >> Log: >> Second stab at target-dependent lowering of everyone's favorite >> nodes: [SU]ADDO >> >> - LowerXADDO lowers [SU]ADDO into an ADD with an implicit EFLAGS >> define. The >> EFLAGS are fed into a SETCC node which has the conditional COND_O >> or COND_C, >> depending on the type of ADDO requested. >> >> - LowerBRCOND now recognizes if it's coming from a SETCC node with >> COND_O or >> COND_C set. >> >> // If condition flag is set by a X86ISD::CMP, then use it as the >> condition >> // setting operand in place of the X86ISD::SETCC. >> @@ -5199,6 +5201,17 @@ >> Opc == X86ISD::UCOMI) { >> Cond = Cmp; >> addTest = false; >> + } else { >> + if (ConstantSDNode *CSDN = >> dyn_cast(CC.getNode())) { > > Is it possible for CC not to be a constsdnode here? Should it be an > assertion instead? > I'll make it a cast<>() instead. -bw From isanbard at gmail.com Wed Dec 3 02:32:02 2008 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 03 Dec 2008 08:32:02 -0000 Subject: [llvm-commits] [llvm] r60477 - /llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200812030832.mB38W2uC029552@zion.cs.uiuc.edu> Author: void Date: Wed Dec 3 02:32:02 2008 New Revision: 60477 URL: http://llvm.org/viewvc/llvm-project?rev=60477&view=rev Log: CC should only be a ConstantSDNode at this point. Just use 'cast' instead of 'dyn_cast'. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=60477&r1=60476&r2=60477&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Dec 3 02:32:02 2008 @@ -5202,15 +5202,15 @@ Cond = Cmp; addTest = false; } else { - if (ConstantSDNode *CSDN = dyn_cast(CC.getNode())) { - switch (CSDN->getZExtValue()) { - default: break; - case X86::COND_O: - case X86::COND_C: - Cond = Cond.getNode()->getOperand(1); - addTest = false; - break; - } + ConstantSDNode *CSDN = cast(CC.getNode()); + + switch (CSDN->getZExtValue()) { + default: break; + case X86::COND_O: + case X86::COND_C: + Cond = Cond.getNode()->getOperand(1); + addTest = false; + break; } } // Also, recognize the pattern generated by an FCMP_UNE. We can emit From evan.cheng at apple.com Wed Dec 3 02:38:44 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 03 Dec 2008 08:38:44 -0000 Subject: [llvm-commits] [llvm] r60478 - /llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200812030838.mB38cjdR030110@zion.cs.uiuc.edu> Author: evancheng Date: Wed Dec 3 02:38:43 2008 New Revision: 60478 URL: http://llvm.org/viewvc/llvm-project?rev=60478&view=rev Log: Refactor code. No functionality change. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=60478&r1=60477&r2=60478&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Dec 3 02:38:43 2008 @@ -5130,6 +5130,11 @@ return Result; } +// isX86LogicalCmp - Return true if opcode is a X86 logical comparison. +static bool isX86LogicalCmp(unsigned Opc) { + return Opc == X86ISD::CMP || Opc == X86ISD::COMI || Opc == X86ISD::UCOMI; +} + SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) { bool addTest = true; SDValue Cond = Op.getOperand(0); @@ -5152,9 +5157,7 @@ !isScalarFPTypeInSSEReg(VT)) // FPStack? IllegalFPCMov = !hasFPCMov(cast(CC)->getSExtValue()); - if ((Opc == X86ISD::CMP || - Opc == X86ISD::COMI || - Opc == X86ISD::UCOMI) && !IllegalFPCMov) { + if (isX86LogicalCmp(Opc) && !IllegalFPCMov) { Cond = Cmp; addTest = false; } @@ -5177,6 +5180,19 @@ return DAG.getNode(X86ISD::CMOV, VTs, 2, &Ops[0], Ops.size()); } +// isAndOrOfSingleUseSetCCs - Return true if node is an ISD::AND or +// ISD::OR of two X86ISD::SETCC nodes each of which has no other use apart +// from the AND / OR. +static bool isAndOrOfSetCCs(SDValue Op, unsigned &Opc) { + Opc = Op.getOpcode(); + if (Opc != ISD::OR && Opc != ISD::AND) + return false; + return (Op.getOperand(0).getOpcode() == X86ISD::SETCC && + Op.getOperand(0).hasOneUse() && + Op.getOperand(1).getOpcode() == X86ISD::SETCC && + Op.getOperand(1).hasOneUse()); +} + SDValue X86TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) { bool addTest = true; SDValue Chain = Op.getOperand(0); @@ -5196,86 +5212,73 @@ SDValue Cmp = Cond.getOperand(1); unsigned Opc = Cmp.getOpcode(); - if (Opc == X86ISD::CMP || - Opc == X86ISD::COMI || - Opc == X86ISD::UCOMI) { + if (isX86LogicalCmp(Opc)) { Cond = Cmp; addTest = false; } else { - ConstantSDNode *CSDN = cast(CC.getNode()); - - switch (CSDN->getZExtValue()) { + switch (cast(CC)->getZExtValue()) { default: break; case X86::COND_O: case X86::COND_C: + // These can only come from an arithmetic instruction with overflow, e.g. + // SADDO, UADDO. Cond = Cond.getNode()->getOperand(1); addTest = false; break; } } - // Also, recognize the pattern generated by an FCMP_UNE. We can emit - // two branches instead of an explicit OR instruction with a - // separate test. - } else if (Cond.getOpcode() == ISD::OR && - Cond.hasOneUse() && - Cond.getOperand(0).getOpcode() == X86ISD::SETCC && - Cond.getOperand(0).hasOneUse() && - Cond.getOperand(1).getOpcode() == X86ISD::SETCC && - Cond.getOperand(1).hasOneUse()) { - SDValue Cmp = Cond.getOperand(0).getOperand(1); - unsigned Opc = Cmp.getOpcode(); - if (Cmp == Cond.getOperand(1).getOperand(1) && - (Opc == X86ISD::CMP || - Opc == X86ISD::COMI || - Opc == X86ISD::UCOMI)) { - CC = Cond.getOperand(0).getOperand(0); - Chain = DAG.getNode(X86ISD::BRCOND, Op.getValueType(), - Chain, Dest, CC, Cmp); - CC = Cond.getOperand(1).getOperand(0); - Cond = Cmp; - addTest = false; - } - // Also, recognize the pattern generated by an FCMP_OEQ. We can emit - // two branches instead of an explicit AND instruction with a - // separate test. However, we only do this if this block doesn't - // have a fall-through edge, because this requires an explicit - // jmp when the condition is false. - } else if (Cond.getOpcode() == ISD::AND && - Cond.hasOneUse() && - Cond.getOperand(0).getOpcode() == X86ISD::SETCC && - Cond.getOperand(0).hasOneUse() && - Cond.getOperand(1).getOpcode() == X86ISD::SETCC && - Cond.getOperand(1).hasOneUse()) { - SDValue Cmp = Cond.getOperand(0).getOperand(1); - unsigned Opc = Cmp.getOpcode(); - if (Cmp == Cond.getOperand(1).getOperand(1) && - (Opc == X86ISD::CMP || - Opc == X86ISD::COMI || - Opc == X86ISD::UCOMI) && - Op.getNode()->hasOneUse()) { - X86::CondCode CCode = - (X86::CondCode)Cond.getOperand(0).getConstantOperandVal(0); - CCode = X86::GetOppositeBranchCondition(CCode); - CC = DAG.getConstant(CCode, MVT::i8); - SDValue User = SDValue(*Op.getNode()->use_begin(), 0); - // Look for an unconditional branch following this conditional branch. - // We need this because we need to reverse the successors in order - // to implement FCMP_OEQ. - if (User.getOpcode() == ISD::BR) { - SDValue FalseBB = User.getOperand(1); - SDValue NewBR = - DAG.UpdateNodeOperands(User, User.getOperand(0), Dest); - assert(NewBR == User); - Dest = FalseBB; - - Chain = DAG.getNode(X86ISD::BRCOND, Op.getValueType(), - Chain, Dest, CC, Cmp); - X86::CondCode CCode = - (X86::CondCode)Cond.getOperand(1).getConstantOperandVal(0); - CCode = X86::GetOppositeBranchCondition(CCode); - CC = DAG.getConstant(CCode, MVT::i8); - Cond = Cmp; - addTest = false; + } else { + unsigned CondOpc; + if (Cond.hasOneUse() && isAndOrOfSetCCs(Cond, CondOpc)) { + SDValue Cmp = Cond.getOperand(0).getOperand(1); + unsigned Opc = Cmp.getOpcode(); + if (CondOpc == ISD::OR) { + // Also, recognize the pattern generated by an FCMP_UNE. We can emit + // two branches instead of an explicit OR instruction with a + // separate test. + if (Cmp == Cond.getOperand(1).getOperand(1) && + isX86LogicalCmp(Opc)) { + CC = Cond.getOperand(0).getOperand(0); + Chain = DAG.getNode(X86ISD::BRCOND, Op.getValueType(), + Chain, Dest, CC, Cmp); + CC = Cond.getOperand(1).getOperand(0); + Cond = Cmp; + addTest = false; + } + } else { // ISD::AND + // Also, recognize the pattern generated by an FCMP_OEQ. We can emit + // two branches instead of an explicit AND instruction with a + // separate test. However, we only do this if this block doesn't + // have a fall-through edge, because this requires an explicit + // jmp when the condition is false. + if (Cmp == Cond.getOperand(1).getOperand(1) && + isX86LogicalCmp(Opc) && + Op.getNode()->hasOneUse()) { + X86::CondCode CCode = + (X86::CondCode)Cond.getOperand(0).getConstantOperandVal(0); + CCode = X86::GetOppositeBranchCondition(CCode); + CC = DAG.getConstant(CCode, MVT::i8); + SDValue User = SDValue(*Op.getNode()->use_begin(), 0); + // Look for an unconditional branch following this conditional branch. + // We need this because we need to reverse the successors in order + // to implement FCMP_OEQ. + if (User.getOpcode() == ISD::BR) { + SDValue FalseBB = User.getOperand(1); + SDValue NewBR = + DAG.UpdateNodeOperands(User, User.getOperand(0), Dest); + assert(NewBR == User); + Dest = FalseBB; + + Chain = DAG.getNode(X86ISD::BRCOND, Op.getValueType(), + Chain, Dest, CC, Cmp); + X86::CondCode CCode = + (X86::CondCode)Cond.getOperand(1).getConstantOperandVal(0); + CCode = X86::GetOppositeBranchCondition(CCode); + CC = DAG.getConstant(CCode, MVT::i8); + Cond = Cmp; + addTest = false; + } + } } } } From richard at xmos.com Wed Dec 3 04:59:19 2008 From: richard at xmos.com (Richard Osborne) Date: Wed, 03 Dec 2008 10:59:19 -0000 Subject: [llvm-commits] [llvm] r60479 - in /llvm/trunk: lib/Target/XCore/XCoreISelLowering.cpp lib/Target/XCore/XCoreInstrInfo.td test/CodeGen/XCore/trap.ll Message-ID: <200812031059.mB3AxJMV011346@zion.cs.uiuc.edu> Author: friedgold Date: Wed Dec 3 04:59:16 2008 New Revision: 60479 URL: http://llvm.org/viewvc/llvm-project?rev=60479&view=rev Log: Add support for ISD::TRAP to the XCore backend Added: llvm/trunk/test/CodeGen/XCore/trap.ll Modified: llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td Modified: llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp?rev=60479&r1=60478&r2=60479&view=diff ============================================================================== --- llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp (original) +++ llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp Wed Dec 3 04:59:16 2008 @@ -106,6 +106,8 @@ setOperationAction(ISD::ROTL , MVT::i32, Expand); setOperationAction(ISD::ROTR , MVT::i32, Expand); + setOperationAction(ISD::TRAP, MVT::Other, Legal); + // Expand jump tables for now setOperationAction(ISD::BR_JT, MVT::Other, Expand); setOperationAction(ISD::JumpTable, MVT::i32, Custom); Modified: llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td?rev=60479&r1=60478&r2=60479&view=diff ============================================================================== --- llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td (original) +++ llvm/trunk/lib/Target/XCore/XCoreInstrInfo.td Wed Dec 3 04:59:16 2008 @@ -762,7 +762,7 @@ // One operand short // TODO edu, eeu, waitet, waitef, freer, tstart, msync, mjoin, syncr, clrtp -// bru, setdp, setcp, setv, setev, kcall, ecallt, ecallf +// bru, setdp, setcp, setv, setev, kcall // dgetreg let isBranch=1, isIndirectBranch=1, isTerminator=1 in def BAU_1r : _F1R<(outs), (ins GRRegs:$addr), @@ -774,6 +774,16 @@ "set sp, $src", []>; +let isBarrier = 1, hasCtrlDep = 1 in +def ECALLT_1r : _F1R<(outs), (ins GRRegs:$src), + "ecallt $src", + []>; + +let isBarrier = 1, hasCtrlDep = 1 in +def ECALLF_1r : _F1R<(outs), (ins GRRegs:$src), + "ecallf $src", + []>; + let isCall=1, // All calls clobber the the link register and the non-callee-saved registers: Defs = [R0, R1, R2, R3, R11, LR] in { @@ -852,6 +862,9 @@ /// cttz def : Pat<(cttz GRRegs:$src), (CLZ_l2r (BITREV_l2r GRRegs:$src))>; +/// trap +def : Pat<(trap), (ECALLF_1r (LDC_ru6 0))>; + /// /// branch patterns /// Added: llvm/trunk/test/CodeGen/XCore/trap.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/XCore/trap.ll?rev=60479&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/XCore/trap.ll (added) +++ llvm/trunk/test/CodeGen/XCore/trap.ll Wed Dec 3 04:59:16 2008 @@ -0,0 +1,11 @@ +; RUN: llvm-as < %s | llc -march=xcore > %t1.s +; RUN: grep "ecallf" %t1.s | count 1 +; RUN: grep "ldc" %t1.s | count 1 +define i32 @test() noreturn nounwind { +entry: + tail call void @llvm.trap( ) + unreachable +} + +declare void @llvm.trap() nounwind + From rafael.espindola at gmail.com Wed Dec 3 05:01:38 2008 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Wed, 03 Dec 2008 11:01:38 -0000 Subject: [llvm-commits] [llvm] r60480 - in /llvm/trunk: include/llvm/Target/TargetAsmInfo.h lib/CodeGen/AsmPrinter/AsmPrinter.cpp lib/Target/ARM/ARMTargetAsmInfo.cpp lib/Target/PowerPC/PPCTargetAsmInfo.cpp lib/Target/TargetAsmInfo.cpp lib/Target/X86/X86TargetAsmInfo.cpp Message-ID: <200812031101.mB3B1cNL011423@zion.cs.uiuc.edu> Author: rafael Date: Wed Dec 3 05:01:37 2008 New Revision: 60480 URL: http://llvm.org/viewvc/llvm-project?rev=60480&view=rev Log: Fix bug 3140. Print a single parameter .file directive if we have an ELF target. Modified: llvm/trunk/include/llvm/Target/TargetAsmInfo.h llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp llvm/trunk/lib/Target/ARM/ARMTargetAsmInfo.cpp llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp llvm/trunk/lib/Target/TargetAsmInfo.cpp llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp Modified: llvm/trunk/include/llvm/Target/TargetAsmInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetAsmInfo.h?rev=60480&r1=60479&r2=60480&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetAsmInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetAsmInfo.h Wed Dec 3 05:01:37 2008 @@ -390,7 +390,11 @@ /// HasDotTypeDotSizeDirective - True if the target has .type and .size /// directives, this is true for most ELF targets. bool HasDotTypeDotSizeDirective; // Defaults to true. - + + /// HasSingleParameterDotFile - True if the target has a single parameter + /// .file directive, this is true for ELF targets. + bool HasSingleParameterDotFile; // Defaults to true. + /// UsedDirective - This directive, if non-null, is used to declare a global /// as being used somehow that the assembler can't see. This prevents dead /// code elimination on some targets. @@ -765,6 +769,9 @@ bool hasDotTypeDotSizeDirective() const { return HasDotTypeDotSizeDirective; } + bool hasSingleParameterDotFile() const { + return HasSingleParameterDotFile; + } const char *getUsedDirective() const { return UsedDirective; } @@ -856,4 +863,3 @@ } #endif - Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=60480&r1=60479&r2=60480&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Wed Dec 3 05:01:37 2008 @@ -142,6 +142,14 @@ GCModuleInfo *MI = getAnalysisToUpdate(); assert(MI && "AsmPrinter didn't require GCModuleInfo?"); + + if (TAI->hasSingleParameterDotFile()) { + /* Very minimal debug info. It is ignored if we emit actual + debug info. If we don't, this at helps the user find where + a function came from. */ + O << "\t.file\t\"" << M.getModuleIdentifier() << "\"\n"; + } + for (GCModuleInfo::iterator I = MI->begin(), E = MI->end(); I != E; ++I) if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*I)) MP->beginAssembly(O, *this, *TAI); Modified: llvm/trunk/lib/Target/ARM/ARMTargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMTargetAsmInfo.cpp?rev=60480&r1=60479&r2=60480&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMTargetAsmInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMTargetAsmInfo.cpp Wed Dec 3 05:01:37 2008 @@ -61,6 +61,7 @@ JumpTableDataSection = ".const"; CStringSection = "\t.cstring"; HasDotTypeDotSizeDirective = false; + HasSingleParameterDotFile = false; NeedsIndirectEncoding = true; if (TM.getRelocationModel() == Reloc::Static) { StaticCtorsSection = ".constructor"; Modified: llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp?rev=60480&r1=60479&r2=60480&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp Wed Dec 3 05:01:37 2008 @@ -37,6 +37,7 @@ StaticCtorsSection = ".mod_init_func"; StaticDtorsSection = ".mod_term_func"; } + HasSingleParameterDotFile = false; SwitchToSectionDirective = "\t.section "; UsedDirective = "\t.no_dead_strip\t"; WeakDefDirective = "\t.weak_definition "; Modified: llvm/trunk/lib/Target/TargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetAsmInfo.cpp?rev=60480&r1=60479&r2=60480&view=diff ============================================================================== --- llvm/trunk/lib/Target/TargetAsmInfo.cpp (original) +++ llvm/trunk/lib/Target/TargetAsmInfo.cpp Wed Dec 3 05:01:37 2008 @@ -85,6 +85,7 @@ COMMDirective = "\t.comm\t"; COMMDirectiveTakesAlignment = true; HasDotTypeDotSizeDirective = true; + HasSingleParameterDotFile = true; UsedDirective = 0; WeakRefDirective = 0; WeakDefDirective = 0; Modified: llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp?rev=60480&r1=60479&r2=60480&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp Wed Dec 3 05:01:37 2008 @@ -69,6 +69,7 @@ // Leopard and above support aligned common symbols. COMMDirectiveTakesAlignment = (Subtarget->getDarwinVers() >= 9); HasDotTypeDotSizeDirective = false; + HasSingleParameterDotFile = false; if (TM.getRelocationModel() == Reloc::Static) { StaticCtorsSection = ".constructor"; StaticDtorsSection = ".destructor"; @@ -221,6 +222,7 @@ LCOMMDirective = "\t.lcomm\t"; COMMDirectiveTakesAlignment = false; HasDotTypeDotSizeDirective = false; + HasSingleParameterDotFile = false; StaticCtorsSection = "\t.section .ctors,\"aw\""; StaticDtorsSection = "\t.section .dtors,\"aw\""; HiddenDirective = NULL; @@ -335,6 +337,7 @@ Data32bitsDirective = "\tdd\t"; Data64bitsDirective = "\tdq\t"; HasDotTypeDotSizeDirective = false; + HasSingleParameterDotFile = false; TextSection = getUnnamedSection("_text", SectionFlags::Code); DataSection = getUnnamedSection("_data", SectionFlags::Writeable); From baldrick at free.fr Wed Dec 3 02:48:10 2008 From: baldrick at free.fr (Duncan Sands) Date: Wed, 3 Dec 2008 09:48:10 +0100 Subject: [llvm-commits] [llvm] r60443 - in /llvm/trunk: lib/CodeGen/SelectionDAG/LegalizeTypes.cpp test/CodeGen/PowerPC/2008-12-02-LegalizeTypeAssert.ll In-Reply-To: <200812022157.mB2LvEl9010483@zion.cs.uiuc.edu> References: <200812022157.mB2LvEl9010483@zion.cs.uiuc.edu> Message-ID: <200812030948.10724.baldrick@free.fr> Hi Evan, > Duncan, please take a look. Thanks. this sounds similar to some other problems I'm looking into (PR3117). I will take a look. Ciao, Duncan. From baldrick at free.fr Wed Dec 3 06:36:17 2008 From: baldrick at free.fr (Duncan Sands) Date: Wed, 03 Dec 2008 12:36:17 -0000 Subject: [llvm-commits] [llvm] r60482 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp Message-ID: <200812031236.mB3CaHLL014187@zion.cs.uiuc.edu> Author: baldrick Date: Wed Dec 3 06:36:16 2008 New Revision: 60482 URL: http://llvm.org/viewvc/llvm-project?rev=60482&view=rev Log: Only check that the result of the mapping was not a new node if the node was actually remapped. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp?rev=60482&r1=60481&r2=60482&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp Wed Dec 3 06:36:16 2008 @@ -385,6 +385,7 @@ // replaced with other values. RemapValue(I->second); N = I->second; + assert(N.getNode()->getNodeId() != NewNode && "Mapped to unanalyzed node!"); } } From anton at korobeynikov.info Wed Dec 3 06:45:41 2008 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Wed, 3 Dec 2008 15:45:41 +0300 Subject: [llvm-commits] [llvm] r60480 - in /llvm/trunk: include/llvm/Target/TargetAsmInfo.h lib/CodeGen/AsmPrinter/AsmPrinter.cpp lib/Target/ARM/ARMTargetAsmInfo.cpp lib/Target/PowerPC/PPCTargetAsmInfo.cpp lib/Target/TargetAsmInfo.cpp lib/Target/X86/X86Ta Message-ID: Hi, Rafael > + HasSingleParameterDotFile = false; Why don't put this into DarwinTargetAsmInfo? Then it will be applied to all darwin'ish targets. -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University From gohman at apple.com Wed Dec 3 11:11:05 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 03 Dec 2008 17:11:05 -0000 Subject: [llvm-commits] [llvm] r60484 - /llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Message-ID: <200812031711.mB3HB7ht022905@zion.cs.uiuc.edu> Author: djg Date: Wed Dec 3 11:10:41 2008 New Revision: 60484 URL: http://llvm.org/viewvc/llvm-project?rev=60484&view=rev Log: Update a comment. Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=60484&r1=60483&r2=60484&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Wed Dec 3 11:10:41 2008 @@ -380,9 +380,10 @@ SDValue &Base, SDValue &Offset){ if (N.getOpcode() != ISD::ADD) { Base = N; - // We must materialize a zero in a reg! Returning an constant here won't - // work since its node is -1 so it won't get added to the selection queue. - // Explicitly issue a tMOVri8 node! + // We must materialize a zero in a reg! Returning a constant here + // wouldn't work without additional code to position the node within + // ISel's topological ordering in a place where ISel will process it + // normally. Instead, just explicitly issue a tMOVri8 node! Offset = SDValue(CurDAG->getTargetNode(ARM::tMOVi8, MVT::i32, CurDAG->getTargetConstant(0, MVT::i32)), 0); return true; From rafael.espindola at gmail.com Wed Dec 3 11:15:07 2008 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Wed, 03 Dec 2008 17:15:07 -0000 Subject: [llvm-commits] [llvm] r60485 - in /llvm/trunk/test/CodeGen/CellSPU: call_indirect.ll fdiv.ll immed32.ll immed64.ll vec_const.ll vecinsert.ll Message-ID: <200812031715.mB3HF8MF023057@zion.cs.uiuc.edu> Author: rafael Date: Wed Dec 3 11:14:56 2008 New Revision: 60485 URL: http://llvm.org/viewvc/llvm-project?rev=60485&view=rev Log: Fix some tests. The grep for "il" was matching "file". Modified: llvm/trunk/test/CodeGen/CellSPU/call_indirect.ll llvm/trunk/test/CodeGen/CellSPU/fdiv.ll llvm/trunk/test/CodeGen/CellSPU/immed32.ll llvm/trunk/test/CodeGen/CellSPU/immed64.ll llvm/trunk/test/CodeGen/CellSPU/vec_const.ll llvm/trunk/test/CodeGen/CellSPU/vecinsert.ll Modified: llvm/trunk/test/CodeGen/CellSPU/call_indirect.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/call_indirect.ll?rev=60485&r1=60484&r2=60485&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/call_indirect.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/call_indirect.ll Wed Dec 3 11:14:56 2008 @@ -11,7 +11,7 @@ ; RUN: grep iohl %t2.s | count 2 ; RUN: grep rotqby %t2.s | count 6 ; RUN: grep lqd %t2.s | count 18 -; RUN: grep il %t2.s | count 2 +; RUN: grep ilhu %t2.s | count 2 ; RUN: grep ai %t2.s | count 9 ; RUN: grep dispatch_tab %t2.s | count 6 Modified: llvm/trunk/test/CodeGen/CellSPU/fdiv.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/fdiv.ll?rev=60485&r1=60484&r2=60485&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/fdiv.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/fdiv.ll Wed Dec 3 11:14:56 2008 @@ -1,6 +1,6 @@ ; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s ; RUN: grep frest %t1.s | count 2 -; RUN: grep fi %t1.s | count 2 +; RUN: grep -w fi %t1.s | count 2 ; RUN: grep fm %t1.s | count 4 ; RUN: grep fma %t1.s | count 2 ; RUN: grep fnms %t1.s | count 2 Modified: llvm/trunk/test/CodeGen/CellSPU/immed32.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/immed32.ll?rev=60485&r1=60484&r2=60485&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/immed32.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/immed32.ll Wed Dec 3 11:14:56 2008 @@ -1,7 +1,7 @@ ; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s ; RUN: grep ilhu %t1.s | count 8 ; RUN: grep iohl %t1.s | count 6 -; RUN: grep il %t1.s | count 11 +; RUN: grep -w il %t1.s | count 3 ; RUN: grep 16429 %t1.s | count 1 ; RUN: grep 63572 %t1.s | count 1 ; RUN: grep 128 %t1.s | count 1 Modified: llvm/trunk/test/CodeGen/CellSPU/immed64.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/immed64.ll?rev=60485&r1=60484&r2=60485&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/immed64.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/immed64.ll Wed Dec 3 11:14:56 2008 @@ -1,6 +1,8 @@ ; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s ; RUN: grep lqa %t1.s | count 13 -; RUN: grep il %t1.s | count 22 +; RUN: grep ilhu %t1.s | count 15 +; RUN: grep ila %t1.s | count 1 +; RUN: grep -w il %t1.s | count 6 ; RUN: grep shufb %t1.s | count 13 ; RUN: grep 65520 %t1.s | count 1 ; RUN: grep 43981 %t1.s | count 1 Modified: llvm/trunk/test/CodeGen/CellSPU/vec_const.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/vec_const.ll?rev=60485&r1=60484&r2=60485&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/vec_const.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/vec_const.ll Wed Dec 3 11:14:56 2008 @@ -1,8 +1,8 @@ ; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s ; RUN: llvm-as -o - %s | llc -march=cellspu -mattr=large_mem > %t2.s -; RUN: grep il %t1.s | count 16 +; RUN: grep -w il %t1.s | count 3 ; RUN: grep ilhu %t1.s | count 8 -; RUN: grep ilh %t1.s | count 13 +; RUN: grep -w ilh %t1.s | count 5 ; RUN: grep iohl %t1.s | count 7 ; RUN: grep lqa %t1.s | count 6 ; RUN: grep 24672 %t1.s | count 2 Modified: llvm/trunk/test/CodeGen/CellSPU/vecinsert.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/vecinsert.ll?rev=60485&r1=60484&r2=60485&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/vecinsert.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/vecinsert.ll Wed Dec 3 11:14:56 2008 @@ -2,8 +2,8 @@ ; RUN: grep cbd %t1.s | count 5 ; RUN: grep chd %t1.s | count 5 ; RUN: grep cwd %t1.s | count 10 -; RUN: grep il %t1.s | count 15 -; RUN: grep ilh %t1.s | count 10 +; RUN: grep -w il %t1.s | count 5 +; RUN: grep -w ilh %t1.s | count 6 ; RUN: grep iohl %t1.s | count 1 ; RUN: grep ilhu %t1.s | count 4 ; RUN: grep shufb %t1.s | count 26 From gohman at apple.com Wed Dec 3 12:11:46 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 03 Dec 2008 18:11:46 -0000 Subject: [llvm-commits] [llvm] r60486 - in /llvm/trunk: include/llvm/CodeGen/MachineFrameInfo.h include/llvm/CodeGen/MachineInstrBuilder.h lib/Target/X86/X86InstrBuilder.h Message-ID: <200812031811.mB3IBpTE025114@zion.cs.uiuc.edu> Author: djg Date: Wed Dec 3 12:11:40 2008 New Revision: 60486 URL: http://llvm.org/viewvc/llvm-project?rev=60486&view=rev Log: Extend X86's addFrameReference to add a MachineMemOperand for the frame reference. This will help post-RA scheduling determine that spills to distinct stack slots are independent. Modified: llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h llvm/trunk/include/llvm/CodeGen/MachineInstrBuilder.h llvm/trunk/lib/Target/X86/X86InstrBuilder.h Modified: llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h?rev=60486&r1=60485&r2=60486&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineFrameInfo.h Wed Dec 3 12:11:40 2008 @@ -99,7 +99,7 @@ // the function. This field has no meaning for a variable sized element. int64_t SPOffset; - StackObject(uint64_t Sz, unsigned Al, int64_t SP, bool IM = false) + StackObject(uint64_t Sz, unsigned Al, int64_t SP = 0, bool IM = false) : Size(Sz), Alignment(Al), isImmutable(IM), SPOffset(SP) {} }; @@ -355,7 +355,7 @@ /// int CreateStackObject(uint64_t Size, unsigned Alignment) { assert(Size != 0 && "Cannot allocate zero size stack objects!"); - Objects.push_back(StackObject(Size, Alignment, -1)); + Objects.push_back(StackObject(Size, Alignment)); return (int)Objects.size()-NumFixedObjects-1; } @@ -373,7 +373,7 @@ /// int CreateVariableSizedObject() { HasVarSizedObjects = true; - Objects.push_back(StackObject(0, 1, -1)); + Objects.push_back(StackObject(0, 1)); return (int)Objects.size()-NumFixedObjects-1; } Modified: llvm/trunk/include/llvm/CodeGen/MachineInstrBuilder.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineInstrBuilder.h?rev=60486&r1=60485&r2=60486&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineInstrBuilder.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineInstrBuilder.h Wed Dec 3 12:11:40 2008 @@ -89,6 +89,11 @@ MI->addOperand(MachineOperand::CreateES(FnName, Offset)); return *this; } + + const MachineInstrBuilder &addMemOperand(const MachineMemOperand &MMO) const { + MI->addMemOperand(*MI->getParent()->getParent(), MMO); + return *this; + } }; /// BuildMI - Builder interface. Specify how to create the initial instruction Modified: llvm/trunk/lib/Target/X86/X86InstrBuilder.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrBuilder.h?rev=60486&r1=60485&r2=60486&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrBuilder.h (original) +++ llvm/trunk/lib/Target/X86/X86InstrBuilder.h Wed Dec 3 12:11:40 2008 @@ -24,7 +24,9 @@ #ifndef X86INSTRBUILDER_H #define X86INSTRBUILDER_H +#include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/PseudoSourceValue.h" namespace llvm { @@ -109,7 +111,22 @@ /// inline const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset = 0) { - return MIB.addFrameIndex(FI).addImm(1).addReg(0).addImm(Offset); + MachineInstr *MI = MIB; + MachineFunction &MF = *MI->getParent()->getParent(); + MachineFrameInfo &MFI = *MF.getFrameInfo(); + const TargetInstrDesc &TID = MI->getDesc(); + unsigned Flags = 0; + if (TID.mayLoad()) + Flags |= MachineMemOperand::MOLoad; + if (TID.mayStore()) + Flags |= MachineMemOperand::MOStore; + MachineMemOperand MMO(PseudoSourceValue::getFixedStack(FI), + Flags, + MFI.getObjectOffset(FI) + Offset, + MFI.getObjectSize(FI), + MFI.getObjectAlignment(FI)); + return MIB.addFrameIndex(FI).addImm(1).addReg(0).addImm(Offset) + .addMemOperand(MMO); } /// addConstantPoolReference - This function is used to add a reference to the From gohman at apple.com Wed Dec 3 12:16:00 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 03 Dec 2008 18:16:00 -0000 Subject: [llvm-commits] [llvm] r60487 - in /llvm/trunk: docs/ include/llvm/Target/ lib/CodeGen/ lib/Target/ARM/ lib/Target/Alpha/ lib/Target/CellSPU/ lib/Target/IA64/ lib/Target/Mips/ lib/Target/PowerPC/ lib/Target/X86/ utils/TableGen/ Message-ID: <200812031816.mB3IG3eT025269@zion.cs.uiuc.edu> Author: djg Date: Wed Dec 3 12:15:48 2008 New Revision: 60487 URL: http://llvm.org/viewvc/llvm-project?rev=60487&view=rev Log: Rename isSimpleLoad to canFoldAsLoad, to better reflect its meaning. Modified: llvm/trunk/docs/TableGenFundamentals.html llvm/trunk/include/llvm/Target/Target.td llvm/trunk/include/llvm/Target/TargetInstrDesc.h llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp llvm/trunk/lib/Target/ARM/ARMInstrInfo.td llvm/trunk/lib/Target/ARM/ARMInstrThumb.td llvm/trunk/lib/Target/ARM/ARMInstrVFP.td llvm/trunk/lib/Target/Alpha/AlphaInstrFormats.td llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td llvm/trunk/lib/Target/IA64/IA64InstrInfo.td llvm/trunk/lib/Target/Mips/MipsInstrInfo.td llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td llvm/trunk/lib/Target/PowerPC/PPCInstrAltivec.td llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td llvm/trunk/lib/Target/X86/X86Instr64bit.td llvm/trunk/lib/Target/X86/X86InstrFPStack.td llvm/trunk/lib/Target/X86/X86InstrInfo.td llvm/trunk/lib/Target/X86/X86InstrMMX.td llvm/trunk/lib/Target/X86/X86InstrSSE.td llvm/trunk/utils/TableGen/CodeGenInstruction.cpp llvm/trunk/utils/TableGen/CodeGenInstruction.h llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Modified: llvm/trunk/docs/TableGenFundamentals.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/TableGenFundamentals.html?rev=60487&r1=60486&r2=60487&view=diff ============================================================================== --- llvm/trunk/docs/TableGenFundamentals.html (original) +++ llvm/trunk/docs/TableGenFundamentals.html Wed Dec 3 12:15:48 2008 @@ -138,7 +138,7 @@ bit isIndirectBranch = 0; bit isBarrier = 0; bit isCall = 0; - bit isSimpleLoad = 0; + bit canFoldAsLoad = 0; bit mayLoad = 0; bit mayStore = 0; bit isImplicitDef = 0; Modified: llvm/trunk/include/llvm/Target/Target.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=60487&r1=60486&r2=60487&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/Target.td (original) +++ llvm/trunk/include/llvm/Target/Target.td Wed Dec 3 12:15:48 2008 @@ -189,7 +189,7 @@ bit isIndirectBranch = 0; // Is this instruction an indirect branch? bit isBarrier = 0; // Can control flow fall through this instruction? bit isCall = 0; // Is this instruction a call instruction? - bit isSimpleLoad = 0; // Can this be folded as a memory operand? + bit canFoldAsLoad = 0; // Can this be folded as a simple memory operand? bit mayLoad = 0; // Is it possible for this inst to read memory? bit mayStore = 0; // Is it possible for this inst to write memory? bit isTwoAddress = 0; // Is this a two address instruction? Modified: llvm/trunk/include/llvm/Target/TargetInstrDesc.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrDesc.h?rev=60487&r1=60486&r2=60487&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetInstrDesc.h (original) +++ llvm/trunk/include/llvm/Target/TargetInstrDesc.h Wed Dec 3 12:15:48 2008 @@ -90,7 +90,7 @@ Predicable, NotDuplicable, DelaySlot, - SimpleLoad, + FoldableAsLoad, MayLoad, MayStore, UnmodeledSideEffects, @@ -301,7 +301,7 @@ return Flags & (1 << TID::DelaySlot); } - /// isSimpleLoad - Return true for instructions that can be folded as + /// canFoldAsLoad - Return true for instructions that can be folded as /// memory operands in other instructions. The most common use for this /// is instructions that are simple loads from memory that don't modify /// the loaded value in any way, but it can also be used for instructions @@ -309,8 +309,8 @@ /// on x86, to allow them to be folded when it is beneficial. /// This should only be set on instructions that return a value in their /// only virtual register definition. - bool isSimpleLoad() const { - return Flags & (1 << TID::SimpleLoad); + bool canFoldAsLoad() const { + return Flags & (1 << TID::FoldableAsLoad); } //===--------------------------------------------------------------------===// Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=60487&r1=60486&r2=60487&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Wed Dec 3 12:15:48 2008 @@ -1841,7 +1841,7 @@ int LdSlot = 0; bool isLoadSS = DefIsReMat && tii_->isLoadFromStackSlot(ReMatDefMI, LdSlot); bool isLoad = isLoadSS || - (DefIsReMat && (ReMatDefMI->getDesc().isSimpleLoad())); + (DefIsReMat && (ReMatDefMI->getDesc().canFoldAsLoad())); bool IsFirstRange = true; for (LiveInterval::Ranges::const_iterator I = li.ranges.begin(), E = li.ranges.end(); I != E; ++I) { @@ -1927,7 +1927,7 @@ int LdSlot = 0; bool isLoadSS = DefIsReMat && tii_->isLoadFromStackSlot(ReMatDefMI, LdSlot); bool isLoad = isLoadSS || - (DefIsReMat && ReMatDefMI->getDesc().isSimpleLoad()); + (DefIsReMat && ReMatDefMI->getDesc().canFoldAsLoad()); rewriteInstructionsForSpills(li, TrySplit, I, ReMatOrigDefMI, ReMatDefMI, Slot, LdSlot, isLoad, isLoadSS, DefIsReMat, CanDelete, vrm, rc, ReMatIds, loopInfo, @@ -2056,7 +2056,7 @@ int LdSlot = 0; bool isLoadSS = tii_->isLoadFromStackSlot(ReMatDefMI, LdSlot); // If the rematerializable def is a load, also try to fold it. - if (isLoadSS || ReMatDefMI->getDesc().isSimpleLoad()) + if (isLoadSS || ReMatDefMI->getDesc().canFoldAsLoad()) Folded = tryFoldMemoryOperand(MI, vrm, ReMatDefMI, index, Ops, isLoadSS, LdSlot, VReg); unsigned ImpUse = getReMatImplicitUse(li, ReMatDefMI); Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=60487&r1=60486&r2=60487&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Wed Dec 3 12:15:48 2008 @@ -479,7 +479,7 @@ [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>; let AddedComplexity = 10 in { -let isSimpleLoad = 1 in +let canFoldAsLoad = 1 in def PICLDR : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p), Pseudo, "${addr:label}:\n\tldr$p $dst, $addr", [(set GPR:$dst, (load addrmodepc:$addr))]>; @@ -614,13 +614,13 @@ // // Load -let isSimpleLoad = 1 in +let canFoldAsLoad = 1 in def LDR : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, "ldr", " $dst, $addr", [(set GPR:$dst, (load addrmode2:$addr))]>; // Special LDR for loads from non-pc-relative constpools. -let isSimpleLoad = 1, mayLoad = 1, isReMaterializable = 1 in +let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, "ldr", " $dst, $addr", []>; Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=60487&r1=60486&r2=60487&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Wed Dec 3 12:15:48 2008 @@ -192,7 +192,7 @@ // Load Store Instructions. // -let isSimpleLoad = 1 in +let canFoldAsLoad = 1 in def tLDR : TI4<(outs GPR:$dst), (ins t_addrmode_s4:$addr), "ldr $dst, $addr", [(set GPR:$dst, (load t_addrmode_s4:$addr))]>; @@ -213,25 +213,25 @@ "ldrsh $dst, $addr", [(set GPR:$dst, (sextloadi16 t_addrmode_rr:$addr))]>; -let isSimpleLoad = 1 in +let canFoldAsLoad = 1 in def tLDRspi : TIs<(outs GPR:$dst), (ins t_addrmode_sp:$addr), "ldr $dst, $addr", [(set GPR:$dst, (load t_addrmode_sp:$addr))]>; // Special instruction for restore. It cannot clobber condition register // when it's expanded by eliminateCallFramePseudoInstr(). -let isSimpleLoad = 1, mayLoad = 1 in +let canFoldAsLoad = 1, mayLoad = 1 in def tRestore : TIs<(outs GPR:$dst), (ins t_addrmode_sp:$addr), "ldr $dst, $addr", []>; // Load tconstpool -let isSimpleLoad = 1 in +let canFoldAsLoad = 1 in def tLDRpci : TIs<(outs GPR:$dst), (ins i32imm:$addr), "ldr $dst, $addr", [(set GPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>; // Special LDR for loads from non-pc-relative constpools. -let isSimpleLoad = 1, mayLoad = 1, isReMaterializable = 1 in +let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in def tLDRcp : TIs<(outs GPR:$dst), (ins i32imm:$addr), "ldr $dst, $addr", []>; Modified: llvm/trunk/lib/Target/ARM/ARMInstrVFP.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrVFP.td?rev=60487&r1=60486&r2=60487&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrVFP.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrVFP.td Wed Dec 3 12:15:48 2008 @@ -34,7 +34,7 @@ // Load / store Instructions. // -let isSimpleLoad = 1 in { +let canFoldAsLoad = 1 in { def FLDD : ADI5<0b1101, 0b01, (outs DPR:$dst), (ins addrmode5:$addr), "fldd", " $dst, $addr", [(set DPR:$dst, (load addrmode5:$addr))]>; @@ -42,7 +42,7 @@ def FLDS : ASI5<0b1101, 0b01, (outs SPR:$dst), (ins addrmode5:$addr), "flds", " $dst, $addr", [(set SPR:$dst, (load addrmode5:$addr))]>; -} // isSimpleLoad +} // canFoldAsLoad def FSTD : ADI5<0b1101, 0b00, (outs), (ins DPR:$src, addrmode5:$addr), "fstd", " $src, $addr", Modified: llvm/trunk/lib/Target/Alpha/AlphaInstrFormats.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaInstrFormats.td?rev=60487&r1=60486&r2=60487&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/AlphaInstrFormats.td (original) +++ llvm/trunk/lib/Target/Alpha/AlphaInstrFormats.td Wed Dec 3 12:15:48 2008 @@ -41,7 +41,7 @@ class MForm opcode, bit load, string asmstr, list pattern, InstrItinClass itin> : InstAlpha { let Pattern = pattern; - let isSimpleLoad = load; + let canFoldAsLoad = load; let Defs = [R28]; //We may use this for frame index calculations, so reserve it here bits<5> Ra; Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td?rev=60487&r1=60486&r2=60487&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td (original) +++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td Wed Dec 3 12:15:48 2008 @@ -47,7 +47,7 @@ // finally the X-form with the register-register. //===----------------------------------------------------------------------===// -let isSimpleLoad = 1 in { +let canFoldAsLoad = 1 in { class LoadDFormVec : RI10Form<0b00101100, (outs VECREG:$rT), (ins memri10:$src), "lqd\t$rT, $src", Modified: llvm/trunk/lib/Target/IA64/IA64InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/IA64/IA64InstrInfo.td?rev=60487&r1=60486&r2=60487&view=diff ============================================================================== --- llvm/trunk/lib/Target/IA64/IA64InstrInfo.td (original) +++ llvm/trunk/lib/Target/IA64/IA64InstrInfo.td Wed Dec 3 12:15:48 2008 @@ -546,7 +546,7 @@ "stf.spill [$dstPtr] = $value">, isM; } -let isSimpleLoad = 1 in { +let canFoldAsLoad = 1 in { def LD1 : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$srcPtr), "ld1 $dst = [$srcPtr]">, isM; def LD2 : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$srcPtr), Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.td?rev=60487&r1=60486&r2=60487&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrInfo.td (original) +++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.td Wed Dec 3 12:15:48 2008 @@ -224,7 +224,7 @@ [], IIAlu>; // Memory Load/Store -let isSimpleLoad = 1, hasDelaySlot = 1 in +let canFoldAsLoad = 1, hasDelaySlot = 1 in class LoadM op, string instr_asm, PatFrag OpNode>: FI< op, (outs CPURegs:$dst), Modified: llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td?rev=60487&r1=60486&r2=60487&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td (original) +++ llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td Wed Dec 3 12:15:48 2008 @@ -468,7 +468,7 @@ // Sign extending loads. -let isSimpleLoad = 1, PPC970_Unit = 2 in { +let canFoldAsLoad = 1, PPC970_Unit = 2 in { def LHA8: DForm_1<42, (outs G8RC:$rD), (ins memri:$src), "lha $rD, $src", LdStLHA, [(set G8RC:$rD, (sextloadi16 iaddr:$src))]>, @@ -498,7 +498,7 @@ } // Zero extending loads. -let isSimpleLoad = 1, PPC970_Unit = 2 in { +let canFoldAsLoad = 1, PPC970_Unit = 2 in { def LBZ8 : DForm_1<34, (outs G8RC:$rD), (ins memri:$src), "lbz $rD, $src", LdStGeneral, [(set G8RC:$rD, (zextloadi8 iaddr:$src))]>; @@ -539,7 +539,7 @@ // Full 8-byte loads. -let isSimpleLoad = 1, PPC970_Unit = 2 in { +let canFoldAsLoad = 1, PPC970_Unit = 2 in { def LD : DSForm_1<58, 0, (outs G8RC:$rD), (ins memrix:$src), "ld $rD, $src", LdStLD, [(set G8RC:$rD, (load ixaddr:$src))]>, isPPC64; Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrAltivec.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrAltivec.td?rev=60487&r1=60486&r2=60487&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCInstrAltivec.td (original) +++ llvm/trunk/lib/Target/PowerPC/PPCInstrAltivec.td Wed Dec 3 12:15:48 2008 @@ -199,7 +199,7 @@ "mtvscr $vB", LdStGeneral, [(int_ppc_altivec_mtvscr VRRC:$vB)]>; -let isSimpleLoad = 1, PPC970_Unit = 2 in { // Loads. +let canFoldAsLoad = 1, PPC970_Unit = 2 in { // Loads. def LVEBX: XForm_1<31, 7, (outs VRRC:$vD), (ins memrr:$src), "lvebx $vD, $src", LdStGeneral, [(set VRRC:$vD, (int_ppc_altivec_lvebx xoaddr:$src))]>; Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td?rev=60487&r1=60486&r2=60487&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td (original) +++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td Wed Dec 3 12:15:48 2008 @@ -659,7 +659,7 @@ // // Unindexed (r+i) Loads. -let isSimpleLoad = 1, PPC970_Unit = 2 in { +let canFoldAsLoad = 1, PPC970_Unit = 2 in { def LBZ : DForm_1<34, (outs GPRC:$rD), (ins memri:$src), "lbz $rD, $src", LdStGeneral, [(set GPRC:$rD, (zextloadi8 iaddr:$src))]>; @@ -718,7 +718,7 @@ // Indexed (r+r) Loads. // -let isSimpleLoad = 1, PPC970_Unit = 2 in { +let canFoldAsLoad = 1, PPC970_Unit = 2 in { def LBZX : XForm_1<31, 87, (outs GPRC:$rD), (ins memrr:$src), "lbzx $rD, $src", LdStGeneral, [(set GPRC:$rD, (zextloadi8 xaddr:$src))]>; Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Instr64bit.td?rev=60487&r1=60486&r2=60487&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Instr64bit.td (original) +++ llvm/trunk/lib/Target/X86/X86Instr64bit.td Wed Dec 3 12:15:48 2008 @@ -232,7 +232,7 @@ [(set GR64:$dst, i64immSExt32:$src)]>; } -let isSimpleLoad = 1 in +let canFoldAsLoad = 1 in def MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src), "mov{q}\t{$src, $dst|$dst, $src}", [(set GR64:$dst, (load addr:$src))]>; Modified: llvm/trunk/lib/Target/X86/X86InstrFPStack.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrFPStack.td?rev=60487&r1=60486&r2=60487&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrFPStack.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrFPStack.td Wed Dec 3 12:15:48 2008 @@ -342,7 +342,7 @@ "fcmovnu\t{$op, %st(0)|%ST(0), $op}">, DB; // Floating point loads & stores. -let isSimpleLoad = 1 in { +let canFoldAsLoad = 1 in { def LD_Fp32m : FpIf32<(outs RFP32:$dst), (ins f32mem:$src), ZeroArgFP, [(set RFP32:$dst, (loadf32 addr:$src))]>; let isReMaterializable = 1, mayHaveSideEffects = 1 in Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=60487&r1=60486&r2=60487&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Wed Dec 3 12:15:48 2008 @@ -677,7 +677,7 @@ "mov{l}\t{$src, $dst|$dst, $src}", [(store (i32 imm:$src), addr:$dst)]>; -let isSimpleLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in { +let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in { def MOV8rm : I<0x8A, MRMSrcMem, (outs GR8 :$dst), (ins i8mem :$src), "mov{b}\t{$src, $dst|$dst, $src}", [(set GR8:$dst, (load addr:$src))]>; @@ -2666,7 +2666,7 @@ "mov{l}\t{$src, $dst|$dst, $src}", []>; } // neverHasSideEffects -let isSimpleLoad = 1, mayLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in { +let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in { def MOV16_rm : I<0x8B, MRMSrcMem, (outs GR16_:$dst), (ins i16mem:$src), "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize; def MOV32_rm : I<0x8B, MRMSrcMem, (outs GR32_:$dst), (ins i32mem:$src), Modified: llvm/trunk/lib/Target/X86/X86InstrMMX.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrMMX.td?rev=60487&r1=60486&r2=60487&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrMMX.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrMMX.td Wed Dec 3 12:15:48 2008 @@ -146,7 +146,7 @@ def MMX_MOVD64rr : MMXI<0x6E, MRMSrcReg, (outs VR64:$dst), (ins GR32:$src), "movd\t{$src, $dst|$dst, $src}", [(set VR64:$dst, (v2i32 (scalar_to_vector GR32:$src)))]>; -let isSimpleLoad = 1, isReMaterializable = 1 in +let canFoldAsLoad = 1, isReMaterializable = 1 in def MMX_MOVD64rm : MMXI<0x6E, MRMSrcMem, (outs VR64:$dst), (ins i32mem:$src), "movd\t{$src, $dst|$dst, $src}", [(set VR64:$dst, (v2i32 (scalar_to_vector (loadi32 addr:$src))))]>; @@ -165,7 +165,7 @@ let neverHasSideEffects = 1 in def MMX_MOVQ64rr : MMXI<0x6F, MRMSrcReg, (outs VR64:$dst), (ins VR64:$src), "movq\t{$src, $dst|$dst, $src}", []>; -let isSimpleLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in +let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in def MMX_MOVQ64rm : MMXI<0x6F, MRMSrcMem, (outs VR64:$dst), (ins i64mem:$src), "movq\t{$src, $dst|$dst, $src}", [(set VR64:$dst, (load_mmx addr:$src))]>; Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=60487&r1=60486&r2=60487&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Wed Dec 3 12:15:48 2008 @@ -315,7 +315,7 @@ let neverHasSideEffects = 1 in def MOVSSrr : SSI<0x10, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src), "movss\t{$src, $dst|$dst, $src}", []>; -let isSimpleLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in +let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in def MOVSSrm : SSI<0x10, MRMSrcMem, (outs FR32:$dst), (ins f32mem:$src), "movss\t{$src, $dst|$dst, $src}", [(set FR32:$dst, (loadf32 addr:$src))]>; @@ -474,7 +474,7 @@ // Alias instruction to load FR32 from f128mem using movaps. Upper bits are // disregarded. -let isSimpleLoad = 1 in +let canFoldAsLoad = 1 in def FsMOVAPSrm : PSI<0x28, MRMSrcMem, (outs FR32:$dst), (ins f128mem:$src), "movaps\t{$src, $dst|$dst, $src}", [(set FR32:$dst, (alignedloadfsf32 addr:$src))]>; @@ -667,7 +667,7 @@ let neverHasSideEffects = 1 in def MOVAPSrr : PSI<0x28, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), "movaps\t{$src, $dst|$dst, $src}", []>; -let isSimpleLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in +let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in def MOVAPSrm : PSI<0x28, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src), "movaps\t{$src, $dst|$dst, $src}", [(set VR128:$dst, (alignedloadv4f32 addr:$src))]>; @@ -679,7 +679,7 @@ let neverHasSideEffects = 1 in def MOVUPSrr : PSI<0x10, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), "movups\t{$src, $dst|$dst, $src}", []>; -let isSimpleLoad = 1 in +let canFoldAsLoad = 1 in def MOVUPSrm : PSI<0x10, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src), "movups\t{$src, $dst|$dst, $src}", [(set VR128:$dst, (loadv4f32 addr:$src))]>; @@ -688,7 +688,7 @@ [(store (v4f32 VR128:$src), addr:$dst)]>; // Intrinsic forms of MOVUPS load and store -let isSimpleLoad = 1 in +let canFoldAsLoad = 1 in def MOVUPSrm_Int : PSI<0x10, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src), "movups\t{$src, $dst|$dst, $src}", [(set VR128:$dst, (int_x86_sse_loadu_ps addr:$src))]>; @@ -987,9 +987,9 @@ "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)]>; // Alias instructions that map zero vector to pxor / xorp* for sse. -// We set isSimpleLoad because this can be converted to a constant-pool +// We set canFoldAsLoad because this can be converted to a constant-pool // load of an all-zeros value if folding it would be beneficial. -let isReMaterializable = 1, isAsCheapAsAMove = 1, isSimpleLoad = 1 in +let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1 in def V_SET0 : PSI<0x57, MRMInitReg, (outs VR128:$dst), (ins), "xorps\t$dst, $dst", [(set VR128:$dst, (v4i32 immAllZerosV))]>; @@ -1063,7 +1063,7 @@ let neverHasSideEffects = 1 in def MOVSDrr : SDI<0x10, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src), "movsd\t{$src, $dst|$dst, $src}", []>; -let isSimpleLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in +let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in def MOVSDrm : SDI<0x10, MRMSrcMem, (outs FR64:$dst), (ins f64mem:$src), "movsd\t{$src, $dst|$dst, $src}", [(set FR64:$dst, (loadf64 addr:$src))]>; @@ -1215,7 +1215,7 @@ // Alias instruction to load FR64 from f128mem using movapd. Upper bits are // disregarded. -let isSimpleLoad = 1 in +let canFoldAsLoad = 1 in def FsMOVAPDrm : PDI<0x28, MRMSrcMem, (outs FR64:$dst), (ins f128mem:$src), "movapd\t{$src, $dst|$dst, $src}", [(set FR64:$dst, (alignedloadfsf64 addr:$src))]>; @@ -1410,7 +1410,7 @@ let neverHasSideEffects = 1 in def MOVAPDrr : PDI<0x28, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), "movapd\t{$src, $dst|$dst, $src}", []>; -let isSimpleLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in +let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in def MOVAPDrm : PDI<0x28, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src), "movapd\t{$src, $dst|$dst, $src}", [(set VR128:$dst, (alignedloadv2f64 addr:$src))]>; @@ -1422,7 +1422,7 @@ let neverHasSideEffects = 1 in def MOVUPDrr : PDI<0x10, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), "movupd\t{$src, $dst|$dst, $src}", []>; -let isSimpleLoad = 1 in +let canFoldAsLoad = 1 in def MOVUPDrm : PDI<0x10, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src), "movupd\t{$src, $dst|$dst, $src}", [(set VR128:$dst, (loadv2f64 addr:$src))]>; @@ -1790,7 +1790,7 @@ let neverHasSideEffects = 1 in def MOVDQArr : PDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src), "movdqa\t{$src, $dst|$dst, $src}", []>; -let isSimpleLoad = 1, mayLoad = 1 in +let canFoldAsLoad = 1, mayLoad = 1 in def MOVDQArm : PDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src), "movdqa\t{$src, $dst|$dst, $src}", [/*(set VR128:$dst, (alignedloadv2i64 addr:$src))*/]>; @@ -1798,7 +1798,7 @@ def MOVDQAmr : PDI<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src), "movdqa\t{$src, $dst|$dst, $src}", [/*(alignedstore (v2i64 VR128:$src), addr:$dst)*/]>; -let isSimpleLoad = 1, mayLoad = 1 in +let canFoldAsLoad = 1, mayLoad = 1 in def MOVDQUrm : I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src), "movdqu\t{$src, $dst|$dst, $src}", [/*(set VR128:$dst, (loadv2i64 addr:$src))*/]>, @@ -1810,7 +1810,7 @@ XS, Requires<[HasSSE2]>; // Intrinsic forms of MOVDQU load and store -let isSimpleLoad = 1 in +let canFoldAsLoad = 1 in def MOVDQUrm_Int : I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src), "movdqu\t{$src, $dst|$dst, $src}", [(set VR128:$dst, (int_x86_sse2_loadu_dq addr:$src))]>, @@ -2255,9 +2255,9 @@ (i8 1)), (MFENCE)>; // Alias instructions that map zero vector to pxor / xorp* for sse. -// We set isSimpleLoad because this can be converted to a constant-pool +// We set canFoldAsLoad because this can be converted to a constant-pool // load of an all-ones value if folding it would be beneficial. -let isReMaterializable = 1, isAsCheapAsAMove = 1, isSimpleLoad = 1 in +let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1 in def V_SETALLONES : PDI<0x76, MRMInitReg, (outs VR128:$dst), (ins), "pcmpeqd\t$dst, $dst", [(set VR128:$dst, (v4i32 immAllOnesV))]>; Modified: llvm/trunk/utils/TableGen/CodeGenInstruction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenInstruction.cpp?rev=60487&r1=60486&r2=60487&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenInstruction.cpp (original) +++ llvm/trunk/utils/TableGen/CodeGenInstruction.cpp Wed Dec 3 12:15:48 2008 @@ -84,7 +84,7 @@ isIndirectBranch = R->getValueAsBit("isIndirectBranch"); isBarrier = R->getValueAsBit("isBarrier"); isCall = R->getValueAsBit("isCall"); - isSimpleLoad = R->getValueAsBit("isSimpleLoad"); + canFoldAsLoad = R->getValueAsBit("canFoldAsLoad"); mayLoad = R->getValueAsBit("mayLoad"); mayStore = R->getValueAsBit("mayStore"); bool isTwoAddress = R->getValueAsBit("isTwoAddress"); Modified: llvm/trunk/utils/TableGen/CodeGenInstruction.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenInstruction.h?rev=60487&r1=60486&r2=60487&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/CodeGenInstruction.h (original) +++ llvm/trunk/utils/TableGen/CodeGenInstruction.h Wed Dec 3 12:15:48 2008 @@ -89,7 +89,7 @@ bool isIndirectBranch; bool isBarrier; bool isCall; - bool isSimpleLoad; + bool canFoldAsLoad; bool mayLoad, mayStore; bool isPredicable; bool isConvertibleToThreeAddress; Modified: llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp?rev=60487&r1=60486&r2=60487&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Wed Dec 3 12:15:48 2008 @@ -262,7 +262,7 @@ if (Inst.isBarrier) OS << "|(1< References: <200812030521.mB35LReU024052@zion.cs.uiuc.edu> <3D688597-4F63-43BA-9BEE-7D42EA15AA7D@apple.com> Message-ID: On Dec 2, 2008, at 11:20 PM, Evan Cheng wrote: > Hi Dan, > > You are changing the meaning of isSimpleLoad to something that's not > at all obvious form the name. Perhaps we should add a new > TargetInstrDesc flag (canChangeIntoSimpleLoad?). Ok, I just renamed isSimpleLoad to canFoldAsLoad, which I believe captures the new generalized meaning. > BranchFolding also > uses isSimpleLoad. That's already fixed. Dan From gohman at apple.com Wed Dec 3 12:43:31 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 03 Dec 2008 18:43:31 -0000 Subject: [llvm-commits] [llvm] r60488 - in /llvm/trunk: include/llvm/Target/ lib/CodeGen/ lib/Target/ARM/ lib/Target/Alpha/ lib/Target/CellSPU/ lib/Target/Mips/ lib/Target/PowerPC/ lib/Target/Sparc/ lib/Target/X86/ Message-ID: <200812031843.mB3Ihbka026265@zion.cs.uiuc.edu> Author: djg Date: Wed Dec 3 12:43:12 2008 New Revision: 60488 URL: http://llvm.org/viewvc/llvm-project?rev=60488&view=rev Log: Split foldMemoryOperand into public non-virtual and protected virtual parts, and add target-independent code to add/preserve MachineMemOperands. Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h llvm/trunk/lib/CodeGen/TargetInstrInfoImpl.cpp llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp llvm/trunk/lib/Target/ARM/ARMInstrInfo.h llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.cpp llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.h llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp llvm/trunk/lib/Target/Mips/MipsInstrInfo.h llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h llvm/trunk/lib/Target/Sparc/SparcInstrInfo.cpp llvm/trunk/lib/Target/Sparc/SparcInstrInfo.h llvm/trunk/lib/Target/X86/X86InstrInfo.cpp llvm/trunk/lib/Target/X86/X86InstrInfo.h Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrInfo.h?rev=60488&r1=60487&r2=60488&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetInstrInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetInstrInfo.h Wed Dec 3 12:43:12 2008 @@ -305,23 +305,41 @@ /// operand folded, otherwise NULL is returned. The client is responsible for /// removing the old instruction and adding the new one in the instruction /// stream. - virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, - MachineInstr* MI, - const SmallVectorImpl &Ops, - int FrameIndex) const { - return 0; - } + MachineInstr* foldMemoryOperand(MachineFunction &MF, + MachineInstr* MI, + const SmallVectorImpl &Ops, + int FrameIndex) const; /// foldMemoryOperand - Same as the previous version except it allows folding /// of any load and store from / to any address, not just from a specific /// stack slot. - virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, + MachineInstr* foldMemoryOperand(MachineFunction &MF, + MachineInstr* MI, + const SmallVectorImpl &Ops, + MachineInstr* LoadMI) const; + +protected: + /// foldMemoryOperandImpl - Target-dependent implementation for + /// foldMemoryOperand. Target-independent code in foldMemoryOperand will + /// take care of adding a MachineMemOperand to the newly created instruction. + virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, MachineInstr* MI, const SmallVectorImpl &Ops, - MachineInstr* LoadMI) const { + int FrameIndex) const { + return 0; + } + + /// foldMemoryOperandImpl - Target-dependent implementation for + /// foldMemoryOperand. Target-independent code in foldMemoryOperand will + /// take care of adding a MachineMemOperand to the newly created instruction. + virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr* MI, + const SmallVectorImpl &Ops, + MachineInstr* LoadMI) const { return 0; } +public: /// canFoldMemoryOperand - Returns true if the specified load / store is /// folding is possible. virtual Modified: llvm/trunk/lib/CodeGen/TargetInstrInfoImpl.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetInstrInfoImpl.cpp?rev=60488&r1=60487&r2=60488&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TargetInstrInfoImpl.cpp (original) +++ llvm/trunk/lib/CodeGen/TargetInstrInfoImpl.cpp Wed Dec 3 12:43:12 2008 @@ -14,8 +14,10 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/PseudoSourceValue.h" using namespace llvm; // commuteInstruction - The default implementation of this method just exchanges @@ -124,3 +126,69 @@ } return FnSize; } + +/// foldMemoryOperand - Attempt to fold a load or store of the specified stack +/// slot into the specified machine instruction for the specified operand(s). +/// If this is possible, a new instruction is returned with the specified +/// operand folded, otherwise NULL is returned. The client is responsible for +/// removing the old instruction and adding the new one in the instruction +/// stream. +MachineInstr* +TargetInstrInfo::foldMemoryOperand(MachineFunction &MF, + MachineInstr* MI, + const SmallVectorImpl &Ops, + int FrameIndex) const { + unsigned Flags = 0; + for (unsigned i = 0, e = Ops.size(); i != e; ++i) + if (MI->getOperand(Ops[i]).isDef()) + Flags |= MachineMemOperand::MOStore; + else + Flags |= MachineMemOperand::MOLoad; + + // Ask the target to do the actual folding. + MachineInstr *NewMI = foldMemoryOperandImpl(MF, MI, Ops, FrameIndex); + if (!NewMI) return 0; + + assert((!(Flags & MachineMemOperand::MOStore) || + NewMI->getDesc().mayStore()) && + "Folded a def to a non-store!"); + assert((!(Flags & MachineMemOperand::MOLoad) || + NewMI->getDesc().mayLoad()) && + "Folded a use to a non-load!"); + const MachineFrameInfo &MFI = *MF.getFrameInfo(); + assert(MFI.getObjectOffset(FrameIndex) != -1); + MachineMemOperand MMO(PseudoSourceValue::getFixedStack(FrameIndex), + Flags, + MFI.getObjectOffset(FrameIndex), + MFI.getObjectSize(FrameIndex), + MFI.getObjectAlignment(FrameIndex)); + NewMI->addMemOperand(MF, MMO); + + return NewMI; +} + +/// foldMemoryOperand - Same as the previous version except it allows folding +/// of any load and store from / to any address, not just from a specific +/// stack slot. +MachineInstr* +TargetInstrInfo::foldMemoryOperand(MachineFunction &MF, + MachineInstr* MI, + const SmallVectorImpl &Ops, + MachineInstr* LoadMI) const { + assert(LoadMI->getDesc().canFoldAsLoad() && "LoadMI isn't foldable!"); +#ifndef NDEBUG + for (unsigned i = 0, e = Ops.size(); i != e; ++i) + assert(MI->getOperand(Ops[i]).isUse() && "Folding load into def!"); +#endif + + // Ask the target to do the actual folding. + MachineInstr *NewMI = foldMemoryOperandImpl(MF, MI, Ops, LoadMI); + if (!NewMI) return 0; + + // Copy the memoperands from the load to the folded instruction. + for (std::list::iterator I = LoadMI->memoperands_begin(), + E = LoadMI->memoperands_end(); I != E; ++I) + NewMI->addMemOperand(MF, *I); + + return NewMI; +} Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp?rev=60488&r1=60487&r2=60488&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp Wed Dec 3 12:43:12 2008 @@ -663,10 +663,10 @@ return true; } -MachineInstr *ARMInstrInfo::foldMemoryOperand(MachineFunction &MF, - MachineInstr *MI, +MachineInstr *ARMInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr *MI, const SmallVectorImpl &Ops, - int FI) const { + int FI) const { if (Ops.size() != 1) return NULL; unsigned OpNum = Ops[0]; Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.h?rev=60488&r1=60487&r2=60488&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.h (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.h Wed Dec 3 12:43:12 2008 @@ -211,15 +211,15 @@ MachineBasicBlock::iterator MI, const std::vector &CSI) const; - virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, - MachineInstr* MI, - const SmallVectorImpl &Ops, - int FrameIndex) const; - - virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, - MachineInstr* MI, - const SmallVectorImpl &Ops, - MachineInstr* LoadMI) const { + virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr* MI, + const SmallVectorImpl &Ops, + int FrameIndex) const; + + virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr* MI, + const SmallVectorImpl &Ops, + MachineInstr* LoadMI) const { return 0; } Modified: llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.cpp?rev=60488&r1=60487&r2=60488&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.cpp Wed Dec 3 12:43:12 2008 @@ -255,10 +255,10 @@ NewMIs.push_back(MIB); } -MachineInstr *AlphaInstrInfo::foldMemoryOperand(MachineFunction &MF, - MachineInstr *MI, +MachineInstr *AlphaInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr *MI, const SmallVectorImpl &Ops, - int FrameIndex) const { + int FrameIndex) const { if (Ops.size() != 1) return NULL; // Make sure this is a reg-reg copy. Modified: llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.h?rev=60488&r1=60487&r2=60488&view=diff ============================================================================== --- llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.h (original) +++ llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.h Wed Dec 3 12:43:12 2008 @@ -69,15 +69,15 @@ const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const; - virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, - MachineInstr* MI, - const SmallVectorImpl &Ops, - int FrameIndex) const; + virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr* MI, + const SmallVectorImpl &Ops, + int FrameIndex) const; - virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, - MachineInstr* MI, - const SmallVectorImpl &Ops, - MachineInstr* LoadMI) const { + virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr* MI, + const SmallVectorImpl &Ops, + MachineInstr* LoadMI) const { return 0; } Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp?rev=60488&r1=60487&r2=60488&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.cpp Wed Dec 3 12:43:12 2008 @@ -399,10 +399,10 @@ /// foldMemoryOperand - SPU, like PPC, can only fold spills into /// copy instructions, turning them into load/store instructions. MachineInstr * -SPUInstrInfo::foldMemoryOperand(MachineFunction &MF, - MachineInstr *MI, - const SmallVectorImpl &Ops, - int FrameIndex) const +SPUInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr *MI, + const SmallVectorImpl &Ops, + int FrameIndex) const { #if SOMEDAY_SCOTT_LOOKS_AT_ME_AGAIN if (Ops.size() != 1) return NULL; Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h?rev=60488&r1=60487&r2=60488&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h (original) +++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.h Wed Dec 3 12:43:12 2008 @@ -79,16 +79,16 @@ SmallVectorImpl &NewMIs) const; //! Fold spills into load/store instructions - virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, - MachineInstr* MI, - const SmallVectorImpl &Ops, - int FrameIndex) const; + virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr* MI, + const SmallVectorImpl &Ops, + int FrameIndex) const; //! Fold any load/store to an operand - virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, - MachineInstr* MI, - const SmallVectorImpl &Ops, - MachineInstr* LoadMI) const { + virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr* MI, + const SmallVectorImpl &Ops, + MachineInstr* LoadMI) const { return 0; } }; Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp?rev=60488&r1=60487&r2=60488&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp Wed Dec 3 12:43:12 2008 @@ -279,9 +279,9 @@ } MachineInstr *MipsInstrInfo:: -foldMemoryOperand(MachineFunction &MF, - MachineInstr* MI, - const SmallVectorImpl &Ops, int FI) const +foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr* MI, + const SmallVectorImpl &Ops, int FI) const { if (Ops.size() != 1) return NULL; @@ -323,7 +323,7 @@ } else if (RC == Mips::AFGR64RegisterClass) { LoadOpc = Mips::LDC1; StoreOpc = Mips::SDC1; } else - assert(0 && "foldMemoryOperand register unknown"); + assert(0 && "foldMemoryOperandImpl register unknown"); if (Ops[0] == 0) { // COPY -> STORE unsigned SrcReg = MI->getOperand(1).getReg(); Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.h?rev=60488&r1=60487&r2=60488&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrInfo.h (original) +++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.h Wed Dec 3 12:43:12 2008 @@ -196,15 +196,15 @@ const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const; - virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, - MachineInstr* MI, - const SmallVectorImpl &Ops, - int FrameIndex) const; + virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr* MI, + const SmallVectorImpl &Ops, + int FrameIndex) const; - virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, - MachineInstr* MI, - const SmallVectorImpl &Ops, - MachineInstr* LoadMI) const { + virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr* MI, + const SmallVectorImpl &Ops, + MachineInstr* LoadMI) const { return 0; } Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp?rev=60488&r1=60487&r2=60488&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp Wed Dec 3 12:43:12 2008 @@ -655,10 +655,10 @@ /// foldMemoryOperand - PowerPC (like most RISC's) can only fold spills into /// copy instructions, turning them into load/store instructions. -MachineInstr *PPCInstrInfo::foldMemoryOperand(MachineFunction &MF, - MachineInstr *MI, - const SmallVectorImpl &Ops, - int FrameIndex) const { +MachineInstr *PPCInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr *MI, + const SmallVectorImpl &Ops, + int FrameIndex) const { if (Ops.size() != 1) return NULL; // Make sure this is a reg-reg copy. Note that we can't handle MCRF, because Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h?rev=60488&r1=60487&r2=60488&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h (original) +++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h Wed Dec 3 12:43:12 2008 @@ -142,15 +142,15 @@ /// foldMemoryOperand - PowerPC (like most RISC's) can only fold spills into /// copy instructions, turning them into load/store instructions. - virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, - MachineInstr* MI, - const SmallVectorImpl &Ops, - int FrameIndex) const; + virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr* MI, + const SmallVectorImpl &Ops, + int FrameIndex) const; - virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, - MachineInstr* MI, - const SmallVectorImpl &Ops, - MachineInstr* LoadMI) const { + virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr* MI, + const SmallVectorImpl &Ops, + MachineInstr* LoadMI) const { return 0; } Modified: llvm/trunk/lib/Target/Sparc/SparcInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcInstrInfo.cpp?rev=60488&r1=60487&r2=60488&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/SparcInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/Sparc/SparcInstrInfo.cpp Wed Dec 3 12:43:12 2008 @@ -225,10 +225,10 @@ return; } -MachineInstr *SparcInstrInfo::foldMemoryOperand(MachineFunction &MF, - MachineInstr* MI, +MachineInstr *SparcInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr* MI, const SmallVectorImpl &Ops, - int FI) const { + int FI) const { if (Ops.size() != 1) return NULL; unsigned OpNum = Ops[0]; Modified: llvm/trunk/lib/Target/Sparc/SparcInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcInstrInfo.h?rev=60488&r1=60487&r2=60488&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/SparcInstrInfo.h (original) +++ llvm/trunk/lib/Target/Sparc/SparcInstrInfo.h Wed Dec 3 12:43:12 2008 @@ -96,15 +96,15 @@ const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const; - virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, - MachineInstr* MI, - const SmallVectorImpl &Ops, - int FrameIndex) const; + virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr* MI, + const SmallVectorImpl &Ops, + int FrameIndex) const; - virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, - MachineInstr* MI, - const SmallVectorImpl &Ops, - MachineInstr* LoadMI) const { + virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr* MI, + const SmallVectorImpl &Ops, + MachineInstr* LoadMI) const { return 0; } }; Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=60488&r1=60487&r2=60488&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Wed Dec 3 12:43:12 2008 @@ -1976,9 +1976,9 @@ } MachineInstr* -X86InstrInfo::foldMemoryOperand(MachineFunction &MF, - MachineInstr *MI, unsigned i, - const SmallVector &MOs) const{ +X86InstrInfo::foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr *MI, unsigned i, + const SmallVector &MOs) const{ const DenseMap *OpcodeTablePtr = NULL; bool isTwoAddrFold = false; unsigned NumOps = MI->getDesc().getNumOperands(); @@ -2035,10 +2035,10 @@ } -MachineInstr* X86InstrInfo::foldMemoryOperand(MachineFunction &MF, - MachineInstr *MI, - const SmallVectorImpl &Ops, - int FrameIndex) const { +MachineInstr* X86InstrInfo::foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr *MI, + const SmallVectorImpl &Ops, + int FrameIndex) const { // Check switch flag if (NoFusing) return NULL; @@ -2079,13 +2079,13 @@ SmallVector MOs; MOs.push_back(MachineOperand::CreateFI(FrameIndex)); - return foldMemoryOperand(MF, MI, Ops[0], MOs); + return foldMemoryOperandImpl(MF, MI, Ops[0], MOs); } -MachineInstr* X86InstrInfo::foldMemoryOperand(MachineFunction &MF, - MachineInstr *MI, - const SmallVectorImpl &Ops, - MachineInstr *LoadMI) const { +MachineInstr* X86InstrInfo::foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr *MI, + const SmallVectorImpl &Ops, + MachineInstr *LoadMI) const { // Check switch flag if (NoFusing) return NULL; @@ -2158,7 +2158,7 @@ for (unsigned i = NumOps - 4; i != NumOps; ++i) MOs.push_back(LoadMI->getOperand(i)); } - return foldMemoryOperand(MF, MI, Ops[0], MOs); + return foldMemoryOperandImpl(MF, MI, Ops[0], MOs); } Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.h?rev=60488&r1=60487&r2=60488&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.h (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.h Wed Dec 3 12:43:12 2008 @@ -368,18 +368,18 @@ /// folding and return true, otherwise it should return false. If it folds /// the instruction, it is likely that the MachineInstruction the iterator /// references has been changed. - virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, - MachineInstr* MI, - const SmallVectorImpl &Ops, - int FrameIndex) const; + virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr* MI, + const SmallVectorImpl &Ops, + int FrameIndex) const; /// foldMemoryOperand - Same as the previous version except it allows folding /// of any load and store from / to any address, not just from a specific /// stack slot. - virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, - MachineInstr* MI, - const SmallVectorImpl &Ops, - MachineInstr* LoadMI) const; + virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr* MI, + const SmallVectorImpl &Ops, + MachineInstr* LoadMI) const; /// canFoldMemoryOperand - Returns true if the specified load / store is /// folding is possible. @@ -444,10 +444,10 @@ unsigned getGlobalBaseReg(MachineFunction *MF) const; private: - MachineInstr* foldMemoryOperand(MachineFunction &MF, - MachineInstr* MI, - unsigned OpNum, - const SmallVector &MOs) const; + MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr* MI, + unsigned OpNum, + const SmallVector &MOs) const; }; } // End llvm namespace From sabre at nondot.org Wed Dec 3 13:18:59 2008 From: sabre at nondot.org (Chris Lattner) Date: Wed, 03 Dec 2008 19:18:59 -0000 Subject: [llvm-commits] [llvm] r60492 - /llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h Message-ID: <200812031919.mB3JJ1NH027446@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 3 13:18:54 2008 New Revision: 60492 URL: http://llvm.org/viewvc/llvm-project?rev=60492&view=rev Log: fix a really incorrect comment. Modified: llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h Modified: llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h?rev=60492&r1=60491&r2=60492&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h (original) +++ llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h Wed Dec 3 13:18:54 2008 @@ -94,10 +94,10 @@ /// will not invalidate either of them. This returns true if the edge was split, /// false otherwise. /// -/// If MergeIdenticalEdges is true (the default), *all* edges from TI to the +/// If MergeIdenticalEdges is true (not the default), *all* edges from TI to the /// specified successor will be merged into the same critical edge block. /// This is most commonly interesting with switch instructions, which may -/// have many edges to any one destination. This ensures that all edges to that +/// have many edges to any one destination. This ensures that all edges to that /// dest go to one block instead of each going to a different block, but isn't /// the standard definition of a "critical edge". /// From dalej at apple.com Wed Dec 3 13:25:55 2008 From: dalej at apple.com (Dale Johannesen) Date: Wed, 03 Dec 2008 19:25:55 -0000 Subject: [llvm-commits] [llvm] r60494 - /llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200812031925.mB3JPtdI027717@zion.cs.uiuc.edu> Author: johannes Date: Wed Dec 3 13:25:46 2008 New Revision: 60494 URL: http://llvm.org/viewvc/llvm-project?rev=60494&view=rev Log: Fix a really wrong comment. Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=60494&r1=60493&r2=60494&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Wed Dec 3 13:25:46 2008 @@ -1180,7 +1180,7 @@ for (unsigned i = 0, e = Uses.Users.size(); i != e; ++i) { UsersToProcess.push_back(BasedUser(Uses.Users[i], SE)); - // Move any loop invariant operands from the offset field to the immediate + // Move any loop variant operands from the offset field to the immediate // field of the use, so that we don't try to use something before it is // computed. MoveLoopVariantsToImediateField(UsersToProcess.back().Base, From gohman at apple.com Wed Dec 3 13:30:20 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 03 Dec 2008 19:30:20 -0000 Subject: [llvm-commits] [llvm] r60495 - /llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Message-ID: <200812031930.mB3JUKJ2027862@zion.cs.uiuc.edu> Author: djg Date: Wed Dec 3 13:30:13 2008 New Revision: 60495 URL: http://llvm.org/viewvc/llvm-project?rev=60495&view=rev Log: Add a comment about callee-saved registers. Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=60495&r1=60494&r2=60495&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Wed Dec 3 13:30:13 2008 @@ -278,6 +278,8 @@ // TODO: If the callee saves and restores these, then we can potentially // use them between the save and the restore. To do that, we could scan // the exit blocks to see which of these registers are defined. + // Alternatively, calle-saved registers that aren't saved and restored + // could be marked live-in in every block. for (const unsigned *I = TRI->getCalleeSavedRegs(); *I; ++I) { unsigned Reg = *I; Classes[Reg] = reinterpret_cast(-1); From gohman at apple.com Wed Dec 3 13:32:28 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 03 Dec 2008 19:32:28 -0000 Subject: [llvm-commits] [llvm] r60496 - /llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Message-ID: <200812031932.mB3JWT72027937@zion.cs.uiuc.edu> Author: djg Date: Wed Dec 3 13:32:26 2008 New Revision: 60496 URL: http://llvm.org/viewvc/llvm-project?rev=60496&view=rev Log: When looking for anti-dependences on the critical path, don't bother examining non-anti-dependence edges. Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=60496&r1=60495&r2=60496&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Wed Dec 3 13:32:26 2008 @@ -195,6 +195,10 @@ SDep *Edge = CriticalPath[SU->NodeNum]; SUnit *NextSU = Edge->Dep; unsigned AntiDepReg = Edge->Reg; + // Only consider anti-dependence edges. + if (!Edge->isAntiDep) + continue; + assert(AntiDepReg != 0 && "Anti-dependence on reg0?"); // Don't break anti-dependencies on non-allocatable registers. if (!AllocatableSet.test(AntiDepReg)) continue; From dalej at apple.com Wed Dec 3 13:33:12 2008 From: dalej at apple.com (Dale Johannesen) Date: Wed, 03 Dec 2008 19:33:12 -0000 Subject: [llvm-commits] [llvm] r60497 - /llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp Message-ID: <200812031933.mB3JXCrw027968@zion.cs.uiuc.edu> Author: johannes Date: Wed Dec 3 13:33:10 2008 New Revision: 60497 URL: http://llvm.org/viewvc/llvm-project?rev=60497&view=rev Log: A step towards geting linux ppc to work (see PR 3099) Modified: llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp Modified: llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp?rev=60497&r1=60496&r2=60497&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp Wed Dec 3 13:33:10 2008 @@ -613,6 +613,8 @@ // Print out jump tables referenced by the function. EmitJumpTableInfo(MF.getJumpTableInfo(), MF); + SwitchToSection(TAI->SectionForGlobal(F)); + // Emit post-function debug information. DW.EndFunction(&MF); From gohman at apple.com Wed Dec 3 13:37:42 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 03 Dec 2008 19:37:42 -0000 Subject: [llvm-commits] [llvm] r60498 - /llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Message-ID: <200812031937.mB3JbgIv028077@zion.cs.uiuc.edu> Author: djg Date: Wed Dec 3 13:37:34 2008 New Revision: 60498 URL: http://llvm.org/viewvc/llvm-project?rev=60498&view=rev Log: Don't charge the full latency for anti and output dependencies. This is an area where eventually it would be good to use target-dependent information. Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=60498&r1=60497&r2=60498&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Wed Dec 3 13:37:34 2008 @@ -160,9 +160,12 @@ for (SUnit::pred_iterator P = SU->Preds.begin(), PE = SU->Preds.end(); P != PE; ++P) { SUnit *PredSU = P->Dep; - unsigned PredLatency = PredSU->CycleBound + PredSU->Latency; - if (SU->CycleBound < PredLatency) { - SU->CycleBound = PredLatency; + // This assumes that there's no delay for reusing registers. + unsigned PredLatency = (P->isCtrl && P->Reg != 0) ? 1 : PredSU->Latency; + unsigned PredTotalLatency = PredSU->CycleBound + PredLatency; + if (SU->CycleBound < PredTotalLatency || + (SU->CycleBound == PredTotalLatency && !P->isAntiDep)) { + SU->CycleBound = PredTotalLatency; CriticalPath[*I] = &*P; } } From evan.cheng at apple.com Wed Dec 3 13:38:06 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 03 Dec 2008 19:38:06 -0000 Subject: [llvm-commits] [llvm] r60499 - in /llvm/trunk: lib/Target/X86/X86InstrMMX.td test/CodeGen/X86/mmx-vzmovl-2.ll Message-ID: <200812031938.mB3Jc7af028097@zion.cs.uiuc.edu> Author: evancheng Date: Wed Dec 3 13:38:05 2008 New Revision: 60499 URL: http://llvm.org/viewvc/llvm-project?rev=60499&view=rev Log: Use mmx (punpckldq VR64, (mmx_v_set0)) to clear high 32-bits of a VR64 register. Added: llvm/trunk/test/CodeGen/X86/mmx-vzmovl-2.ll Modified: llvm/trunk/lib/Target/X86/X86InstrMMX.td Modified: llvm/trunk/lib/Target/X86/X86InstrMMX.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrMMX.td?rev=60499&r1=60498&r2=60499&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrMMX.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrMMX.td Wed Dec 3 13:38:05 2008 @@ -587,11 +587,21 @@ let AddedComplexity = 20 in { def : Pat<(v8i8 (X86vzmovl (bc_v8i8 (load_mmx addr:$src)))), - (MMX_MOVZDI2PDIrm addr:$src)>; + (MMX_MOVZDI2PDIrm addr:$src)>; def : Pat<(v4i16 (X86vzmovl (bc_v4i16 (load_mmx addr:$src)))), - (MMX_MOVZDI2PDIrm addr:$src)>; + (MMX_MOVZDI2PDIrm addr:$src)>; def : Pat<(v2i32 (X86vzmovl (bc_v2i32 (load_mmx addr:$src)))), - (MMX_MOVZDI2PDIrm addr:$src)>; + (MMX_MOVZDI2PDIrm addr:$src)>; +} + +// Clear top half. +let AddedComplexity = 15 in { + def : Pat<(v8i8 (X86vzmovl VR64:$src)), + (MMX_PUNPCKLDQrr VR64:$src, (MMX_V_SET0))>; + def : Pat<(v4i16 (X86vzmovl VR64:$src)), + (MMX_PUNPCKLDQrr VR64:$src, (MMX_V_SET0))>; + def : Pat<(v2i32 (X86vzmovl VR64:$src)), + (MMX_PUNPCKLDQrr VR64:$src, (MMX_V_SET0))>; } // Scalar to v4i16 / v8i8. The source may be a GR32, but only the lower Added: llvm/trunk/test/CodeGen/X86/mmx-vzmovl-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/mmx-vzmovl-2.ll?rev=60499&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/mmx-vzmovl-2.ll (added) +++ llvm/trunk/test/CodeGen/X86/mmx-vzmovl-2.ll Wed Dec 3 13:38:05 2008 @@ -0,0 +1,24 @@ +; RUN: llvm-as < %s | llc -march=x86-64 -mattr=+mmx | grep pxor +; RUN: llvm-as < %s | llc -march=x86-64 -mattr=+mmx | grep punpckldq + + %struct.vS1024 = type { [8 x <4 x i32>] } + %struct.vS512 = type { [4 x <4 x i32>] } + +declare <1 x i64> @llvm.x86.mmx.psrli.q(<1 x i64>, i32) nounwind readnone + +define void @t() nounwind { +entry: + br label %bb554 + +bb554: ; preds = %bb554, %entry + %sum.0.reg2mem.0 = phi <1 x i64> [ %tmp562, %bb554 ], [ zeroinitializer, %entry ] ; <<1 x i64>> [#uses=1] + %0 = load <1 x i64>* null, align 8 ; <<1 x i64>> [#uses=2] + %1 = bitcast <1 x i64> %0 to <2 x i32> ; <<2 x i32>> [#uses=1] + %tmp555 = and <2 x i32> %1, < i32 -1, i32 0 > ; <<2 x i32>> [#uses=1] + %2 = bitcast <2 x i32> %tmp555 to <1 x i64> ; <<1 x i64>> [#uses=1] + %3 = call <1 x i64> @llvm.x86.mmx.psrli.q(<1 x i64> %0, i32 32) nounwind readnone ; <<1 x i64>> [#uses=1] + %tmp558 = add <1 x i64> %sum.0.reg2mem.0, %2 ; <<1 x i64>> [#uses=1] + %4 = call <1 x i64> @llvm.x86.mmx.psrli.q(<1 x i64> %tmp558, i32 32) nounwind readnone ; <<1 x i64>> [#uses=1] + %tmp562 = add <1 x i64> %4, %3 ; <<1 x i64>> [#uses=1] + br label %bb554 +} From gohman at apple.com Wed Dec 3 13:38:38 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 03 Dec 2008 19:38:38 -0000 Subject: [llvm-commits] [llvm] r60500 - /llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Message-ID: <200812031938.mB3JccYh028122@zion.cs.uiuc.edu> Author: djg Date: Wed Dec 3 13:38:38 2008 New Revision: 60500 URL: http://llvm.org/viewvc/llvm-project?rev=60500&view=rev Log: Fix an inconsistency in a comment. Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=60500&r1=60499&r2=60500&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Wed Dec 3 13:38:38 2008 @@ -223,10 +223,9 @@ } // For live regs that are only used in one register class in a live range, - // the register class. If the register is not live or is referenced in - // multiple register classes, the corresponding value is null. If the - // register is used in multiple register classes, the corresponding value - // is -1 casted to a pointer. + // the register class. If the register is not live, the corresponding value + // is null. If the register is live but used in multiple register classes, + // the corresponding value is -1 casted to a pointer. const TargetRegisterClass * Classes[TargetRegisterInfo::FirstVirtualRegister] = {}; From monping at apple.com Wed Dec 3 13:38:36 2008 From: monping at apple.com (Mon Ping Wang) Date: Wed, 3 Dec 2008 11:38:36 -0800 Subject: [llvm-commits] Patch: small fix to bit convert and shifts In-Reply-To: References: Message-ID: <2E498C01-B301-4F46-B16B-D030D169FE88@apple.com> Hi, On Dec 1, 2008, at 10:44 AM, Evan Cheng wrote: > > On Nov 30, 2008, at 8:32 PM, Mon Ping Wang wrote: > >> Hi, >> >> This is a small patch that fixes two problems in SelectionDAG.cpp >> >> 1) in getShuffleScalarElt, the code assumes that if the input to >> the shuffle is a BIT_CONVERT, the input to the bit convert is also a >> vector. This is not necessarily true as it is legal to bit convert a > > You didn't finish your sentence? :-) > My mind was going one way and my finger went another :->. What I mean to say it is legal to bit convert a scalar type to a vector type so the assumption that the input to the bit convert must be a vector type is incorrect. The current code assumes that it is vector and asks for number of vector elements. The change is to make sure that the incoming type is a vector first before asking for the number of vector elements. >> >> >> 2) In getNode, the code assumes that for shifts, the shift amount >> is always a scalar. Since shifts can operate also on vectors, this >> assumption is not correct. > > The shift amount can be a vector as well? I thought operand 1 can be, > but not the shift amount. > I thought so though I am probably reading the lang ref liberally. -- Mon Ping > Evan > >> >> >> -- Mon Ping >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Wed Dec 3 13:44:11 2008 From: sabre at nondot.org (Chris Lattner) Date: Wed, 03 Dec 2008 19:44:11 -0000 Subject: [llvm-commits] [llvm] r60501 - in /llvm/trunk: include/llvm/Transforms/Utils/BasicBlockUtils.h include/llvm/Transforms/Utils/Local.h lib/Transforms/Scalar/CondPropagate.cpp lib/Transforms/Utils/BasicBlockUtils.cpp lib/Transforms/Utils/SimplifyCFG.cpp lib/Transforms/Utils/UnrollLoop.cpp Message-ID: <200812031944.mB3JiDaT028335@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 3 13:44:02 2008 New Revision: 60501 URL: http://llvm.org/viewvc/llvm-project?rev=60501&view=rev Log: Factor some code into a new FoldSingleEntryPHINodes method. Modified: llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h llvm/trunk/include/llvm/Transforms/Utils/Local.h llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp llvm/trunk/lib/Transforms/Utils/UnrollLoop.cpp Modified: llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h?rev=60501&r1=60500&r2=60501&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h (original) +++ llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h Wed Dec 3 13:44:02 2008 @@ -30,6 +30,14 @@ /// predecessors. void DeleteDeadBlock(BasicBlock *BB); + +/// FoldSingleEntryPHINodes - We know that BB has one predecessor. If there are +/// any single-entry PHI nodes in it, fold them away. This handles the case +/// when all entries to the PHI nodes in a block are guaranteed equal, such as +/// when the block has exactly one predecessor. +void FoldSingleEntryPHINodes(BasicBlock *BB); + + /// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor, /// if possible. The return value indicates success or failure. bool MergeBlockIntoPredecessor(BasicBlock* BB, Pass* P = 0); Modified: llvm/trunk/include/llvm/Transforms/Utils/Local.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Local.h?rev=60501&r1=60500&r2=60501&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/Local.h (original) +++ llvm/trunk/include/llvm/Transforms/Utils/Local.h Wed Dec 3 13:44:02 2008 @@ -56,7 +56,7 @@ SmallVectorImpl *DeadInst = 0); //===----------------------------------------------------------------------===// -// Control Flow Graph Restructuring... +// Control Flow Graph Restructuring. // /// MergeBasicBlockIntoOnlyPred - BB is a block with one predecessor and its Modified: llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp?rev=60501&r1=60500&r2=60501&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp Wed Dec 3 13:44:02 2008 @@ -14,12 +14,13 @@ #define DEBUG_TYPE "condprop" #include "llvm/Transforms/Scalar.h" -#include "llvm/Transforms/Utils/Local.h" #include "llvm/Constants.h" #include "llvm/Function.h" #include "llvm/Instructions.h" #include "llvm/Pass.h" #include "llvm/Type.h" +#include "llvm/Transforms/Utils/BasicBlockUtils.h" +#include "llvm/Transforms/Utils/Local.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/Compiler.h" @@ -95,13 +96,9 @@ BB != BI->getSuccessor(0)) { BasicBlock *Succ = BI->getSuccessor(0); - // If Succ has any PHI nodes, they are all single-entry PHI's. - while (PHINode *PN = dyn_cast(Succ->begin())) { - assert(PN->getNumIncomingValues() == 1 && - "PHI doesn't match parent block"); - PN->replaceAllUsesWith(PN->getIncomingValue(0)); - PN->eraseFromParent(); - } + // If Succ has any PHI nodes, they are all single-entry PHI's. Eliminate + // them. + FoldSingleEntryPHINodes(Succ); // Remove BI. BI->eraseFromParent(); @@ -205,11 +202,7 @@ // OldSucc had multiple successors. If ToBB has multiple predecessors, then // the edge between them would be critical, which we already took care of. // If ToBB has single operand PHI node then take care of it here. - while (PHINode *PN = dyn_cast(ToBB->begin())) { - assert(PN->getNumIncomingValues() == 1 && "Critical Edge Found!"); - PN->replaceAllUsesWith(PN->getIncomingValue(0)); - PN->eraseFromParent(); - } + FoldSingleEntryPHINodes(ToBB); // Update PHI nodes in OldSucc to know that FromBB no longer branches to it. OldSucc->removePredecessor(FromBB); Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp?rev=60501&r1=60500&r2=60501&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Wed Dec 3 13:44:02 2008 @@ -54,6 +54,24 @@ BB->eraseFromParent(); } +/// FoldSingleEntryPHINodes - We know that BB has one predecessor. If there are +/// any single-entry PHI nodes in it, fold them away. This handles the case +/// when all entries to the PHI nodes in a block are guaranteed equal, such as +/// when the block has exactly one predecessor. +void llvm::FoldSingleEntryPHINodes(BasicBlock *BB) { + if (!isa(BB->begin())) + return; + + while (PHINode *PN = dyn_cast(BB->begin())) { + if (PN->getIncomingValue(0) != PN) + PN->replaceAllUsesWith(PN->getIncomingValue(0)); + else + PN->replaceAllUsesWith(UndefValue::get(PN->getType())); + PN->eraseFromParent(); + } +} + + /// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor, /// if possible. The return value indicates success or failure. bool llvm::MergeBlockIntoPredecessor(BasicBlock* BB, Pass* P) { Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=60501&r1=60500&r2=60501&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Wed Dec 3 13:44:02 2008 @@ -1101,10 +1101,7 @@ // Degenerate case of a single entry PHI. if (PN->getNumIncomingValues() == 1) { - if (PN->getIncomingValue(0) != PN) - PN->replaceAllUsesWith(PN->getIncomingValue(0)); - else - PN->replaceAllUsesWith(UndefValue::get(PN->getType())); + FoldSingleEntryPHINodes(PN->getParent()); PN->eraseFromParent(); return true; } Modified: llvm/trunk/lib/Transforms/Utils/UnrollLoop.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/UnrollLoop.cpp?rev=60501&r1=60500&r2=60501&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/UnrollLoop.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/UnrollLoop.cpp Wed Dec 3 13:44:02 2008 @@ -25,13 +25,14 @@ #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Support/Debug.h" +#include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Transforms/Utils/Local.h" #include using namespace llvm; -/* TODO: Should these be here or in LoopUnroll? */ +// TODO: Should these be here or in LoopUnroll? STATISTIC(NumCompletelyUnrolled, "Number of loops completely unrolled"); STATISTIC(NumUnrolled, "Number of loops unrolled (completely or otherwise)"); @@ -68,11 +69,7 @@ // multiple duplicate (but guaranteed to be equal) entries for the // incoming edges. This occurs when there are multiple edges from // OnlyPred to OnlySucc. - // - while (PHINode *PN = dyn_cast(&BB->front())) { - PN->replaceAllUsesWith(PN->getIncomingValue(0)); - BB->getInstList().pop_front(); // Delete the phi node... - } + FoldSingleEntryPHINodes(BB); // Delete the unconditional branch from the predecessor... OnlyPred->getInstList().pop_back(); From stefanus.dutoit at rapidmind.com Wed Dec 3 13:48:01 2008 From: stefanus.dutoit at rapidmind.com (Stefanus Du Toit) Date: Wed, 3 Dec 2008 14:48:01 -0500 Subject: [llvm-commits] Patch: small fix to bit convert and shifts In-Reply-To: <2E498C01-B301-4F46-B16B-D030D169FE88@apple.com> References: <2E498C01-B301-4F46-B16B-D030D169FE88@apple.com> Message-ID: <9677A259-CA70-47BC-A7B9-8F969B887B02@rapidmind.com> On 3-Dec-08, at 2:38 PM, Mon Ping Wang wrote: >>> 2) In getNode, the code assumes that for shifts, the shift amount >>> is always a scalar. Since shifts can operate also on vectors, this >>> assumption is not correct. >> >> The shift amount can be a vector as well? I thought operand 1 can be, >> but not the shift amount. >> > > I thought so though I am probably reading the lang ref liberally. That was certainly our assumption/intent, in the interest of orthogonality (e.g. this makes the instruction far more convenient for an autovectorizer). Of course, machines may have vector x scalar shift instructions that can benefit from cases where the shift amount is a (replicated) scalar. -- Stefanus Du Toit RapidMind Inc. phone: +1 519 885 5455 x116 -- fax: +1 519 885 1463 From dalej at apple.com Wed Dec 3 14:56:13 2008 From: dalej at apple.com (Dale Johannesen) Date: Wed, 03 Dec 2008 20:56:13 -0000 Subject: [llvm-commits] [llvm] r60506 - /llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200812032056.mB3KuDs8031307@zion.cs.uiuc.edu> Author: johannes Date: Wed Dec 3 14:56:12 2008 New Revision: 60506 URL: http://llvm.org/viewvc/llvm-project?rev=60506&view=rev Log: Fix a misspelled function name. Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=60506&r1=60505&r2=60506&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Wed Dec 3 14:56:12 2008 @@ -767,9 +767,9 @@ return false; } -/// MoveLoopVariantsToImediateField - Move any subexpressions from Val that are +/// MoveLoopVariantsToImmediateField - Move any subexpressions from Val that are /// loop varying to the Imm operand. -static void MoveLoopVariantsToImediateField(SCEVHandle &Val, SCEVHandle &Imm, +static void MoveLoopVariantsToImmediateField(SCEVHandle &Val, SCEVHandle &Imm, Loop *L, ScalarEvolution *SE) { if (Val->isLoopInvariant(L)) return; // Nothing to do. @@ -793,7 +793,7 @@ } else if (SCEVAddRecExpr *SARE = dyn_cast(Val)) { // Try to pull immediates out of the start value of nested addrec's. SCEVHandle Start = SARE->getStart(); - MoveLoopVariantsToImediateField(Start, Imm, L, SE); + MoveLoopVariantsToImmediateField(Start, Imm, L, SE); std::vector Ops(SARE->op_begin(), SARE->op_end()); Ops[0] = Start; @@ -1183,7 +1183,7 @@ // Move any loop variant operands from the offset field to the immediate // field of the use, so that we don't try to use something before it is // computed. - MoveLoopVariantsToImediateField(UsersToProcess.back().Base, + MoveLoopVariantsToImmediateField(UsersToProcess.back().Base, UsersToProcess.back().Imm, L, SE); assert(UsersToProcess.back().Base->isLoopInvariant(L) && "Base value is not loop invariant!"); From gohman at apple.com Wed Dec 3 15:37:29 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 03 Dec 2008 21:37:29 -0000 Subject: [llvm-commits] [llvm] r60507 - in /llvm/trunk: include/llvm/CodeGen/PseudoSourceValue.h lib/CodeGen/PseudoSourceValue.cpp lib/VMCore/AsmWriter.cpp Message-ID: <200812032137.mB3LbUeW032648@zion.cs.uiuc.edu> Author: djg Date: Wed Dec 3 15:37:21 2008 New Revision: 60507 URL: http://llvm.org/viewvc/llvm-project?rev=60507&view=rev Log: Have PseudoSourceValue override Value::dump, so that it works on PseudoSourceValue values. This also fixes a FIXME in lib/VMCode/AsmWriter.cpp. Modified: llvm/trunk/include/llvm/CodeGen/PseudoSourceValue.h llvm/trunk/lib/CodeGen/PseudoSourceValue.cpp llvm/trunk/lib/VMCore/AsmWriter.cpp Modified: llvm/trunk/include/llvm/CodeGen/PseudoSourceValue.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/PseudoSourceValue.h?rev=60507&r1=60506&r2=60507&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/PseudoSourceValue.h (original) +++ llvm/trunk/include/llvm/CodeGen/PseudoSourceValue.h Wed Dec 3 15:37:21 2008 @@ -28,6 +28,12 @@ public: PseudoSourceValue(); + /// dump - Support for debugging, callable in GDB: V->dump() + // + virtual void dump() const; + + /// print - Implement operator<< on PseudoSourceValue. + /// virtual void print(raw_ostream &OS) const; /// isConstant - Test whether this PseudoSourceValue has a constant value. Modified: llvm/trunk/lib/CodeGen/PseudoSourceValue.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PseudoSourceValue.cpp?rev=60507&r1=60506&r2=60507&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PseudoSourceValue.cpp (original) +++ llvm/trunk/lib/CodeGen/PseudoSourceValue.cpp Wed Dec 3 15:37:21 2008 @@ -41,6 +41,10 @@ PseudoSourceValue::PseudoSourceValue() : Value(PointerType::getUnqual(Type::Int8Ty), PseudoSourceValueVal) {} +void PseudoSourceValue::dump() const { + print(errs()); errs() << '\n'; errs().flush(); +} + void PseudoSourceValue::print(raw_ostream &OS) const { OS << PSVNames[this - *PSVs]; } Modified: llvm/trunk/lib/VMCore/AsmWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/AsmWriter.cpp?rev=60507&r1=60506&r2=60507&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/AsmWriter.cpp (original) +++ llvm/trunk/lib/VMCore/AsmWriter.cpp Wed Dec 3 15:37:21 2008 @@ -1759,8 +1759,7 @@ } else if (isa(this)) { WriteAsOperand(OS, this, true, 0); } else { - // FIXME: PseudoSourceValue breaks this! - //assert(0 && "Unknown value to print out!"); + assert(0 && "Unknown value to print out!"); } } From dalej at apple.com Wed Dec 3 16:44:07 2008 From: dalej at apple.com (Dale Johannesen) Date: Wed, 03 Dec 2008 22:44:07 -0000 Subject: [llvm-commits] [llvm] r60508 - /llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200812032244.mB3MiBt0002445@zion.cs.uiuc.edu> Author: johannes Date: Wed Dec 3 16:43:56 2008 New Revision: 60508 URL: http://llvm.org/viewvc/llvm-project?rev=60508&view=rev Log: Remove an unused field. Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=60508&r1=60507&r2=60508&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Wed Dec 3 16:43:56 2008 @@ -542,10 +542,6 @@ /// instruction. SCEVHandle Imm; - /// EmittedBase - The actual value* to use for the base value of this - /// operation. This is null if we should just use zero so far. - Value *EmittedBase; - // isUseOfPostIncrementedValue - True if this should use the // post-incremented version of this IV, not the preincremented version. // This can only be set in special cases, such as the terminating setcc @@ -556,7 +552,7 @@ BasedUser(IVStrideUse &IVSU, ScalarEvolution *se) : SE(se), Base(IVSU.Offset), Inst(IVSU.User), OperandValToReplace(IVSU.OperandValToReplace), - Imm(SE->getIntegerSCEV(0, Base->getType())), EmittedBase(0), + Imm(SE->getIntegerSCEV(0, Base->getType())), isUseOfPostIncrementedValue(IVSU.isUseOfPostIncrementedValue) {} // Once we rewrite the code to insert the new IVs we want, update the @@ -577,9 +573,6 @@ void BasedUser::dump() const { cerr << " Base=" << *Base; cerr << " Imm=" << *Imm; - if (EmittedBase) - cerr << " EB=" << *EmittedBase; - cerr << " Inst: " << *Inst; } From dalej at apple.com Wed Dec 3 16:45:31 2008 From: dalej at apple.com (Dale Johannesen) Date: Wed, 03 Dec 2008 22:45:31 -0000 Subject: [llvm-commits] [llvm] r60509 - /llvm/trunk/lib/Analysis/ScalarEvolution.cpp Message-ID: <200812032245.mB3MjWO7002487@zion.cs.uiuc.edu> Author: johannes Date: Wed Dec 3 16:45:31 2008 New Revision: 60509 URL: http://llvm.org/viewvc/llvm-project?rev=60509&view=rev Log: Make the debugging dump be a full line. Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=60509&r1=60508&r2=60509&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Wed Dec 3 16:45:31 2008 @@ -112,6 +112,7 @@ SCEV::~SCEV() {} void SCEV::dump() const { print(cerr); + cerr << '\n'; } uint32_t SCEV::getBitWidth() const { From gohman at apple.com Wed Dec 3 17:07:29 2008 From: gohman at apple.com (Dan Gohman) Date: Wed, 03 Dec 2008 23:07:29 -0000 Subject: [llvm-commits] [llvm] r60510 - /llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Message-ID: <200812032307.mB3N7TeB003151@zion.cs.uiuc.edu> Author: djg Date: Wed Dec 3 17:07:27 2008 New Revision: 60510 URL: http://llvm.org/viewvc/llvm-project?rev=60510&view=rev Log: Rewrite the liveness bookkeeping code to fix a bunch of issues with subreg operands and tied operands. Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=60510&r1=60509&r2=60510&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Wed Dec 3 17:07:27 2008 @@ -31,6 +31,7 @@ #include "llvm/Support/Debug.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/SmallVector.h" #include #include using namespace llvm; @@ -343,11 +344,6 @@ // still be considered, though only if no other registers are available. unsigned LastNewReg[TargetRegisterInfo::FirstVirtualRegister] = {}; - // A registers defined and not used in an instruction. This is used for - // liveness tracking and is declared outside the loop only to avoid - // having it be re-allocated on each iteration. - DenseSet Defs; - // Attempt to break anti-dependence edges on the critical path. Walk the // instructions from the bottom up, tracking information about liveness // as we go to help determine which registers are available. @@ -433,7 +429,8 @@ if (KillIndices[NewReg] == -1u && KillIndices[AntiDepReg] <= DefIndices[NewReg]) { DOUT << "Breaking anti-dependence edge on reg " << AntiDepReg - << " with reg " << NewReg << "!\n"; + << " with " << RegRefs.count(AntiDepReg) << " references" + << " with new reg " << NewReg << "!\n"; // Update the references to the old register to refer to the new // register. @@ -464,39 +461,17 @@ } // Update liveness. - Defs.clear(); + // Proceding upwards, registers that are defed but not used in this + // instruction are now dead. for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { MachineOperand &MO = MI->getOperand(i); if (!MO.isReg()) continue; unsigned Reg = MO.getReg(); if (Reg == 0) continue; - if (MO.isDef()) - Defs.insert(Reg); - else { - // Treat a use in the same instruction as a def as an extension of - // a live range. - Defs.erase(Reg); - // It wasn't previously live but now it is, this is a kill. - if (KillIndices[Reg] == -1u) { - KillIndices[Reg] = Count; - DefIndices[Reg] = -1u; - } - // Repeat, for all aliases. - for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { - unsigned AliasReg = *Alias; - Defs.erase(AliasReg); - if (KillIndices[AliasReg] == -1u) { - KillIndices[AliasReg] = Count; - DefIndices[AliasReg] = -1u; - } - } - } - } - // Proceding upwards, registers that are defed but not used in this - // instruction are now dead. - for (DenseSet::iterator D = Defs.begin(), DE = Defs.end(); - D != DE; ++D) { - unsigned Reg = *D; + if (!MO.isDef()) continue; + // Ignore two-addr defs. + if (MI->isRegReDefinedByTwoAddr(Reg, i)) continue; + DefIndices[Reg] = Count; KillIndices[Reg] = -1; Classes[Reg] = 0; @@ -511,6 +486,39 @@ RegRefs.erase(SubregReg); } } + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI->getOperand(i); + if (!MO.isReg()) continue; + unsigned Reg = MO.getReg(); + if (Reg == 0) continue; + if (!MO.isUse()) continue; + + const TargetRegisterClass *NewRC = + getInstrOperandRegClass(TRI, TII, MI->getDesc(), i); + + // For now, only allow the register to be changed if its register + // class is consistent across all uses. + if (!Classes[Reg] && NewRC) + Classes[Reg] = NewRC; + else if (!NewRC || Classes[Reg] != NewRC) + Classes[Reg] = reinterpret_cast(-1); + + RegRefs.insert(std::make_pair(Reg, &MO)); + + // It wasn't previously live but now it is, this is a kill. + if (KillIndices[Reg] == -1u) { + KillIndices[Reg] = Count; + DefIndices[Reg] = -1u; + } + // Repeat, for all aliases. + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + unsigned AliasReg = *Alias; + if (KillIndices[AliasReg] == -1u) { + KillIndices[AliasReg] = Count; + DefIndices[AliasReg] = -1u; + } + } + } } assert(Count == -1u && "Count mismatch!"); From isanbard at gmail.com Wed Dec 3 17:23:18 2008 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 03 Dec 2008 23:23:18 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60512 - in /llvm-gcc-4.2/tags/Apple/llvmgcc42-2079.1: ./ build_gcc Message-ID: <200812032323.mB3NNIdk003750@zion.cs.uiuc.edu> Author: void Date: Wed Dec 3 17:23:17 2008 New Revision: 60512 URL: http://llvm.org/viewvc/llvm-project?rev=60512&view=rev Log: Tagging: llvmgcc42-2079 with r60454 patch. Added: llvm-gcc-4.2/tags/Apple/llvmgcc42-2079.1/ - copied from r60509, llvm-gcc-4.2/tags/Apple/llvmgcc42-2079/ Modified: llvm-gcc-4.2/tags/Apple/llvmgcc42-2079.1/build_gcc Modified: llvm-gcc-4.2/tags/Apple/llvmgcc42-2079.1/build_gcc URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/tags/Apple/llvmgcc42-2079.1/build_gcc?rev=60512&r1=60509&r2=60512&view=diff ============================================================================== --- llvm-gcc-4.2/tags/Apple/llvmgcc42-2079.1/build_gcc (original) +++ llvm-gcc-4.2/tags/Apple/llvmgcc42-2079.1/build_gcc Wed Dec 3 17:23:17 2008 @@ -619,6 +619,13 @@ rm libllvmgcc.dylib ln -s ../../libllvmgcc.dylib done + +if [ "x$LLVM_BUILT_ROOTS" == "x" ]; then + mkdir -p $DEST_DIR/usr/bin + cd $DEST_DIR/usr/bin + ln -s /Developer/usr/bin/llvm-gcc llvm-gcc + ln -s /Developer/usr/bin/llvm-g++ llvm-g++ +fi # LLVM LOCAL end find $DEST_DIR -name \*.dSYM -print | xargs rm -r || exit 1 From isanbard at gmail.com Wed Dec 3 17:24:01 2008 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 03 Dec 2008 23:24:01 -0000 Subject: [llvm-commits] [llvm] r60513 - /llvm/tags/Apple/llvmCore-2079.1/ Message-ID: <200812032324.mB3NO1YF003799@zion.cs.uiuc.edu> Author: void Date: Wed Dec 3 17:24:01 2008 New Revision: 60513 URL: http://llvm.org/viewvc/llvm-project?rev=60513&view=rev Log: Tagging: Coincide with llvmgcc42-2079. Added: llvm/tags/Apple/llvmCore-2079.1/ - copied from r60509, llvm/tags/Apple/llvmCore-2079/ From sabre at nondot.org Wed Dec 3 18:08:00 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 04 Dec 2008 00:08:00 -0000 Subject: [llvm-commits] [llvm] r60514 - /llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Message-ID: <200812040008.mB4080pv005119@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 3 18:07:59 2008 New Revision: 60514 URL: http://llvm.org/viewvc/llvm-project?rev=60514&view=rev Log: add a debugging option to help track down j-t problems. Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=60514&r1=60513&r2=60514&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Wed Dec 3 18:07:59 2008 @@ -36,6 +36,11 @@ cl::desc("Max block size to duplicate for jump threading"), cl::init(6), cl::Hidden); +static cl::opt +DebugIterations("jump-threading-debug", + cl::desc("Stop jump threading after N iterations"), + cl::init(-1), cl::Hidden); + namespace { /// This pass performs 'jump threading', which looks at blocks that have /// multiple predecessors and multiple successors. If one or more of the @@ -104,11 +109,15 @@ // If the block is trivially dead, zap it. This eliminates the successor // edges which simplifies the CFG. if (pred_begin(BB) == pred_end(BB) && - BB != &BB->getParent()->getEntryBlock()) { + BB != &BB->getParent()->getEntryBlock() && + DebugIterations != 0) { DOUT << " JT: Deleting dead block '" << BB->getNameStart() << "' with terminator: " << *BB->getTerminator(); DeleteDeadBlock(BB); Changed = true; + + if (DebugIterations != -1) + DebugIterations = DebugIterations-1; } } AnotherIteration = Changed; @@ -183,6 +192,10 @@ /// ProcessBlock - If there are any predecessors whose control can be threaded /// through to a successor, transform them now. bool JumpThreading::ProcessBlock(BasicBlock *BB) { + if (DebugIterations == 0) return false; + if (DebugIterations != -1) + DebugIterations = DebugIterations-1; + // If this block has a single predecessor, and if that pred has a single // successor, merge the blocks. This encourages recursive jump threading // because now the condition in this block can be threaded through From gohman at apple.com Wed Dec 3 19:35:47 2008 From: gohman at apple.com (Dan Gohman) Date: Thu, 04 Dec 2008 01:35:47 -0000 Subject: [llvm-commits] [llvm] r60517 - /llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Message-ID: <200812040135.mB41Zl8U007448@zion.cs.uiuc.edu> Author: djg Date: Wed Dec 3 19:35:46 2008 New Revision: 60517 URL: http://llvm.org/viewvc/llvm-project?rev=60517&view=rev Log: Add minimal support for disambiguating memory references. Currently the main thing this covers is spills to distinct spill slots. Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp?rev=60517&r1=60516&r2=60517&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp (original) +++ llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Wed Dec 3 19:35:46 2008 @@ -14,11 +14,13 @@ #define DEBUG_TYPE "sched-instrs" #include "llvm/CodeGen/ScheduleDAGInstrs.h" +#include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" +#include using namespace llvm; ScheduleDAGInstrs::ScheduleDAGInstrs(MachineBasicBlock *bb, @@ -28,19 +30,40 @@ void ScheduleDAGInstrs::BuildSchedUnits() { SUnits.clear(); SUnits.reserve(BB->size()); + int Cost = 1; // FIXME - std::vector PendingLoads; - SUnit *Terminator = 0; - SUnit *Chain = 0; + // We build scheduling units by walking a block's instruction list from bottom + // to top. + + // Remember where defs and uses of each physical register are as we procede. SUnit *Defs[TargetRegisterInfo::FirstVirtualRegister] = {}; std::vector Uses[TargetRegisterInfo::FirstVirtualRegister] = {}; - int Cost = 1; // FIXME + + // Remember where unknown loads are after the most recent unknown store + // as we procede. + std::vector PendingLoads; + + // Remember where a generic side-effecting instruction is as we procede. If + // ChainMMO is null, this is assumed to have arbitrary side-effects. If + // ChainMMO is non-null, then Chain makes only a single memory reference. + SUnit *Chain = 0; + MachineMemOperand *ChainMMO = 0; + + // Memory references to specific known memory locations are tracked so that + // they can be given more precise dependencies. + std::map MemDefs; + std::map > MemUses; + + // Terminators can perform control transfers, we we need to make sure that + // all the work of the block is done before the terminator. + SUnit *Terminator = 0; for (MachineBasicBlock::iterator MII = BB->end(), MIE = BB->begin(); MII != MIE; --MII) { MachineInstr *MI = prior(MII); SUnit *SU = NewSUnit(MI); + // Add register-based dependencies (data, anti, and output). for (unsigned j = 0, n = MI->getNumOperands(); j != n; ++j) { const MachineOperand &MO = MI->getOperand(j); if (!MO.isReg()) continue; @@ -81,23 +104,110 @@ UseList.push_back(SU); } } - bool False = false; - bool True = true; - if (!MI->isSafeToMove(TII, False)) { + + // Add chain dependencies. + // Note that isStoreToStackSlot and isLoadFromStackSLot are not usable + // after stack slots are lowered to actual addresses. + // TODO: Use an AliasAnalysis and do real alias-analysis queries, and + // produce more precise dependence information. + const TargetInstrDesc &TID = MI->getDesc(); + if (TID.isCall() || TID.isReturn() || TID.isBranch() || + TID.hasUnmodeledSideEffects()) { + new_chain: + // This is the conservative case. Add dependencies on all memory references. if (Chain) Chain->addPred(SU, /*isCtrl=*/true, /*isArtificial=*/false); + Chain = SU; for (unsigned k = 0, m = PendingLoads.size(); k != m; ++k) PendingLoads[k]->addPred(SU, /*isCtrl=*/true, /*isArtificial=*/false); PendingLoads.clear(); - Chain = SU; - } else if (!MI->isSafeToMove(TII, True)) { - if (Chain) - Chain->addPred(SU, /*isCtrl=*/true, /*isArtificial=*/false); - PendingLoads.push_back(SU); + for (std::map::iterator I = MemDefs.begin(), + E = MemDefs.end(); I != E; ++I) { + I->second->addPred(SU, /*isCtrl=*/true, /*isArtificial=*/false); + I->second = SU; + } + for (std::map >::iterator I = + MemUses.begin(), E = MemUses.end(); I != E; ++I) { + for (unsigned i = 0, e = I->second.size(); i != e; ++i) + I->second[i]->addPred(SU, /*isCtrl=*/true, /*isArtificial=*/false); + I->second.clear(); + } + // See if it is known to just have a single memory reference. + MachineInstr *ChainMI = Chain->getInstr(); + const TargetInstrDesc &ChainTID = ChainMI->getDesc(); + if (!ChainTID.isCall() && !ChainTID.isReturn() && !ChainTID.isBranch() && + !ChainTID.hasUnmodeledSideEffects() && + ChainMI->hasOneMemOperand() && + !ChainMI->memoperands_begin()->isVolatile() && + ChainMI->memoperands_begin()->getValue()) + // We know that the Chain accesses one specific memory location. + ChainMMO = &*ChainMI->memoperands_begin(); + else + // Unknown memory accesses. Assume the worst. + ChainMMO = 0; + } else if (TID.mayStore()) { + if (MI->hasOneMemOperand() && + MI->memoperands_begin()->getValue() && + !MI->memoperands_begin()->isVolatile() && + isa(MI->memoperands_begin()->getValue())) { + // A store to a specific PseudoSourceValue. Add precise dependencies. + const Value *V = MI->memoperands_begin()->getValue(); + // Handle the def in MemDefs, if there is one. + std::map::iterator I = MemDefs.find(V); + if (I != MemDefs.end()) { + I->second->addPred(SU, /*isCtrl=*/true, /*isArtificial=*/false); + I->second = SU; + } else { + MemDefs[V] = SU; + } + // Handle the uses in MemUses, if there are any. + std::map >::iterator J = MemUses.find(V); + if (J != MemUses.end()) { + for (unsigned i = 0, e = J->second.size(); i != e; ++i) + J->second[i]->addPred(SU, /*isCtrl=*/true, /*isArtificial=*/false); + J->second.clear(); + } + // Add a general dependence too, if needed. + if (Chain) + Chain->addPred(SU, /*isCtrl=*/true, /*isArtificial=*/false); + } else + // Treat all other stores conservatively. + goto new_chain; + } else if (TID.mayLoad()) { + if (TII->isInvariantLoad(MI)) { + // Invariant load, no chain dependencies needed! + } else if (MI->hasOneMemOperand() && + MI->memoperands_begin()->getValue() && + !MI->memoperands_begin()->isVolatile() && + isa(MI->memoperands_begin()->getValue())) { + // A load from a specific PseudoSourceValue. Add precise dependencies. + const Value *V = MI->memoperands_begin()->getValue(); + std::map::iterator I = MemDefs.find(V); + if (I != MemDefs.end()) + I->second->addPred(SU, /*isCtrl=*/true, /*isArtificial=*/false); + MemUses[V].push_back(SU); + + // Add a general dependence too, if needed. + if (Chain && (!ChainMMO || + (ChainMMO->isStore() || ChainMMO->isVolatile()))) + Chain->addPred(SU, /*isCtrl=*/true, /*isArtificial=*/false); + } else if (MI->hasVolatileMemoryRef()) { + // Treat volatile loads conservatively. Note that this includes + // cases where memoperand information is unavailable. + goto new_chain; + } else { + // A normal load. Just depend on the general chain. + if (Chain) + Chain->addPred(SU, /*isCtrl=*/true, /*isArtificial=*/false); + PendingLoads.push_back(SU); + } } + + // Add chain edges from the terminator to ensure that all the work of the block is + // completed before any control transfers. if (Terminator && SU->Succs.empty()) Terminator->addPred(SU, /*isCtrl=*/true, /*isArtificial=*/false); - if (MI->getDesc().isTerminator() || MI->isLabel()) + if (TID.isTerminator() || MI->isLabel()) Terminator = SU; // Assign the Latency field of SU using target-provided information. From gohman at apple.com Wed Dec 3 19:39:52 2008 From: gohman at apple.com (Dan Gohman) Date: Thu, 04 Dec 2008 01:39:52 -0000 Subject: [llvm-commits] [test-suite] r60518 - /test-suite/trunk/Makefile.programs Message-ID: <200812040139.mB41dqFJ007573@zion.cs.uiuc.edu> Author: djg Date: Wed Dec 3 19:39:52 2008 New Revision: 60518 URL: http://llvm.org/viewvc/llvm-project?rev=60518&view=rev Log: Test post-RA scheduling with anti-dependence breaking with LLCBETA. Currently this also requires tail-merging to be disabled because tail-merging does not properly update block live-in information. Modified: test-suite/trunk/Makefile.programs Modified: test-suite/trunk/Makefile.programs URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.programs?rev=60518&r1=60517&r2=60518&view=diff ============================================================================== --- test-suite/trunk/Makefile.programs (original) +++ test-suite/trunk/Makefile.programs Wed Dec 3 19:39:52 2008 @@ -226,7 +226,7 @@ LLCBETAOPTION := -sched=simple endif ifeq ($(ARCH),x86) -LLCBETAOPTION := -disable-post-RA-scheduler=false +LLCBETAOPTION := -disable-post-RA-scheduler=false -break-anti-dependencies -enable-tail-merge=false #-machine-licm #-fast-isel #-aggressive-remat From evan.cheng at apple.com Wed Dec 3 19:56:51 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 04 Dec 2008 01:56:51 -0000 Subject: [llvm-commits] [llvm] r60519 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp lib/Target/PowerPC/PPCSubtarget.cpp lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp lib/Target/X86/X86Subtarget.cpp test/CodeGen/X86/hidden-vis-2.ll Message-ID: <200812040156.mB41up9h008099@zion.cs.uiuc.edu> Author: evancheng Date: Wed Dec 3 19:56:50 2008 New Revision: 60519 URL: http://llvm.org/viewvc/llvm-project?rev=60519&view=rev Log: Visibility hidden GVs do not require extra load of symbol address from the GOT or non-lazy-ptr. Added: llvm/trunk/test/CodeGen/X86/hidden-vis-2.ll Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp llvm/trunk/lib/Target/X86/X86Subtarget.cpp Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=60519&r1=60518&r2=60519&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Wed Dec 3 19:56:50 2008 @@ -830,7 +830,7 @@ /// GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol /// even in non-static mode. static bool GVIsIndirectSymbol(GlobalValue *GV, Reloc::Model RelocM) { - return RelocM != Reloc::Static && + return RelocM != Reloc::Static && !GV->hasHiddenVisibility() && (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || (GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode())); } Modified: llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp?rev=60519&r1=60518&r2=60519&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp Wed Dec 3 19:56:50 2008 @@ -387,8 +387,9 @@ // External or weakly linked global variables need non-lazily-resolved stubs if (TM.getRelocationModel() != Reloc::Static) { - if (((GV->isDeclaration() || GV->hasWeakLinkage() || - GV->hasLinkOnceLinkage() || GV->hasCommonLinkage()))) { + if (!GV->hasHiddenVisibility() && + (GV->isDeclaration() || GV->hasWeakLinkage() || + GV->hasLinkOnceLinkage() || GV->hasCommonLinkage())) { GVStubs.insert(Name); printSuffixedName(Name, "$non_lazy_ptr"); if (GV->hasExternalWeakLinkage()) Modified: llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp?rev=60519&r1=60518&r2=60519&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp Wed Dec 3 19:56:50 2008 @@ -141,7 +141,9 @@ // We never hae stubs if HasLazyResolverStubs=false or if in static mode. if (!HasLazyResolverStubs || TM.getRelocationModel() == Reloc::Static) return false; - + // Extra load is not needed for symbols with hidden visibility. + if (GV->hasHiddenVisibility()) + return false; return GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || GV->hasCommonLinkage() || (GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode()); Modified: llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp?rev=60519&r1=60518&r2=60519&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp Wed Dec 3 19:56:50 2008 @@ -391,6 +391,8 @@ FnStubs.insert(Name); printSuffixedName(Name, "$stub"); } + } else if (GV->hasHiddenVisibility()) { + O << Name; } else { GVStubs.insert(Name); printSuffixedName(Name, "$non_lazy_ptr"); Modified: llvm/trunk/lib/Target/X86/X86Subtarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.cpp?rev=60519&r1=60518&r2=60519&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Subtarget.cpp (original) +++ llvm/trunk/lib/Target/X86/X86Subtarget.cpp Wed Dec 3 19:56:50 2008 @@ -40,6 +40,9 @@ if (TM.getRelocationModel() != Reloc::Static && TM.getCodeModel() != CodeModel::Large) { if (isTargetDarwin()) { + if (GV->hasHiddenVisibility()) + // Extra load is not needed for symbols with hidden visibility. + return false; return (!isDirectCall && (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || GV->hasCommonLinkage() || Added: llvm/trunk/test/CodeGen/X86/hidden-vis-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/hidden-vis-2.ll?rev=60519&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/hidden-vis-2.ll (added) +++ llvm/trunk/test/CodeGen/X86/hidden-vis-2.ll Wed Dec 3 19:56:50 2008 @@ -0,0 +1,10 @@ +; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep mov | count 1 +; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin9 | not grep GOT + + at x = weak hidden global i32 0 ; [#uses=1] + +define i32 @t() nounwind readonly { +entry: + %0 = load i32* @x, align 4 ; [#uses=1] + ret i32 %0 +} From gohman at apple.com Wed Dec 3 20:14:58 2008 From: gohman at apple.com (Dan Gohman) Date: Thu, 04 Dec 2008 02:14:58 -0000 Subject: [llvm-commits] [llvm] r60524 - /llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Message-ID: <200812040214.mB42Ew0R008669@zion.cs.uiuc.edu> Author: djg Date: Wed Dec 3 20:14:57 2008 New Revision: 60524 URL: http://llvm.org/viewvc/llvm-project?rev=60524&view=rev Log: Make debug output more informative. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=60524&r1=60523&r2=60524&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Wed Dec 3 20:14:57 2008 @@ -1300,7 +1300,7 @@ (hasCopyToRegUse(SU) && !hasCopyToRegUse(SuccSU)) || (!SU->isCommutable && SuccSU->isCommutable)) && !scheduleDAG->IsReachable(SuccSU, SU)) { - DOUT << "Adding an edge from SU # " << SU->NodeNum + DOUT << "Adding a pseudo-two-addr edge from SU # " << SU->NodeNum << " to SU #" << SuccSU->NodeNum << "\n"; scheduleDAG->AddPred(SU, SuccSU, true, true); } From gohman at apple.com Wed Dec 3 20:15:26 2008 From: gohman at apple.com (Dan Gohman) Date: Thu, 04 Dec 2008 02:15:26 -0000 Subject: [llvm-commits] [llvm] r60525 - /llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Message-ID: <200812040215.mB42FRsM008694@zion.cs.uiuc.edu> Author: djg Date: Wed Dec 3 20:15:26 2008 New Revision: 60525 URL: http://llvm.org/viewvc/llvm-project?rev=60525&view=rev Log: Use register names instead of numbers in debug output. Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=60525&r1=60524&r2=60525&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Wed Dec 3 20:15:26 2008 @@ -428,9 +428,10 @@ "Kill and Def maps aren't consistent for NewReg!"); if (KillIndices[NewReg] == -1u && KillIndices[AntiDepReg] <= DefIndices[NewReg]) { - DOUT << "Breaking anti-dependence edge on reg " << AntiDepReg + DOUT << "Breaking anti-dependence edge on " + << TRI->getName(AntiDepReg) << " with " << RegRefs.count(AntiDepReg) << " references" - << " with new reg " << NewReg << "!\n"; + << " using " << TRI->getName(NewReg) << "!\n"; // Update the references to the old register to refer to the new // register. From scottm at aero.org Wed Dec 3 21:02:42 2008 From: scottm at aero.org (Scott Michel) Date: Thu, 04 Dec 2008 03:02:42 -0000 Subject: [llvm-commits] [llvm] r60526 - in /llvm/trunk/lib/Target/CellSPU: SPUISelDAGToDAG.cpp SPUISelLowering.cpp SPUISelLowering.h SPUInstrInfo.td SPUNodes.td Message-ID: <200812040302.mB432gkh009949@zion.cs.uiuc.edu> Author: pingbak Date: Wed Dec 3 21:02:42 2008 New Revision: 60526 URL: http://llvm.org/viewvc/llvm-project?rev=60526&view=rev Log: CellSPU: - First patch from Nehal Desai, a new contributor at Aerospace. Nehal's patch fixes sign/zero/any-extending loads for integers and floating point. Example code, compiled w/o debugging or optimization where he first noticed the bug: int main(void) { float a = 99.0; printf("%d\n", a); return 0; } Verified that this code actually works on a Cell SPU. Changes by Scott Michel: - Fix bug in the value type list constructed by SPUISD::LDRESULT to include both the load result's result and chain, not just the chain alone. - Simplify LowerLOAD and remove extraneous and unnecessary chains. - Remove unused SPUISD pseudo instructions. Modified: llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td llvm/trunk/lib/Target/CellSPU/SPUNodes.td Modified: llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp?rev=60526&r1=60525&r2=60526&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelDAGToDAG.cpp Wed Dec 3 21:02:42 2008 @@ -676,7 +676,7 @@ Result = CurDAG->getTargetNode(Opc, VT, MVT::Other, Arg, Zero, Chain); } else { - Result = CurDAG->getTargetNode(Opc, MVT::Other, Arg, Arg, Chain); + Result = CurDAG->getTargetNode(Opc, VT, MVT::Other, Arg, Arg, Chain); } Chain = SDValue(Result, 1); Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=60526&r1=60525&r2=60526&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Wed Dec 3 21:02:42 2008 @@ -436,12 +436,6 @@ node_names[(unsigned) SPUISD::CNTB] = "SPUISD::CNTB"; node_names[(unsigned) SPUISD::PROMOTE_SCALAR] = "SPUISD::PROMOTE_SCALAR"; node_names[(unsigned) SPUISD::VEC2PREFSLOT] = "SPUISD::VEC2PREFSLOT"; - node_names[(unsigned) SPUISD::VEC2PREFSLOT_CHAINED] - = "SPUISD::VEC2PREFSLOT_CHAINED"; - node_names[(unsigned) SPUISD::EXTRACT_I1_ZEXT] = "SPUISD::EXTRACT_I1_ZEXT"; - node_names[(unsigned) SPUISD::EXTRACT_I1_SEXT] = "SPUISD::EXTRACT_I1_SEXT"; - node_names[(unsigned) SPUISD::EXTRACT_I8_ZEXT] = "SPUISD::EXTRACT_I8_ZEXT"; - node_names[(unsigned) SPUISD::EXTRACT_I8_SEXT] = "SPUISD::EXTRACT_I8_SEXT"; node_names[(unsigned) SPUISD::MPY] = "SPUISD::MPY"; node_names[(unsigned) SPUISD::MPYU] = "SPUISD::MPYU"; node_names[(unsigned) SPUISD::MPYH] = "SPUISD::MPYH"; @@ -458,8 +452,6 @@ node_names[(unsigned) SPUISD::ROTQUAD_RZ_BITS] = "SPUISD::ROTQUAD_RZ_BITS"; node_names[(unsigned) SPUISD::ROTBYTES_LEFT] = "SPUISD::ROTBYTES_LEFT"; - node_names[(unsigned) SPUISD::ROTBYTES_LEFT_CHAINED] = - "SPUISD::ROTBYTES_LEFT_CHAINED"; node_names[(unsigned) SPUISD::ROTBYTES_LEFT_BITS] = "SPUISD::ROTBYTES_LEFT_BITS"; node_names[(unsigned) SPUISD::SELECT_MASK] = "SPUISD::SELECT_MASK"; @@ -597,13 +589,24 @@ /*! All CellSPU loads and stores are aligned to 16-byte boundaries, so for elements within a 16-byte block, we have to rotate to extract the requested element. - */ + + For extending loads, we also want to ensure that the following sequence is + emitted, e.g. for MVT::f32 extending load to MVT::f64: + +\verbatim +%1 v16i8,ch = load +%2 v16i8,ch = rotate %1 +%3 v4f8, ch = bitconvert %2 +%4 f32 = vec2perfslot %3 +%5 f64 = fp_extend %4 +\endverbatim +*/ static SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) { LoadSDNode *LN = cast(Op); SDValue the_chain = LN->getChain(); - MVT VT = LN->getMemoryVT(); - MVT OpVT = Op.getNode()->getValueType(0); + MVT InVT = LN->getMemoryVT(); + MVT OutVT = Op.getValueType(); ISD::LoadExtType ExtType = LN->getExtensionType(); unsigned alignment = LN->getAlignment(); SDValue Ops[8]; @@ -613,7 +616,8 @@ int offset, rotamt; bool was16aligned; SDValue result = - AlignedLoad(Op, DAG, ST, LN,alignment, offset, rotamt, VT, was16aligned); + AlignedLoad(Op, DAG, ST, LN,alignment, offset, rotamt, InVT, + was16aligned); if (result.getNode() == 0) return result; @@ -625,57 +629,40 @@ if (rotamt != 0 || !was16aligned) { SDVTList vecvts = DAG.getVTList(MVT::v16i8, MVT::Other); - Ops[0] = the_chain; - Ops[1] = result; + Ops[0] = result; if (was16aligned) { - Ops[2] = DAG.getConstant(rotamt, MVT::i16); + Ops[1] = DAG.getConstant(rotamt, MVT::i16); } else { MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); LoadSDNode *LN1 = cast(result); - Ops[2] = DAG.getNode(ISD::ADD, PtrVT, LN1->getBasePtr(), + Ops[1] = DAG.getNode(ISD::ADD, PtrVT, LN1->getBasePtr(), DAG.getConstant(rotamt, PtrVT)); } - result = DAG.getNode(SPUISD::ROTBYTES_LEFT_CHAINED, vecvts, Ops, 3); - the_chain = result.getValue(1); + result = DAG.getNode(SPUISD::ROTBYTES_LEFT, MVT::v16i8, Ops, 2); } - if (VT == OpVT || ExtType == ISD::EXTLOAD) { - SDVTList scalarvts; - MVT vecVT = MVT::v16i8; - - // Convert the loaded v16i8 vector to the appropriate vector type - // specified by the operand: - if (OpVT == VT) { - if (VT != MVT::i1) - vecVT = MVT::getVectorVT(VT, (128 / VT.getSizeInBits())); - } else - vecVT = MVT::getVectorVT(OpVT, (128 / OpVT.getSizeInBits())); + // Convert the loaded v16i8 vector to the appropriate vector type + // specified by the operand: + MVT vecVT = MVT::getVectorVT(InVT, (128 / InVT.getSizeInBits())); + result = DAG.getNode(SPUISD::VEC2PREFSLOT, InVT, + DAG.getNode(ISD::BIT_CONVERT, vecVT, result)); - Ops[0] = the_chain; - Ops[1] = DAG.getNode(ISD::BIT_CONVERT, vecVT, result); - scalarvts = DAG.getVTList((OpVT == VT ? VT : OpVT), MVT::Other); - result = DAG.getNode(SPUISD::VEC2PREFSLOT_CHAINED, scalarvts, Ops, 2); - the_chain = result.getValue(1); - } else { - // Handle the sign and zero-extending loads for i1 and i8: - unsigned NewOpC; + // Handle extending loads by extending the scalar result: + if (ExtType == ISD::SEXTLOAD) { + result = DAG.getNode(ISD::SIGN_EXTEND, OutVT, result); + } else if (ExtType == ISD::ZEXTLOAD) { + result = DAG.getNode(ISD::ZERO_EXTEND, OutVT, result); + } else if (ExtType == ISD::EXTLOAD) { + unsigned NewOpc = ISD::ANY_EXTEND; - if (ExtType == ISD::SEXTLOAD) { - NewOpC = (OpVT == MVT::i1 - ? SPUISD::EXTRACT_I1_SEXT - : SPUISD::EXTRACT_I8_SEXT); - } else { - assert(ExtType == ISD::ZEXTLOAD); - NewOpC = (OpVT == MVT::i1 - ? SPUISD::EXTRACT_I1_ZEXT - : SPUISD::EXTRACT_I8_ZEXT); - } + if (OutVT.isFloatingPoint()) + NewOpc = ISD::FP_EXTEND; - result = DAG.getNode(NewOpC, OpVT, result); + result = DAG.getNode(NewOpc, OutVT, result); } - SDVTList retvts = DAG.getVTList(OpVT, MVT::Other); + SDVTList retvts = DAG.getVTList(OutVT, MVT::Other); SDValue retops[2] = { result, the_chain @@ -3034,10 +3021,16 @@ SDValue combinedConst = DAG.getConstant(CN0->getZExtValue() + CN1->getZExtValue(), Op0VT); - DEBUG(cerr << "Replace: (add " << CN0->getZExtValue() << ", " - << "(SPUindirect , " << CN1->getZExtValue() << "))\n"); - DEBUG(cerr << "With: (SPUindirect , " - << CN0->getZExtValue() + CN1->getZExtValue() << ")\n"); +#if defined(NDEBUG) + if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) { + cerr << "\n" + << "Replace: (add " << CN0->getZExtValue() << ", " + << "(SPUindirect , " << CN1->getZExtValue() << "))\n" + << "With: (SPUindirect , " + << CN0->getZExtValue() + CN1->getZExtValue() << ")\n"; + } +#endif + return DAG.getNode(SPUISD::IndirectAddr, Op0VT, Op0.getOperand(0), combinedConst); } @@ -3071,11 +3064,14 @@ // (any_extend (SPUextract_elt0 )) -> // (SPUextract_elt0 ) // Types must match, however... - DEBUG(cerr << "Replace: "); - DEBUG(N->dump(&DAG)); - DEBUG(cerr << "\nWith: "); - DEBUG(Op0.getNode()->dump(&DAG)); - DEBUG(cerr << "\n"); +#if defined(NDEBUG) + if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) { + cerr << "\nReplace: "; + N->dump(&DAG); + cerr << "\nWith: "; + Op0.getNode()->dump(&DAG); + cerr << "\n"; +#endif return Op0; } @@ -3243,8 +3239,7 @@ } case SPUISD::LDRESULT: - case SPUISD::VEC2PREFSLOT: - case SPUISD::VEC2PREFSLOT_CHAINED: { + case SPUISD::VEC2PREFSLOT: { MVT OpVT = Op.getValueType(); unsigned OpVTBits = OpVT.getSizeInBits(); uint64_t InMask = OpVT.getIntegerVTBitMask(); @@ -3254,10 +3249,6 @@ } #if 0 - case EXTRACT_I1_ZEXT: - case EXTRACT_I1_SEXT: - case EXTRACT_I8_ZEXT: - case EXTRACT_I8_SEXT: case MPY: case MPYU: case MPYH: @@ -3272,7 +3263,6 @@ case SPUISD::ROTQUAD_RZ_BYTES: case SPUISD::ROTQUAD_RZ_BITS: case SPUISD::ROTBYTES_LEFT: - case SPUISD::ROTBYTES_LEFT_CHAINED: case SPUISD::SELECT_MASK: case SPUISD::SELB: case SPUISD::FPInterp: Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h?rev=60526&r1=60525&r2=60526&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.h Wed Dec 3 21:02:42 2008 @@ -41,11 +41,6 @@ CNTB, ///< Count leading ones in bytes PROMOTE_SCALAR, ///< Promote scalar->vector VEC2PREFSLOT, ///< Extract element 0 - VEC2PREFSLOT_CHAINED, ///< Extract element 0, with chain - EXTRACT_I1_ZEXT, ///< Extract element 0 as i1, zero extend - EXTRACT_I1_SEXT, ///< Extract element 0 as i1, sign extend - EXTRACT_I8_ZEXT, ///< Extract element 0 as i8, zero extend - EXTRACT_I8_SEXT, ///< Extract element 0 as i8, sign extend MPY, ///< 16-bit Multiply (low parts of a 32-bit) MPYU, ///< Multiply Unsigned MPYH, ///< Multiply High @@ -60,7 +55,6 @@ ROTQUAD_RZ_BYTES, ///< Rotate quad right, by bytes, zero fill ROTQUAD_RZ_BITS, ///< Rotate quad right, by bits, zero fill ROTBYTES_LEFT, ///< Rotate bytes (loads -> ROTQBYI) - ROTBYTES_LEFT_CHAINED, ///< Rotate bytes (loads -> ROTQBYI), with chain ROTBYTES_LEFT_BITS, ///< Rotate bytes left by bit shift count SELECT_MASK, ///< Select Mask (FSM, FSMB, FSMH, FSMBI) SELB, ///< Select bits -> (b & mask) | (a & ~mask) Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td?rev=60526&r1=60525&r2=60526&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td (original) +++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td Wed Dec 3 21:02:42 2008 @@ -1288,39 +1288,21 @@ def : Pat<(SPUvec2prefslot (v16i8 VECREG:$rA)), (ORi8_v16i8 VECREG:$rA, VECREG:$rA)>; -def : Pat<(SPUvec2prefslot_chained (v16i8 VECREG:$rA)), - (ORi8_v16i8 VECREG:$rA, VECREG:$rA)>; - def : Pat<(SPUvec2prefslot (v8i16 VECREG:$rA)), (ORi16_v8i16 VECREG:$rA, VECREG:$rA)>; -def : Pat<(SPUvec2prefslot_chained (v8i16 VECREG:$rA)), - (ORi16_v8i16 VECREG:$rA, VECREG:$rA)>; - def : Pat<(SPUvec2prefslot (v4i32 VECREG:$rA)), (ORi32_v4i32 VECREG:$rA, VECREG:$rA)>; -def : Pat<(SPUvec2prefslot_chained (v4i32 VECREG:$rA)), - (ORi32_v4i32 VECREG:$rA, VECREG:$rA)>; - def : Pat<(SPUvec2prefslot (v2i64 VECREG:$rA)), (ORi64_v2i64 VECREG:$rA, VECREG:$rA)>; -def : Pat<(SPUvec2prefslot_chained (v2i64 VECREG:$rA)), - (ORi64_v2i64 VECREG:$rA, VECREG:$rA)>; - def : Pat<(SPUvec2prefslot (v4f32 VECREG:$rA)), (ORf32_v4f32 VECREG:$rA, VECREG:$rA)>; -def : Pat<(SPUvec2prefslot_chained (v4f32 VECREG:$rA)), - (ORf32_v4f32 VECREG:$rA, VECREG:$rA)>; - def : Pat<(SPUvec2prefslot (v2f64 VECREG:$rA)), (ORf64_v2f64 VECREG:$rA, VECREG:$rA)>; -def : Pat<(SPUvec2prefslot_chained (v2f64 VECREG:$rA)), - (ORf64_v2f64 VECREG:$rA, VECREG:$rA)>; - // ORC: Bitwise "or" with complement (c = a | ~b) class ORCInst pattern>: @@ -2147,15 +2129,6 @@ defm ROTQBY: RotateQuadLeftByBytes; -def : Pat<(SPUrotbytes_left_chained (v16i8 VECREG:$rA), R32C:$rB), - (ROTQBYv16i8 VECREG:$rA, R32C:$rB)>; -def : Pat<(SPUrotbytes_left_chained (v8i16 VECREG:$rA), R32C:$rB), - (ROTQBYv8i16 VECREG:$rA, R32C:$rB)>; -def : Pat<(SPUrotbytes_left_chained (v4i32 VECREG:$rA), R32C:$rB), - (ROTQBYv4i32 VECREG:$rA, R32C:$rB)>; -def : Pat<(SPUrotbytes_left_chained (v2i64 VECREG:$rA), R32C:$rB), - (ROTQBYv2i64 VECREG:$rA, R32C:$rB)>; - //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ // Rotate quad by byte (count), immediate //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ @@ -2179,15 +2152,6 @@ defm ROTQBYI: RotateQuadByBytesImm; -def : Pat<(SPUrotbytes_left_chained (v16i8 VECREG:$rA), (i16 uimm7:$val)), - (ROTQBYIv16i8 VECREG:$rA, uimm7:$val)>; -def : Pat<(SPUrotbytes_left_chained (v8i16 VECREG:$rA), (i16 uimm7:$val)), - (ROTQBYIv8i16 VECREG:$rA, uimm7:$val)>; -def : Pat<(SPUrotbytes_left_chained (v4i32 VECREG:$rA), (i16 uimm7:$val)), - (ROTQBYIv4i32 VECREG:$rA, uimm7:$val)>; -def : Pat<(SPUrotbytes_left_chained (v2i64 VECREG:$rA), (i16 uimm7:$val)), - (ROTQBYIv2i64 VECREG:$rA, uimm7:$val)>; - // See ROTQBY note above. class ROTQBYBIInst pattern>: RI7Form<0b00110011100, OOL, IOL, @@ -3972,10 +3936,6 @@ // Zero/Any/Sign extensions //===----------------------------------------------------------------------===// -// zext 1->32: Zero extend i1 to i32 -def : Pat<(SPUextract_i1_zext R32C:$rSrc), - (ANDIr32 R32C:$rSrc, 0x1)>; - // sext 8->32: Sign extend bytes to words def : Pat<(sext_inreg R32C:$rSrc, i8), (XSHWr32 (XSBHr32 R32C:$rSrc))>; @@ -3983,19 +3943,10 @@ def : Pat<(i32 (sext R8C:$rSrc)), (XSHWr16 (XSBHr8 R8C:$rSrc))>; -def : Pat<(SPUextract_i8_sext VECREG:$rSrc), - (XSHWr32 (XSBHr32 (ORi32_v4i32 (v4i32 VECREG:$rSrc), - (v4i32 VECREG:$rSrc))))>; - // zext 8->16: Zero extend bytes to halfwords def : Pat<(i16 (zext R8C:$rSrc)), (ANDHIi8i16 R8C:$rSrc, 0xff)>; -// zext 8->32 from preferred slot in load/store -def : Pat<(SPUextract_i8_zext VECREG:$rSrc), - (ANDIr32 (ORi32_v4i32 (v4i32 VECREG:$rSrc), (v4i32 VECREG:$rSrc)), - 0xff)>; - // zext 8->32: Zero extend bytes to words def : Pat<(i32 (zext R8C:$rSrc)), (ANDIi8i32 R8C:$rSrc, 0xff)>; Modified: llvm/trunk/lib/Target/CellSPU/SPUNodes.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUNodes.td?rev=60526&r1=60525&r2=60526&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUNodes.td (original) +++ llvm/trunk/lib/Target/CellSPU/SPUNodes.td Wed Dec 3 21:02:42 2008 @@ -125,11 +125,6 @@ def SPUrotbytes_left: SDNode<"SPUISD::ROTBYTES_LEFT", SPUvecshift_type, []>; -// Same as above, but the node also has a chain associated (used in loads and -// stores) -def SPUrotbytes_left_chained : SDNode<"SPUISD::ROTBYTES_LEFT_CHAINED", - SPUvecshift_type, [SDNPHasChain]>; - // Vector rotate left by bytes, but the count is given in bits and the SPU // internally converts it to bytes (saves an instruction to mask off lower // three bits) @@ -153,13 +148,6 @@ def SPU_vec_demote : SDTypeProfile<1, 1, []>; def SPUvec2prefslot: SDNode<"SPUISD::VEC2PREFSLOT", SPU_vec_demote, []>; -def SPU_vec_demote_chained : SDTypeProfile<1, 2, []>; -def SPUvec2prefslot_chained: SDNode<"SPUISD::VEC2PREFSLOT_CHAINED", - SPU_vec_demote_chained, [SDNPHasChain]>; -def SPUextract_i1_sext: SDNode<"SPUISD::EXTRACT_I1_SEXT", SPU_vec_demote, []>; -def SPUextract_i1_zext: SDNode<"SPUISD::EXTRACT_I1_ZEXT", SPU_vec_demote, []>; -def SPUextract_i8_sext: SDNode<"SPUISD::EXTRACT_I8_SEXT", SPU_vec_demote, []>; -def SPUextract_i8_zext: SDNode<"SPUISD::EXTRACT_I8_ZEXT", SPU_vec_demote, []>; // Address high and low components, used for [r+r] type addressing def SPUhi : SDNode<"SPUISD::Hi", SDTIntBinOp, []>; From clattner at apple.com Wed Dec 3 22:02:59 2008 From: clattner at apple.com (Chris Lattner) Date: Wed, 3 Dec 2008 20:02:59 -0800 Subject: [llvm-commits] [llvm] r60519 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp lib/Target/PowerPC/PPCSubtarget.cpp lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp lib/Target/X86/X86Subtarget.cpp test/CodeGen/X86/hidden-vis-2.ll In-Reply-To: <200812040156.mB41up9h008099@zion.cs.uiuc.edu> References: <200812040156.mB41up9h008099@zion.cs.uiuc.edu> Message-ID: <1C01C792-5B21-4E8C-8941-0B55E7EDE55A@apple.com> On Dec 3, 2008, at 5:56 PM, Evan Cheng wrote: > Author: evancheng > Date: Wed Dec 3 19:56:50 2008 > New Revision: 60519 > > URL: http://llvm.org/viewvc/llvm-project?rev=60519&view=rev > Log: > Visibility hidden GVs do not require extra load of symbol address > from the GOT or non-lazy-ptr. Nifty, does this fix: http://llvm.org/bugs/show_bug.cgi?id=3148 ? -Chris From isanbard at gmail.com Wed Dec 3 22:07:03 2008 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 04 Dec 2008 04:07:03 -0000 Subject: [llvm-commits] [llvm] r60527 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp lib/Target/PowerPC/PPCSubtarget.cpp lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp lib/Target/X86/X86Subtarget.cpp test/CodeGen/X86/hidden-vis-2.ll Message-ID: <200812040407.mB4473w2011637@zion.cs.uiuc.edu> Author: void Date: Wed Dec 3 22:07:00 2008 New Revision: 60527 URL: http://llvm.org/viewvc/llvm-project?rev=60527&view=rev Log: Temporarily revert r60519. It was causing a bootstrap failure: /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm-gcc.obj/./gcc/xgcc -B/Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm-gcc.obj/./gcc/ -B/Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm-gcc.install/i386-apple-darwin9.5.0/bin/ -B/Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm-gcc.install/i386-apple-darwin9.5.0/lib/ -isystem /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm-gcc.install/i386-apple-darwin9.5.0/include -isystem /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm-gcc.install/i386-apple-darwin9.5.0/sys-include -DHAVE_CONFIG_H -I. -I../../../llvm-gcc.src/libgomp -I. -I../../../llvm-gcc.src/libgomp/config/posix -I../../../llvm-gcc.src/libgomp -Wall -pthread -Werror -O2 -g -O2 -MT barrier.lo -MD -MP -MF .deps/barrier.Tpo -c ../../../llvm-gcc.src/libgomp/barrier.c -fno-common -DPIC -o .libs/barrier.o checking for sys/file.h... /var/folders/zG/zGE-ZJOGFiGjv0B5cs5oYE+++TM/-Tmp-//cc34Jg5P.s:13:non-relocatable subtraction expression, "_gomp_tls_key" minus "L1$pb" /var/folders/zG/zGE-ZJOGFiGjv0B5cs5oYE+++TM/-Tmp-//cc34Jg5P.s:13:symbol: "_gomp_tls_key" can't be undefined in a subtraction expression make[4]: *** [barrier.lo] Error 1 make[4]: *** Waiting for unfinished jobs.... /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm-gcc.obj/./gcc/xgcc -B/Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm-gcc.obj/./gcc/ -B/Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm-gcc.install/i386-apple-darwin9.5.0/bin/ -B/Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm-gcc.install/i386-apple-darwin9.5.0/lib/ -isystem /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm-gcc.install/i386-apple-darwin9.5.0/include -isystem /Volumes/Sandbox/Buildbot/llvm/full-llvm/build/llvm-gcc.install/i386-apple-darwin9.5.0/sys-include -DHAVE_CONFIG_H -I. -I../../../llvm-gcc.src/libgomp -I. -I../../../llvm-gcc.src/libgomp/config/posix -I../../../llvm-gcc.src/libgomp -Wall -pthread -Werror -O2 -g -O2 -MT alloc.lo -MD -MP -MF .deps/alloc.Tpo -c ../../../llvm-gcc.src/libgomp/alloc.c -o alloc.o >/dev/null 2>&1 yes checking for sys/param.h... make[3]: *** [all-recursive] Error 1 make[2]: *** [all] Error 2 make[1]: *** [all-target-libgomp] Error 2 make[1]: *** Waiting for unfinished jobs.... Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp llvm/trunk/lib/Target/X86/X86Subtarget.cpp llvm/trunk/test/CodeGen/X86/hidden-vis-2.ll Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=60527&r1=60526&r2=60527&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Wed Dec 3 22:07:00 2008 @@ -830,7 +830,7 @@ /// GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol /// even in non-static mode. static bool GVIsIndirectSymbol(GlobalValue *GV, Reloc::Model RelocM) { - return RelocM != Reloc::Static && !GV->hasHiddenVisibility() && + return RelocM != Reloc::Static && (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || (GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode())); } Modified: llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp?rev=60527&r1=60526&r2=60527&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp Wed Dec 3 22:07:00 2008 @@ -387,9 +387,8 @@ // External or weakly linked global variables need non-lazily-resolved stubs if (TM.getRelocationModel() != Reloc::Static) { - if (!GV->hasHiddenVisibility() && - (GV->isDeclaration() || GV->hasWeakLinkage() || - GV->hasLinkOnceLinkage() || GV->hasCommonLinkage())) { + if (((GV->isDeclaration() || GV->hasWeakLinkage() || + GV->hasLinkOnceLinkage() || GV->hasCommonLinkage()))) { GVStubs.insert(Name); printSuffixedName(Name, "$non_lazy_ptr"); if (GV->hasExternalWeakLinkage()) Modified: llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp?rev=60527&r1=60526&r2=60527&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp Wed Dec 3 22:07:00 2008 @@ -141,9 +141,7 @@ // We never hae stubs if HasLazyResolverStubs=false or if in static mode. if (!HasLazyResolverStubs || TM.getRelocationModel() == Reloc::Static) return false; - // Extra load is not needed for symbols with hidden visibility. - if (GV->hasHiddenVisibility()) - return false; + return GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || GV->hasCommonLinkage() || (GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode()); Modified: llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp?rev=60527&r1=60526&r2=60527&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp Wed Dec 3 22:07:00 2008 @@ -391,8 +391,6 @@ FnStubs.insert(Name); printSuffixedName(Name, "$stub"); } - } else if (GV->hasHiddenVisibility()) { - O << Name; } else { GVStubs.insert(Name); printSuffixedName(Name, "$non_lazy_ptr"); Modified: llvm/trunk/lib/Target/X86/X86Subtarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.cpp?rev=60527&r1=60526&r2=60527&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Subtarget.cpp (original) +++ llvm/trunk/lib/Target/X86/X86Subtarget.cpp Wed Dec 3 22:07:00 2008 @@ -40,9 +40,6 @@ if (TM.getRelocationModel() != Reloc::Static && TM.getCodeModel() != CodeModel::Large) { if (isTargetDarwin()) { - if (GV->hasHiddenVisibility()) - // Extra load is not needed for symbols with hidden visibility. - return false; return (!isDirectCall && (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || GV->hasCommonLinkage() || Modified: llvm/trunk/test/CodeGen/X86/hidden-vis-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/hidden-vis-2.ll?rev=60527&r1=60526&r2=60527&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/hidden-vis-2.ll (original) +++ llvm/trunk/test/CodeGen/X86/hidden-vis-2.ll Wed Dec 3 22:07:00 2008 @@ -1,5 +1,6 @@ ; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep mov | count 1 ; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin9 | not grep GOT +; XFAIL: * @x = weak hidden global i32 0 ; [#uses=1] From sabre at nondot.org Wed Dec 3 23:06:17 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 04 Dec 2008 05:06:17 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60528 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200812040506.mB456Hnp013246@zion.cs.uiuc.edu> Author: lattner Date: Wed Dec 3 23:06:14 2008 New Revision: 60528 URL: http://llvm.org/viewvc/llvm-project?rev=60528&view=rev Log: lower builtin_object_size result to the correct integer intptr_t width. This returns -1 as -1 on 64-bit targets instead of as 4294967295. rdar://6416760 Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=60528&r1=60527&r2=60528&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Wed Dec 3 23:06:14 2008 @@ -4575,9 +4575,9 @@ } if (tree_low_cst (ObjSizeTree, 0) < 2) - Result = ConstantInt::getAllOnesValue(Type::Int32Ty); + Result = ConstantInt::getAllOnesValue(TD.getIntPtrType()); else - Result = ConstantInt::get(Type::Int32Ty, 0); + Result = ConstantInt::get(TD.getIntPtrType(), 0); return true; } // Unary bit counting intrinsics. From isanbard at gmail.com Wed Dec 3 23:08:40 2008 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 04 Dec 2008 05:08:40 -0000 Subject: [llvm-commits] [llvm] r60529 - /llvm/tags/Apple/llvmCore-2087/ Message-ID: <200812040508.mB458enZ013316@zion.cs.uiuc.edu> Author: void Date: Wed Dec 3 23:08:40 2008 New Revision: 60529 URL: http://llvm.org/viewvc/llvm-project?rev=60529&view=rev Log: Creating llvmCore-2087 branch Added: llvm/tags/Apple/llvmCore-2087/ - copied from r60528, llvm/trunk/ From isanbard at gmail.com Wed Dec 3 23:08:49 2008 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 04 Dec 2008 05:08:49 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60530 - /llvm-gcc-4.2/tags/Apple/llvmgcc42-2087/ Message-ID: <200812040508.mB458nFi013337@zion.cs.uiuc.edu> Author: void Date: Wed Dec 3 23:08:49 2008 New Revision: 60530 URL: http://llvm.org/viewvc/llvm-project?rev=60530&view=rev Log: Creating llvmgcc42-2087 branch Added: llvm-gcc-4.2/tags/Apple/llvmgcc42-2087/ - copied from r60529, llvm-gcc-4.2/trunk/ From dpatel at apple.com Wed Dec 3 23:19:42 2008 From: dpatel at apple.com (Devang Patel) Date: Thu, 04 Dec 2008 05:19:42 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60531 - /llvm-gcc-4.2/trunk/gcc/config/i386/driver-i386.c Message-ID: <200812040519.mB45JhsM013614@zion.cs.uiuc.edu> Author: dpatel Date: Wed Dec 3 23:19:42 2008 New Revision: 60531 URL: http://llvm.org/viewvc/llvm-project?rev=60531&view=rev Log: Fix universal bootstrap on a ppc host. Modified: llvm-gcc-4.2/trunk/gcc/config/i386/driver-i386.c Modified: llvm-gcc-4.2/trunk/gcc/config/i386/driver-i386.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/driver-i386.c?rev=60531&r1=60530&r2=60531&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/i386/driver-i386.c (original) +++ llvm-gcc-4.2/trunk/gcc/config/i386/driver-i386.c Wed Dec 3 23:19:42 2008 @@ -26,6 +26,8 @@ const char *host_detect_local_cpu (int argc, const char **argv); +/* LLVM LOCAL fix bootstrap failure on ppc host */ +#if defined(__i386__) || defined(__x86_64__) #ifdef GCC_VERSION #define cpuid(num,a,b,c,d) \ asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \ @@ -298,3 +300,6 @@ return concat ("-m", argv[0], "=", cpu, NULL); } #endif /* GCC_VERSION */ +/* LLVM LOCAL fix bootstrap failure on ppc host */ +#endif + From sabre at nondot.org Thu Dec 4 00:14:27 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 04 Dec 2008 06:14:27 -0000 Subject: [llvm-commits] [llvm] r60532 - /llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Message-ID: <200812040614.mB46ERJY015229@zion.cs.uiuc.edu> Author: lattner Date: Thu Dec 4 00:14:27 2008 New Revision: 60532 URL: http://llvm.org/viewvc/llvm-project?rev=60532&view=rev Log: This code is apparently quite confused. In the meantime, get it building when NDEBUG is set. Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=60532&r1=60531&r2=60532&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Thu Dec 4 00:14:27 2008 @@ -3065,12 +3065,13 @@ // (SPUextract_elt0 ) // Types must match, however... #if defined(NDEBUG) - if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) { + // if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) { cerr << "\nReplace: "; N->dump(&DAG); cerr << "\nWith: "; Op0.getNode()->dump(&DAG); cerr << "\n"; + #endif return Op0; From sabre at nondot.org Thu Dec 4 00:16:47 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 04 Dec 2008 06:16:47 -0000 Subject: [llvm-commits] [test-suite] r60533 - /test-suite/trunk/External/SPEC/CINT2006/483.xalancbmk/Makefile Message-ID: <200812040616.mB46Gl8c015301@zion.cs.uiuc.edu> Author: lattner Date: Thu Dec 4 00:16:46 2008 New Revision: 60533 URL: http://llvm.org/viewvc/llvm-project?rev=60533&view=rev Log: get this working on mac os Modified: test-suite/trunk/External/SPEC/CINT2006/483.xalancbmk/Makefile Modified: test-suite/trunk/External/SPEC/CINT2006/483.xalancbmk/Makefile URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/External/SPEC/CINT2006/483.xalancbmk/Makefile?rev=60533&r1=60532&r2=60533&view=diff ============================================================================== --- test-suite/trunk/External/SPEC/CINT2006/483.xalancbmk/Makefile (original) +++ test-suite/trunk/External/SPEC/CINT2006/483.xalancbmk/Makefile Thu Dec 4 00:16:46 2008 @@ -5,6 +5,7 @@ ##===----------------------------------------------------------------------===## LEVEL = ../../../.. +include $(LEVEL)/Makefile.config CPPFLAGS += -DNDEBUG -DAPP_NO_THREADS -DXALAN_INMEM_MSG_LOADER \ -DPROJ_XMLPARSER -DPROJ_XMLUTIL -DPROJ_PARSERS \ From sabre at nondot.org Thu Dec 4 00:31:07 2008 From: sabre at nondot.org (Chris Lattner) Date: Thu, 04 Dec 2008 06:31:07 -0000 Subject: [llvm-commits] [llvm] r60534 - /llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Message-ID: <200812040631.mB46V962015710@zion.cs.uiuc.edu> Author: lattner Date: Thu Dec 4 00:31:07 2008 New Revision: 60534 URL: http://llvm.org/viewvc/llvm-project?rev=60534&view=rev Log: Start simplifying a switch that has a successor that is a switch. Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=60534&r1=60533&r2=60534&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Thu Dec 4 00:31:07 2008 @@ -73,6 +73,7 @@ void ThreadEdge(BasicBlock *BB, BasicBlock *PredBB, BasicBlock *SuccBB); BasicBlock *FactorCommonPHIPreds(PHINode *PN, Constant *CstVal); bool ProcessBranchOnDuplicateCond(BasicBlock *PredBB, BasicBlock *DestBB); + bool ProcessSwitchOnDuplicateCond(BasicBlock *PredBB, BasicBlock *DestBB); bool ProcessJumpOnPHI(PHINode *PN); bool ProcessBranchOnLogical(Value *V, BasicBlock *BB, bool isAnd); @@ -283,6 +284,13 @@ if (PBI->isConditional() && PBI->getCondition() == Condition && ProcessBranchOnDuplicateCond(*PI, BB)) return true; + } else { + assert(isa(BB->getTerminator()) && "Unknown jump terminator"); + for (; PI != E; ++PI) + if (SwitchInst *PSI = dyn_cast((*PI)->getTerminator())) + if (PSI->getCondition() == Condition && + ProcessSwitchOnDuplicateCond(*PI, BB)) + return true; } } @@ -412,6 +420,72 @@ return true; } +/// ProcessSwitchOnDuplicateCond - We found a block and a predecessor of that +/// block that switch on exactly the same condition. This means that we almost +/// always know the direction of the edge in the DESTBB: +/// PREDBB: +/// switch COND [... DESTBB, BBY ... ] +/// DESTBB: +/// switch COND [... BBZ, BBW ] +/// +/// Optimizing switches like this is very important, because simplifycfg builds +/// switches out of repeated 'if' conditions. +bool JumpThreading::ProcessSwitchOnDuplicateCond(BasicBlock *PredBB, + BasicBlock *DestBB) { + SwitchInst *PredSI = cast(PredBB->getTerminator()); + SwitchInst *DestSI = cast(DestBB->getTerminator()); + + // There are a variety of optimizations that we can potentially do on these + // blocks: we order them from most to least preferable. + + // If DESTBB *just* contains the switch, then we can forward edges from PREDBB + // directly to their destination. This does not introduce *any* code size + // growth. + + // FIXME: Thread if it just contains a PHI. + if (isa(DestBB->begin())) { + bool MadeChange = false; + // Ignore the default edge for now. + for (unsigned i = 1, e = DestSI->getNumSuccessors(); i != e; ++i) { + ConstantInt *DestVal = DestSI->getCaseValue(i); + BasicBlock *DestSucc = DestSI->getSuccessor(i); + + // Okay, DestSI has a case for 'DestVal' that goes to 'DestSucc'. See if + // PredSI has an explicit case for it. If so, forward. If it is covered + // by the default case, we can't update PredSI. + unsigned PredCase = PredSI->findCaseValue(DestVal); + if (PredCase == 0) continue; + + // If PredSI doesn't go to DestBB on this value, then it won't reach the + // case on this condition. + if (PredSI->getSuccessor(PredCase) != DestBB && + DestSI->getSuccessor(i) != DestBB) + continue; + + // Otherwise, we're safe to make the change. Make sure that the edge from + // DestSI to DestSucc is not critical and has no PHI nodes. + DOUT << "FORWARDING EDGE " << *DestVal << " FROM: " << *PredSI; + DOUT << "THROUGH: " << *DestSI; + + // If the destination has PHI nodes, just split the edge for updating + // simplicity. + if (isa(DestSucc->begin()) && !DestSucc->getSinglePredecessor()){ + SplitCriticalEdge(DestSI, i, this); + DestSucc = DestSI->getSuccessor(i); + } + FoldSingleEntryPHINodes(DestSucc); + PredSI->setSuccessor(PredCase, DestSucc); + MadeChange = true; + } + + if (MadeChange) + return true; + } + + return false; +} + + /// SimplifyPartiallyRedundantLoad - If LI is an obviously partially redundant /// load instruction, eliminate it by replacing it with a PHI node. This is an /// important optimization that encourages jump threading, and needs to be run From nicholas at mxc.ca Thu Dec 4 01:11:17 2008 From: nicholas at mxc.ca (Nick Lewycky) Date: Wed, 03 Dec 2008 23:11:17 -0800 Subject: [llvm-commits] [llvm] r60519 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp lib/Target/PowerPC/PPCSubtarget.cpp lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp lib/Target/X86/X86Subtarget.cpp test/CodeGen/X86/hidden-vis-2.ll In-Reply-To: <200812040156.mB41up9h008099@zion.cs.uiuc.edu> References: <200812040156.mB41up9h008099@zion.cs.uiuc.edu> Message-ID: <49378295.8060803@mxc.ca> Evan Cheng wrote: > Author: evancheng > Date: Wed Dec 3 19:56:50 2008 > New Revision: 60519 > > URL: http://llvm.org/viewvc/llvm-project?rev=60519&view=rev > Log: > Visibility hidden GVs do not require extra load of symbol address from the GOT or non-lazy-ptr. Thanks! You missed that the same optimization applies to protected symbols as well, probably because Darwin doesn't have them. Please update PR3148. Does this fix the issue on Linux as well? Nick > Added: > llvm/trunk/test/CodeGen/X86/hidden-vis-2.ll > Modified: > llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp > llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp > llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp > llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp > llvm/trunk/lib/Target/X86/X86Subtarget.cpp > > Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=60519&r1=60518&r2=60519&view=diff > > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Wed Dec 3 19:56:50 2008 > @@ -830,7 +830,7 @@ > /// GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol > /// even in non-static mode. > static bool GVIsIndirectSymbol(GlobalValue *GV, Reloc::Model RelocM) { > - return RelocM != Reloc::Static && > + return RelocM != Reloc::Static && !GV->hasHiddenVisibility() && > (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || > (GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode())); > } > > Modified: llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp?rev=60519&r1=60518&r2=60519&view=diff > > ============================================================================== > --- llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp (original) > +++ llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp Wed Dec 3 19:56:50 2008 > @@ -387,8 +387,9 @@ > > // External or weakly linked global variables need non-lazily-resolved stubs > if (TM.getRelocationModel() != Reloc::Static) { > - if (((GV->isDeclaration() || GV->hasWeakLinkage() || > - GV->hasLinkOnceLinkage() || GV->hasCommonLinkage()))) { > + if (!GV->hasHiddenVisibility() && > + (GV->isDeclaration() || GV->hasWeakLinkage() || > + GV->hasLinkOnceLinkage() || GV->hasCommonLinkage())) { > GVStubs.insert(Name); > printSuffixedName(Name, "$non_lazy_ptr"); > if (GV->hasExternalWeakLinkage()) > > Modified: llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp?rev=60519&r1=60518&r2=60519&view=diff > > ============================================================================== > --- llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp (original) > +++ llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp Wed Dec 3 19:56:50 2008 > @@ -141,7 +141,9 @@ > // We never hae stubs if HasLazyResolverStubs=false or if in static mode. > if (!HasLazyResolverStubs || TM.getRelocationModel() == Reloc::Static) > return false; > - > + // Extra load is not needed for symbols with hidden visibility. > + if (GV->hasHiddenVisibility()) > + return false; > return GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || > GV->hasCommonLinkage() || > (GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode()); > > Modified: llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp?rev=60519&r1=60518&r2=60519&view=diff > > ============================================================================== > --- llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp (original) > +++ llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp Wed Dec 3 19:56:50 2008 > @@ -391,6 +391,8 @@ > FnStubs.insert(Name); > printSuffixedName(Name, "$stub"); > } > + } else if (GV->hasHiddenVisibility()) { > + O << Name; > } else { > GVStubs.insert(Name); > printSuffixedName(Name, "$non_lazy_ptr"); > > Modified: llvm/trunk/lib/Target/X86/X86Subtarget.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.cpp?rev=60519&r1=60518&r2=60519&view=diff > > ============================================================================== > --- llvm/trunk/lib/Target/X86/X86Subtarget.cpp (original) > +++ llvm/trunk/lib/Target/X86/X86Subtarget.cpp Wed Dec 3 19:56:50 2008 > @@ -40,6 +40,9 @@ > if (TM.getRelocationModel() != Reloc::Static && > TM.getCodeModel() != CodeModel::Large) { > if (isTargetDarwin()) { > + if (GV->hasHiddenVisibility()) > + // Extra load is not needed for symbols with hidden visibility. > + return false; > return (!isDirectCall && > (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || > GV->hasCommonLinkage() || > > Added: llvm/trunk/test/CodeGen/X86/hidden-vis-2.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/hidden-vis-2.ll?rev=60519&view=auto > > ============================================================================== > --- llvm/trunk/test/CodeGen/X86/hidden-vis-2.ll (added) > +++ llvm/trunk/test/CodeGen/X86/hidden-vis-2.ll Wed Dec 3 19:56:50 2008 > @@ -0,0 +1,10 @@ > +; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep mov | count 1 > +; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin9 | not grep GOT > + > + at x = weak hidden global i32 0 ; [#uses=1] > + > +define i32 @t() nounwind readonly { > +entry: > + %0 = load i32* @x, align 4 ; [#uses=1] > + ret i32 %0 > +} > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From anton at korobeynikov.info Thu Dec 4 01:18:50 2008 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Thu, 4 Dec 2008 10:18:50 +0300 Subject: [llvm-commits] [llvm] r60519 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp lib/Target/PowerPC/PPCSubtarget.cpp lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp lib/Target/X86/X86Subtarget.cpp t Message-ID: Hi, Nick > You missed that the same optimization applies to protected symbols as > well, probably because Darwin doesn't have them. Please update PR3148. > Does this fix the issue on Linux as well? On linux stuff with internal linkage or hidden visibility never required extra loads. This was from the beginning of the PIC support there (calls were resolved locally, not via PLT, etc). -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University From espindola at google.com Thu Dec 4 09:17:23 2008 From: espindola at google.com (Rafael Espindola) Date: Thu, 4 Dec 2008 15:17:23 +0000 Subject: [llvm-commits] [patch] Really fix bug 2843 Message-ID: <38a0d8450812040717l4e5b6994vab5ced0877d6d0f1@mail.gmail.com> The attached patch really fixes bug 2843. I have tested that the warning is not printed on linux, but is printed on darwin. It is possible to print it on linux by adding -Wformat -Wformat-security and it is possible to avoid it on darwin by adding -Wno-format. Jack, Nick tells me that you found a problem in Fortran with a previous version of this patch. Would you mind testing the attached version? Thanks, -- Rafael Avila de Espindola Google | Gordon House | Barrow Street | Dublin 4 | Ireland Registered in Dublin, Ireland | Registration Number: 368047 -------------- next part -------------- A non-text attachment was scrubbed... Name: 2843.patch Type: text/x-diff Size: 3457 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081204/1d84b234/attachment.bin From scottm at aero.org Thu Dec 4 11:17:01 2008 From: scottm at aero.org (Scott Michel) Date: Thu, 04 Dec 2008 17:17:01 -0000 Subject: [llvm-commits] [llvm] r60541 - /llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Message-ID: <200812041717.mB4HH1Xv012774@zion.cs.uiuc.edu> Author: pingbak Date: Thu Dec 4 11:16:59 2008 New Revision: 60541 URL: http://llvm.org/viewvc/llvm-project?rev=60541&view=rev Log: Missing closing brace and reverse conditional condition on NDEBUG Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=60541&r1=60540&r2=60541&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Thu Dec 4 11:16:59 2008 @@ -766,7 +766,7 @@ LN->getSrcValue(), LN->getSrcValueOffset(), LN->isVolatile(), LN->getAlignment()); -#if 0 && defined(NDEBUG) +#if 0 && !defined(NDEBUG) if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) { const SDValue ¤tRoot = DAG.getRoot(); @@ -3021,7 +3021,7 @@ SDValue combinedConst = DAG.getConstant(CN0->getZExtValue() + CN1->getZExtValue(), Op0VT); -#if defined(NDEBUG) +#if !defined(NDEBUG) if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) { cerr << "\n" << "Replace: (add " << CN0->getZExtValue() << ", " @@ -3064,14 +3064,14 @@ // (any_extend (SPUextract_elt0 )) -> // (SPUextract_elt0 ) // Types must match, however... -#if defined(NDEBUG) - // if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) { +#if !defined(NDEBUG) + if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) { cerr << "\nReplace: "; N->dump(&DAG); cerr << "\nWith: "; Op0.getNode()->dump(&DAG); cerr << "\n"; - + } #endif return Op0; From baldrick at free.fr Thu Dec 4 12:08:40 2008 From: baldrick at free.fr (Duncan Sands) Date: Thu, 04 Dec 2008 18:08:40 -0000 Subject: [llvm-commits] [llvm] r60543 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200812041808.mB4I8eCi014371@zion.cs.uiuc.edu> Author: baldrick Date: Thu Dec 4 12:08:40 2008 New Revision: 60543 URL: http://llvm.org/viewvc/llvm-project?rev=60543&view=rev Log: When allocating a stack temporary, use the correct number of bytes for types such as i1 which are not a multiple of 8 bits in length. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=60543&r1=60542&r2=60543&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Thu Dec 4 12:08:40 2008 @@ -1237,7 +1237,7 @@ /// specified value type. SDValue SelectionDAG::CreateStackTemporary(MVT VT, unsigned minAlign) { MachineFrameInfo *FrameInfo = getMachineFunction().getFrameInfo(); - unsigned ByteSize = VT.getSizeInBits()/8; + unsigned ByteSize = VT.getStoreSizeInBits()/8; const Type *Ty = VT.getTypeForMVT(); unsigned StackAlign = std::max((unsigned)TLI.getTargetData()->getPrefTypeAlignment(Ty), minAlign); From dpatel at apple.com Thu Dec 4 14:51:31 2008 From: dpatel at apple.com (Devang Patel) Date: Thu, 04 Dec 2008 20:51:31 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60549 - /llvm-gcc-4.2/trunk/build_gcc Message-ID: <200812042051.mB4KpVjs019721@zion.cs.uiuc.edu> Author: dpatel Date: Thu Dec 4 14:51:30 2008 New Revision: 60549 URL: http://llvm.org/viewvc/llvm-project?rev=60549&view=rev Log: Include version number in the symlinks. Modified: llvm-gcc-4.2/trunk/build_gcc Modified: llvm-gcc-4.2/trunk/build_gcc URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/build_gcc?rev=60549&r1=60548&r2=60549&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/build_gcc (original) +++ llvm-gcc-4.2/trunk/build_gcc Thu Dec 4 14:51:30 2008 @@ -622,8 +622,8 @@ if [ "x$LLVM_BUILT_ROOTS" == "x" ]; then mkdir -p $DEST_DIR/usr/bin cd $DEST_DIR/usr/bin - ln -s /Developer/usr/bin/llvm-gcc llvm-gcc - ln -s /Developer/usr/bin/llvm-g++ llvm-g++ + ln -s /Developer/usr/bin/llvm-gcc-4.2 llvm-gcc-4.2 + ln -s /Developer/usr/bin/llvm-g++-4.2 llvm-g++-4.2 fi # LLVM LOCAL end From isanbard at gmail.com Thu Dec 4 15:00:08 2008 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 04 Dec 2008 21:00:08 -0000 Subject: [llvm-commits] [llvm] r60550 - /llvm/tags/Apple/llvmCore-2079.2/ Message-ID: <200812042100.mB4L08Nn020012@zion.cs.uiuc.edu> Author: void Date: Thu Dec 4 15:00:08 2008 New Revision: 60550 URL: http://llvm.org/viewvc/llvm-project?rev=60550&view=rev Log: Tagging to coincide with llvmgcc42-2079.2. Added: llvm/tags/Apple/llvmCore-2079.2/ - copied from r60549, llvm/tags/Apple/llvmCore-2079.1/ From isanbard at gmail.com Thu Dec 4 15:01:13 2008 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 04 Dec 2008 21:01:13 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60551 - in /llvm-gcc-4.2/tags/Apple/llvmgcc42-2079.2: ./ build_gcc Message-ID: <200812042101.mB4L1Doc020056@zion.cs.uiuc.edu> Author: void Date: Thu Dec 4 15:01:12 2008 New Revision: 60551 URL: http://llvm.org/viewvc/llvm-project?rev=60551&view=rev Log: llvmgcc42-2079.1 with r60549 patch. Added: llvm-gcc-4.2/tags/Apple/llvmgcc42-2079.2/ - copied from r60509, llvm-gcc-4.2/tags/Apple/llvmgcc42-2079/ Modified: llvm-gcc-4.2/tags/Apple/llvmgcc42-2079.2/build_gcc Modified: llvm-gcc-4.2/tags/Apple/llvmgcc42-2079.2/build_gcc URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/tags/Apple/llvmgcc42-2079.2/build_gcc?rev=60551&r1=60509&r2=60551&view=diff ============================================================================== --- llvm-gcc-4.2/tags/Apple/llvmgcc42-2079.2/build_gcc (original) +++ llvm-gcc-4.2/tags/Apple/llvmgcc42-2079.2/build_gcc Thu Dec 4 15:01:12 2008 @@ -619,6 +619,13 @@ rm libllvmgcc.dylib ln -s ../../libllvmgcc.dylib done + +if [ "x$LLVM_BUILT_ROOTS" == "x" ]; then + mkdir -p $DEST_DIR/usr/bin + cd $DEST_DIR/usr/bin + ln -s /Developer/usr/bin/llvm-gcc-4.2 llvm-gcc-4.2 + ln -s /Developer/usr/bin/llvm-g++-4.2 llvm-g++-4.2 +fi # LLVM LOCAL end find $DEST_DIR -name \*.dSYM -print | xargs rm -r || exit 1 From scottm at aero.org Thu Dec 4 15:01:44 2008 From: scottm at aero.org (Scott Michel) Date: Thu, 04 Dec 2008 21:01:44 -0000 Subject: [llvm-commits] [llvm] r60552 - in /llvm/trunk/lib/Target/CellSPU: AsmPrinter/SPUAsmPrinter.cpp SPUISelLowering.cpp SPUInstrInfo.td Message-ID: <200812042101.mB4L1irQ020086@zion.cs.uiuc.edu> Author: pingbak Date: Thu Dec 4 15:01:44 2008 New Revision: 60552 URL: http://llvm.org/viewvc/llvm-project?rev=60552&view=rev Log: CellSPU: Fix bug 3055 - Add v4f32, v2f64 to LowerVECTOR_SHUFFLE - Look for vector rotate in shuffle elements, generate a vector rotate instead of a full-blown shuffle when opportunity presents itself. - Generate larger test harness and fix a few interesting but obscure bugs. Modified: llvm/trunk/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td Modified: llvm/trunk/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp?rev=60552&r1=60551&r2=60552&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp Thu Dec 4 15:01:44 2008 @@ -221,7 +221,6 @@ void printPCRelativeOperand(const MachineInstr *MI, unsigned OpNo) { printOp(MI->getOperand(OpNo)); - O << "-."; } void printSymbolHi(const MachineInstr *MI, unsigned OpNo) { Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=60552&r1=60551&r2=60552&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Thu Dec 4 15:01:44 2008 @@ -548,7 +548,6 @@ alignOffs = int(FIN->getIndex() * SPUFrameInfo::stackSlotSize()); prefSlotOffs = (int) (alignOffs & 0xf); prefSlotOffs -= vtm->prefslot_byte; - basePtr = DAG.getRegister(SPU::R1, VT); } else { alignOffs = 0; prefSlotOffs = -vtm->prefslot_byte; @@ -1127,6 +1126,8 @@ ArgOffset += StackSlotSize; } break; + case MVT::v2i64: + case MVT::v2f64: case MVT::v4f32: case MVT::v4i32: case MVT::v8i16: @@ -1255,6 +1256,7 @@ NumResults = 1; break; case MVT::v2f64: + case MVT::v2i64: case MVT::v4f32: case MVT::v4i32: case MVT::v8i16: @@ -1747,38 +1749,64 @@ // If we have a single element being moved from V1 to V2, this can be handled // using the C*[DX] compute mask instructions, but the vector elements have // to be monotonically increasing with one exception element. - MVT EltVT = V1.getValueType().getVectorElementType(); + MVT VecVT = V1.getValueType(); + MVT EltVT = VecVT.getVectorElementType(); unsigned EltsFromV2 = 0; unsigned V2Elt = 0; unsigned V2EltIdx0 = 0; unsigned CurrElt = 0; + unsigned MaxElts = VecVT.getVectorNumElements(); + unsigned PrevElt = 0; + unsigned V0Elt = 0; bool monotonic = true; - if (EltVT == MVT::i8) + bool rotate = true; + + if (EltVT == MVT::i8) { V2EltIdx0 = 16; - else if (EltVT == MVT::i16) + } else if (EltVT == MVT::i16) { V2EltIdx0 = 8; - else if (EltVT == MVT::i32) + } else if (EltVT == MVT::i32 || EltVT == MVT::f32) { V2EltIdx0 = 4; - else + } else if (EltVT == MVT::i64 || EltVT == MVT::f64) { + V2EltIdx0 = 2; + } else assert(0 && "Unhandled vector type in LowerVECTOR_SHUFFLE"); - for (unsigned i = 0, e = PermMask.getNumOperands(); - EltsFromV2 <= 1 && monotonic && i != e; - ++i) { - unsigned SrcElt; - if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF) - SrcElt = 0; - else - SrcElt = cast(PermMask.getOperand(i))->getZExtValue(); + for (unsigned i = 0; i != PermMask.getNumOperands(); ++i) { + if (PermMask.getOperand(i).getOpcode() != ISD::UNDEF) { + unsigned SrcElt = cast (PermMask.getOperand(i))->getZExtValue(); + + if (monotonic) { + if (SrcElt >= V2EltIdx0) { + if (1 >= (++EltsFromV2)) { + V2Elt = (V2EltIdx0 - SrcElt) << 2; + } + } else if (CurrElt != SrcElt) { + monotonic = false; + } - if (SrcElt >= V2EltIdx0) { - ++EltsFromV2; - V2Elt = (V2EltIdx0 - SrcElt) << 2; - } else if (CurrElt != SrcElt) { - monotonic = false; - } + ++CurrElt; + } - ++CurrElt; + if (rotate) { + if (PrevElt > 0 && SrcElt < MaxElts) { + if ((PrevElt == SrcElt - 1) + || (PrevElt == MaxElts - 1 && SrcElt == 0)) { + PrevElt = SrcElt; + if (SrcElt == 0) + V0Elt = i; + } else { + rotate = false; + } + } else if (PrevElt == 0) { + // First time through, need to keep track of previous element + PrevElt = SrcElt; + } else { + // This isn't a rotation, takes elements from vector 2 + rotate = false; + } + } + } } if (EltsFromV2 == 1 && monotonic) { @@ -1797,6 +1825,11 @@ DAG.getCopyFromReg(InitTempReg, VReg, PtrVT)); // Use shuffle mask in SHUFB synthetic instruction: return DAG.getNode(SPUISD::SHUFB, V1.getValueType(), V2, V1, ShufMaskOp); + } else if (rotate) { + int rotamt = (MaxElts - V0Elt) * EltVT.getSizeInBits()/8; + + return DAG.getNode(SPUISD::ROTBYTES_LEFT, V1.getValueType(), + V1, DAG.getConstant(rotamt, MVT::i16)); } else { // Convert the SHUFFLE_VECTOR mask's input element units to the // actual bytes. @@ -2127,7 +2160,7 @@ SDValue ShufMask[4]; for (unsigned i = 0; i < sizeof(ShufMask)/sizeof(ShufMask[0]); ++i) { - unsigned bidx = i / 4; + unsigned bidx = i * 4; unsigned int bits = ((ShufBytes[bidx] << 24) | (ShufBytes[bidx+1] << 16) | (ShufBytes[bidx+2] << 8) | Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td?rev=60552&r1=60551&r2=60552&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td (original) +++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td Thu Dec 4 15:01:44 2008 @@ -2124,7 +2124,9 @@ def v16i8: ROTQBYVecInst; def v8i16: ROTQBYVecInst; def v4i32: ROTQBYVecInst; + def v4f32: ROTQBYVecInst; def v2i64: ROTQBYVecInst; + def v2f64: ROTQBYVecInst; } defm ROTQBY: RotateQuadLeftByBytes; @@ -2147,7 +2149,9 @@ def v16i8: ROTQBYIVecInst; def v8i16: ROTQBYIVecInst; def v4i32: ROTQBYIVecInst; + def v4f32: ROTQBYIVecInst; def v2i64: ROTQBYIVecInst; + def vfi64: ROTQBYIVecInst; } defm ROTQBYI: RotateQuadByBytesImm; From resistor at mac.com Thu Dec 4 15:20:31 2008 From: resistor at mac.com (Owen Anderson) Date: Thu, 04 Dec 2008 21:20:31 -0000 Subject: [llvm-commits] [llvm] r60553 - /llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp Message-ID: <200812042120.mB4LKV7U020685@zion.cs.uiuc.edu> Author: resistor Date: Thu Dec 4 15:20:30 2008 New Revision: 60553 URL: http://llvm.org/viewvc/llvm-project?rev=60553&view=rev Log: Factor out some common code. Modified: llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp Modified: llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp?rev=60553&r1=60552&r2=60553&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp (original) +++ llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp Thu Dec 4 15:20:30 2008 @@ -153,6 +153,9 @@ bool SplitRegLiveIntervals(const TargetRegisterClass **); + void RepairLiveInterval(LiveInterval* CurrLI, VNInfo* ValNo, + MachineInstr* DefMI, unsigned RestoreIdx); + bool createsNewJoin(LiveRange* LR, MachineBasicBlock* DefMBB, MachineBasicBlock* BarrierMBB); bool Rematerialize(unsigned vreg, VNInfo* ValNo, @@ -640,35 +643,11 @@ return; } -bool PreAllocSplitting::Rematerialize(unsigned vreg, VNInfo* ValNo, - MachineInstr* DefMI, - MachineBasicBlock::iterator RestorePt, - unsigned RestoreIdx, - SmallPtrSet& RefsInMBB) { - MachineBasicBlock& MBB = *RestorePt->getParent(); - - MachineBasicBlock::iterator KillPt = BarrierMBB->end(); - unsigned KillIdx = 0; - if (ValNo->def == ~0U || DefMI->getParent() == BarrierMBB) - KillPt = findSpillPoint(BarrierMBB, Barrier, NULL, RefsInMBB, KillIdx); - else - KillPt = findNextEmptySlot(DefMI->getParent(), DefMI, KillIdx); - - if (KillPt == DefMI->getParent()->end()) - return false; - - TII->reMaterialize(MBB, RestorePt, vreg, DefMI); - LIs->InsertMachineInstrInMaps(prior(RestorePt), RestoreIdx); - - if (KillPt->getParent() == BarrierMBB) { - UpdateRegisterInterval(ValNo, LIs->getUseIndex(KillIdx)+1, - LIs->getDefIndex(RestoreIdx)); - - ++NumSplits; - ++NumRemats; - return true; - } +void PreAllocSplitting::RepairLiveInterval(LiveInterval* CurrLI, + VNInfo* ValNo, + MachineInstr* DefMI, + unsigned RestoreIdx) { // Shrink wrap the live interval by walking up the CFG and find the // new kills. // Now let's find all the uses of the val#. @@ -717,6 +696,37 @@ // point to re-start the live interval. UpdateRegisterInterval(ValNo, LIs->getUseIndex(BarrierIdx)+1, LIs->getDefIndex(RestoreIdx)); +} +bool PreAllocSplitting::Rematerialize(unsigned vreg, VNInfo* ValNo, + MachineInstr* DefMI, + MachineBasicBlock::iterator RestorePt, + unsigned RestoreIdx, + SmallPtrSet& RefsInMBB) { + MachineBasicBlock& MBB = *RestorePt->getParent(); + + MachineBasicBlock::iterator KillPt = BarrierMBB->end(); + unsigned KillIdx = 0; + if (ValNo->def == ~0U || DefMI->getParent() == BarrierMBB) + KillPt = findSpillPoint(BarrierMBB, Barrier, NULL, RefsInMBB, KillIdx); + else + KillPt = findNextEmptySlot(DefMI->getParent(), DefMI, KillIdx); + + if (KillPt == DefMI->getParent()->end()) + return false; + + TII->reMaterialize(MBB, RestorePt, vreg, DefMI); + LIs->InsertMachineInstrInMaps(prior(RestorePt), RestoreIdx); + + if (KillPt->getParent() == BarrierMBB) { + UpdateRegisterInterval(ValNo, LIs->getUseIndex(KillIdx)+1, + LIs->getDefIndex(RestoreIdx)); + + ++NumSplits; + ++NumRemats; + return true; + } + + RepairLiveInterval(CurrLI, ValNo, DefMI, RestoreIdx); ++NumSplits; ++NumRemats; @@ -908,54 +918,7 @@ UpdateSpillSlotInterval(ValNo, LIs->getUseIndex(SpillIndex)+1, LIs->getDefIndex(RestoreIndex)); - // Shrink wrap the live interval by walking up the CFG and find the - // new kills. - // Now let's find all the uses of the val#. - DenseMap > Uses; - DenseMap > UseMIs; - SmallPtrSet Seen; - SmallVector UseMBBs; - for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(CurrLI->reg), - UE = MRI->use_end(); UI != UE; ++UI) { - MachineOperand &UseMO = UI.getOperand(); - MachineInstr *UseMI = UseMO.getParent(); - unsigned UseIdx = LIs->getInstructionIndex(UseMI); - LiveInterval::iterator ULR = CurrLI->FindLiveRangeContaining(UseIdx); - if (ULR->valno != ValNo) - continue; - MachineBasicBlock *UseMBB = UseMI->getParent(); - // Remember which other mbb's use this val#. - if (Seen.insert(UseMBB) && UseMBB != BarrierMBB) - UseMBBs.push_back(UseMBB); - DenseMap >::iterator - UMII = Uses.find(UseMBB); - if (UMII != Uses.end()) { - DenseMap >::iterator - UMII2 = UseMIs.find(UseMBB); - UMII->second.push_back(&UseMO); - UMII2->second.insert(UseMI); - } else { - SmallVector Ops; - Ops.push_back(&UseMO); - Uses.insert(std::make_pair(UseMBB, Ops)); - SmallPtrSet MIs; - MIs.insert(UseMI); - UseMIs.insert(std::make_pair(UseMBB, MIs)); - } - } - - // Walk up the predecessor chains. - SmallPtrSet Visited; - ShrinkWrapLiveInterval(ValNo, BarrierMBB, NULL, DefMBB, Visited, - Uses, UseMIs, UseMBBs); - - // FIXME: If ValNo->hasPHIKill is false, then renumber the val# by - // the restore. - - // Remove live range from barrier to the restore. FIXME: Find a better - // point to re-start the live interval. - UpdateRegisterInterval(ValNo, LIs->getUseIndex(BarrierIdx)+1, - LIs->getDefIndex(RestoreIndex)); + RepairLiveInterval(CurrLI, ValNo, DefMI, RestoreIndex); ++NumSplits; return true; From dpatel at apple.com Thu Dec 4 15:38:43 2008 From: dpatel at apple.com (Devang Patel) Date: Thu, 04 Dec 2008 21:38:43 -0000 Subject: [llvm-commits] [llvm] r60554 - in /llvm/trunk: lib/Transforms/Scalar/LoopIndexSplit.cpp test/Transforms/LoopIndexSplit/2007-09-24-UpdateIterationSpace.ll test/Transforms/LoopIndexSplit/2007-09-25-UpdateIterationSpace-2.ll test/Transforms/LoopIndexSplit/2008-10-10-OneIteration.ll test/Transforms/LoopIndexSplit/OneIterLoop-2007-08-17.ll test/Transforms/LoopIndexSplit/OneIterLoop2-2007-08-17.ll Message-ID: <200812042138.mB4LchmP021296@zion.cs.uiuc.edu> Author: dpatel Date: Thu Dec 4 15:38:42 2008 New Revision: 60554 URL: http://llvm.org/viewvc/llvm-project?rev=60554&view=rev Log: Rewrite code that 1) filters loops and 2) calculates new loop bounds. This fixes many bugs. I will add more test cases in a separate check-in. Some day, the code that manipulates CFG and updates dom. info could use refactoring help. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp llvm/trunk/test/Transforms/LoopIndexSplit/2007-09-24-UpdateIterationSpace.ll llvm/trunk/test/Transforms/LoopIndexSplit/2007-09-25-UpdateIterationSpace-2.ll llvm/trunk/test/Transforms/LoopIndexSplit/2008-10-10-OneIteration.ll llvm/trunk/test/Transforms/LoopIndexSplit/OneIterLoop-2007-08-17.ll llvm/trunk/test/Transforms/LoopIndexSplit/OneIterLoop2-2007-08-17.ll Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp?rev=60554&r1=60553&r2=60554&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Thu Dec 4 15:38:42 2008 @@ -7,8 +7,36 @@ // //===----------------------------------------------------------------------===// // -// This file implements Loop Index Splitting Pass. +// This file implements Loop Index Splitting Pass. This pass handles three +// kinds of loops. // +// [1] Loop is eliminated when loop body is executed only once. For example, +// for (i = 0; i < N; ++i) { +// if ( i == X) { +// ... +// } +// } +// +// [2] Loop's iteration space is shrunk if loop body is executed for certain +// range only. For example, +// +// for (i = 0; i < N; ++i) { +// if ( i > A && i < B) { +// ... +// } +// } +// is trnasformed to iterators from A to B, if A > 0 and B < N. +// +// [3] Loop is split if the loop body is dominated by an branch. For example, +// +// for (i = LB; i < UB; ++i) { if (i < SV) A; else B; } +// +// is transformed into +// AEV = BSV = SV +// for (i = LB; i < min(UB, AEV); ++i) +// A; +// for (i = max(LB, BSV); i < UB; ++i); +// B; //===----------------------------------------------------------------------===// #define DEBUG_TYPE "loop-index-split" @@ -25,7 +53,9 @@ using namespace llvm; -STATISTIC(NumIndexSplit, "Number of loops index split"); +STATISTIC(NumIndexSplit, "Number of loop index split"); +STATISTIC(NumIndexSplitRemoved, "Number of loops eliminated by loop index split"); +STATISTIC(NumRestrictBounds, "Number of loop iteration space restricted"); namespace { @@ -54,96 +84,50 @@ } private: + /// processOneIterationLoop -- Eliminate loop if loop body is executed + /// only once. For example, + /// for (i = 0; i < N; ++i) { + /// if ( i == X) { + /// ... + /// } + /// } + /// + bool processOneIterationLoop(); - class SplitInfo { - public: - SplitInfo() : SplitValue(NULL), SplitCondition(NULL), - UseTrueBranchFirst(true), A_ExitValue(NULL), - B_StartValue(NULL) {} - - // Induction variable's range is split at this value. - Value *SplitValue; - - // This instruction compares IndVar against SplitValue. - Instruction *SplitCondition; - - // True if after loop index split, first loop will execute split condition's - // true branch. - bool UseTrueBranchFirst; - - // Exit value for first loop after loop split. - Value *A_ExitValue; - - // Start value for second loop after loop split. - Value *B_StartValue; - - // Clear split info. - void clear() { - SplitValue = NULL; - SplitCondition = NULL; - UseTrueBranchFirst = true; - A_ExitValue = NULL; - B_StartValue = NULL; - } + // -- Routines used by updateLoopIterationSpace(); - }; - - private: + /// updateLoopIterationSpace -- Update loop's iteration space if loop + /// body is executed for certain IV range only. For example, + /// + /// for (i = 0; i < N; ++i) { + /// if ( i > A && i < B) { + /// ... + /// } + /// } + /// is trnasformed to iterators from A to B, if A > 0 and B < N. + /// + bool updateLoopIterationSpace(); - // safeIcmpInst - CI is considered safe instruction if one of the operand - // is SCEVAddRecExpr based on induction variable and other operand is - // loop invariant. If CI is safe then populate SplitInfo object SD appropriately - // and return true; - bool safeICmpInst(ICmpInst *CI, SplitInfo &SD); - - /// Find condition inside a loop that is suitable candidate for index split. - void findSplitCondition(); - - /// Find loop's exit condition. - void findLoopConditionals(); - - /// Return induction variable associated with value V. - void findIndVar(Value *V, Loop *L); - - /// processOneIterationLoop - Current loop L contains compare instruction - /// that compares induction variable, IndVar, agains loop invariant. If - /// entire (i.e. meaningful) loop body is dominated by this compare - /// instruction then loop body is executed only for one iteration. In - /// such case eliminate loop structure surrounding this loop body. For - bool processOneIterationLoop(SplitInfo &SD); - - /// isOneIterationLoop - Return true if split condition is EQ and - /// the IV is not used outside the loop. - bool isOneIterationLoop(ICmpInst *CI); - - void updateLoopBounds(ICmpInst *CI); - /// updateLoopIterationSpace - Current loop body is covered by an AND - /// instruction whose operands compares induction variables with loop - /// invariants. If possible, hoist this check outside the loop by - /// updating appropriate start and end values for induction variable. - bool updateLoopIterationSpace(SplitInfo &SD); - - /// If loop header includes loop variant instruction operands then - /// this loop may not be eliminated. - bool safeHeader(SplitInfo &SD, BasicBlock *BB); - - /// If Exiting block includes loop variant instructions then this - /// loop may not be eliminated. - bool safeExitingBlock(SplitInfo &SD, BasicBlock *BB); - - /// removeBlocks - Remove basic block DeadBB and all blocks dominated by DeadBB. - /// This routine is used to remove split condition's dead branch, dominated by - /// DeadBB. LiveBB dominates split conidition's other branch. - void removeBlocks(BasicBlock *DeadBB, Loop *LP, BasicBlock *LiveBB); + /// restrictLoopBound - Op dominates loop body. Op compares an IV based value + /// with a loop invariant value. Update loop's lower and upper bound based on + /// the loop invariant value. + bool restrictLoopBound(ICmpInst &Op); + + // --- Routines used by splitLoop(). --- / - /// safeSplitCondition - Return true if it is possible to - /// split loop using given split condition. - bool safeSplitCondition(SplitInfo &SD); - - /// calculateLoopBounds - ALoop exit value and BLoop start values are calculated - /// based on split value. - void calculateLoopBounds(SplitInfo &SD); + bool splitLoop(); + /// removeBlocks - Remove basic block DeadBB and all blocks dominated by + /// DeadBB. This routine is used to remove split condition's dead branch, + /// dominated by DeadBB. LiveBB dominates split conidition's other branch. + void removeBlocks(BasicBlock *DeadBB, Loop *LP, BasicBlock *LiveBB); + + /// moveExitCondition - Move exit condition EC into split condition block. + void moveExitCondition(BasicBlock *CondBB, BasicBlock *ActiveBB, + BasicBlock *ExitBB, ICmpInst *EC, ICmpInst *SC, + PHINode *IV, Instruction *IVAdd, Loop *LP, + unsigned); + /// updatePHINodes - CFG has been changed. /// Before /// - ExitBB's single predecessor was Latch @@ -157,47 +141,49 @@ BasicBlock *Header, PHINode *IV, Instruction *IVIncrement, Loop *LP); - /// moveExitCondition - Move exit condition EC into split condition block CondBB. - void moveExitCondition(BasicBlock *CondBB, BasicBlock *ActiveBB, - BasicBlock *ExitBB, ICmpInst *EC, ICmpInst *SC, - PHINode *IV, Instruction *IVAdd, Loop *LP); + // --- Utility routines --- / - /// splitLoop - Split current loop L in two loops using split information - /// SD. Update dominator information. Maintain LCSSA form. - bool splitLoop(SplitInfo &SD); - - void initialize() { - IndVar = NULL; - IndVarIncrement = NULL; - ExitCondition = NULL; - StartValue = NULL; - ExitValueNum = 0; - SplitData.clear(); - } + /// cleanBlock - A block is considered clean if all non terminal + /// instructions are either PHINodes or IV based values. + bool cleanBlock(BasicBlock *BB); + + /// IVisLT - If Op is comparing IV based value with an loop invaraint and + /// IV based value is less than the loop invariant then return the loop + /// invariant. Otherwise return NULL. + Value * IVisLT(ICmpInst &Op); + + /// IVisLE - If Op is comparing IV based value with an loop invaraint and + /// IV based value is less than or equal to the loop invariant then + /// return the loop invariant. Otherwise return NULL. + Value * IVisLE(ICmpInst &Op); + + /// IVisGT - If Op is comparing IV based value with an loop invaraint and + /// IV based value is greater than the loop invariant then return the loop + /// invariant. Otherwise return NULL. + Value * IVisGT(ICmpInst &Op); + + /// IVisGE - If Op is comparing IV based value with an loop invaraint and + /// IV based value is greater than or equal to the loop invariant then + /// return the loop invariant. Otherwise return NULL. + Value * IVisGE(ICmpInst &Op); private: - // Current Loop. + // Current Loop information. Loop *L; LPPassManager *LPM; LoopInfo *LI; ScalarEvolution *SE; DominatorTree *DT; DominanceFrontier *DF; - SmallVector SplitData; - // Induction variable whose range is being split by this transformation. PHINode *IndVar; - Instruction *IndVarIncrement; - - // Loop exit condition. ICmpInst *ExitCondition; - - // Induction variable's initial value. - Value *StartValue; - - // Induction variable's final loop exit value operand number in exit condition.. - unsigned ExitValueNum; + ICmpInst *SplitCondition; + Value *IVStartValue; + Value *IVExitValue; + Instruction *IVIncrement; + SmallPtrSet IVBasedValues; }; } @@ -211,7 +197,6 @@ // Index split Loop L. Return true if loop is split. bool LoopIndexSplit::runOnLoop(Loop *IncomingLoop, LPPassManager &LPM_Ref) { - bool Changed = false; L = IncomingLoop; LPM = &LPM_Ref; @@ -224,370 +209,189 @@ LI = &getAnalysis(); DF = &getAnalysis(); - initialize(); - - findLoopConditionals(); - - if (!ExitCondition) + // Initialize loop data. + IndVar = L->getCanonicalInductionVariable(); + if (!IndVar) return false; + + bool P1InLoop = L->contains(IndVar->getIncomingBlock(1)); + IVStartValue = IndVar->getIncomingValue(!P1InLoop); + IVIncrement = dyn_cast(IndVar->getIncomingValue(P1InLoop)); + if (!IVIncrement) return false; + + IVBasedValues.clear(); + IVBasedValues.insert(IndVar); + IVBasedValues.insert(IVIncrement); + for (Loop::block_iterator I = L->block_begin(), E = L->block_end(); + I != E; ++I) + for(BasicBlock::iterator BI = (*I)->begin(), BE = (*I)->end(); + BI != BE; ++BI) { + if (BinaryOperator *BO = dyn_cast(BI)) + if (BO != IVIncrement + && (BO->getOpcode() == Instruction::Add + || BO->getOpcode() == Instruction::Sub)) + if (IVBasedValues.count(BO->getOperand(0)) + && L->isLoopInvariant(BO->getOperand(1))) + IVBasedValues.insert(BO); + } + + // Reject loop if loop exit condition is not suitable. + SmallVector EBs; + L->getExitingBlocks(EBs); + if (EBs.size() != 1) + return false; + BranchInst *EBR = dyn_cast(EBs[0]->getTerminator()); + if (!EBR) return false; + ExitCondition = dyn_cast(EBR->getCondition()); + if (!ExitCondition) return false; + if (EBs[0] != L->getLoopLatch()) return false; + IVExitValue = ExitCondition->getOperand(1); + if (!L->isLoopInvariant(IVExitValue)) + IVExitValue = ExitCondition->getOperand(0); + if (!L->isLoopInvariant(IVExitValue)) return false; - findSplitCondition(); - - if (SplitData.empty()) - return false; + // If start value is more then exit value where induction variable + // increments by 1 then we are potentially dealing with an infinite loop. + // Do not index split this loop. + if (ConstantInt *SV = dyn_cast(IVStartValue)) + if (ConstantInt *EV = dyn_cast(IVExitValue)) + if (SV->getSExtValue() > EV->getSExtValue()) + return false; - // First see if it is possible to eliminate loop itself or not. - for (SmallVector::iterator SI = SplitData.begin(); - SI != SplitData.end();) { - SplitInfo &SD = *SI; - ICmpInst *CI = dyn_cast(SD.SplitCondition); - if (SD.SplitCondition->getOpcode() == Instruction::And) { - Changed = updateLoopIterationSpace(SD); - if (Changed) { - ++NumIndexSplit; - // If is loop is eliminated then nothing else to do here. - return Changed; - } else { - SmallVector::iterator Delete_SI = SI; - SI = SplitData.erase(Delete_SI); - } - } - else if (isOneIterationLoop(CI)) { - Changed = processOneIterationLoop(SD); - if (Changed) { - ++NumIndexSplit; - // If is loop is eliminated then nothing else to do here. - return Changed; - } else { - SmallVector::iterator Delete_SI = SI; - SI = SplitData.erase(Delete_SI); - } - } else - ++SI; - } + if (processOneIterationLoop()) + return true; - if (SplitData.empty()) - return false; + if (updateLoopIterationSpace()) + return true; - // Split most profitiable condition. - // FIXME : Implement cost analysis. - unsigned MostProfitableSDIndex = 0; - Changed = splitLoop(SplitData[MostProfitableSDIndex]); + if (splitLoop()) + return true; - if (Changed) - ++NumIndexSplit; - - return Changed; + return false; } -/// isOneIterationLoop - Return true if split condition is EQ and -/// the IV is not used outside the loop. -bool LoopIndexSplit::isOneIterationLoop(ICmpInst *CI) { - if (!CI) - return false; - if (CI->getPredicate() != ICmpInst::ICMP_EQ) - return false; - - Value *Incr = IndVar->getIncomingValueForBlock(L->getLoopLatch()); - for (Value::use_iterator UI = Incr->use_begin(), E = Incr->use_end(); - UI != E; ++UI) +// --- Helper routines --- +// isUsedOutsideLoop - Returns true iff V is used outside the loop L. +static bool isUsedOutsideLoop(Value *V, Loop *L) { + for(Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ++UI) if (!L->contains(cast(*UI)->getParent())) - return false; - - return true; + return true; + return false; } -/// Return true if V is a induction variable or induction variable's -/// increment for loop L. -void LoopIndexSplit::findIndVar(Value *V, Loop *L) { - - Instruction *I = dyn_cast(V); - if (!I) - return; - - // Check if I is a phi node from loop header or not. - if (PHINode *PN = dyn_cast(V)) { - if (PN->getParent() == L->getHeader()) { - IndVar = PN; - return; - } - } - - // Check if I is a add instruction whose one operand is - // phi node from loop header and second operand is constant. - if (I->getOpcode() != Instruction::Add) - return; - - Value *Op0 = I->getOperand(0); - Value *Op1 = I->getOperand(1); - - if (PHINode *PN = dyn_cast(Op0)) - if (PN->getParent() == L->getHeader()) - if (ConstantInt *CI = dyn_cast(Op1)) - if (CI->isOne()) { - IndVar = PN; - IndVarIncrement = I; - return; - } - if (PHINode *PN = dyn_cast(Op1)) - if (PN->getParent() == L->getHeader()) - if (ConstantInt *CI = dyn_cast(Op0)) - if (CI->isOne()) { - IndVar = PN; - IndVarIncrement = I; - return; - } - - return; +// Return V+1 +static Value *getPlusOne(Value *V, bool Sign, Instruction *InsertPt) { + ConstantInt *One = ConstantInt::get(V->getType(), 1, Sign); + return BinaryOperator::CreateAdd(V, One, "lsp", InsertPt); } -// Find loop's exit condition and associated induction variable. -void LoopIndexSplit::findLoopConditionals() { - - BasicBlock *ExitingBlock = NULL; - - for (Loop::block_iterator I = L->block_begin(), E = L->block_end(); - I != E; ++I) { - BasicBlock *BB = *I; - if (!L->isLoopExit(BB)) - continue; - if (ExitingBlock) - return; - ExitingBlock = BB; - } - - if (!ExitingBlock) - return; - - // If exiting block is neither loop header nor loop latch then this loop is - // not suitable. - if (ExitingBlock != L->getHeader() && ExitingBlock != L->getLoopLatch()) - return; - - // If exit block's terminator is conditional branch inst then we have found - // exit condition. - BranchInst *BR = dyn_cast(ExitingBlock->getTerminator()); - if (!BR || BR->isUnconditional()) - return; - - ICmpInst *CI = dyn_cast(BR->getCondition()); - if (!CI) - return; - - // FIXME - if (CI->getPredicate() == ICmpInst::ICMP_EQ - || CI->getPredicate() == ICmpInst::ICMP_NE) - return; - - ExitCondition = CI; - - // Exit condition's one operand is loop invariant exit value and second - // operand is SCEVAddRecExpr based on induction variable. - Value *V0 = CI->getOperand(0); - Value *V1 = CI->getOperand(1); - - SCEVHandle SH0 = SE->getSCEV(V0); - SCEVHandle SH1 = SE->getSCEV(V1); - - if (SH0->isLoopInvariant(L) && isa(SH1)) { - ExitValueNum = 0; - findIndVar(V1, L); - } - else if (SH1->isLoopInvariant(L) && isa(SH0)) { - ExitValueNum = 1; - findIndVar(V0, L); - } - - if (!IndVar) - ExitCondition = NULL; - else if (IndVar) { - BasicBlock *Preheader = L->getLoopPreheader(); - StartValue = IndVar->getIncomingValueForBlock(Preheader); - } - - // If start value is more then exit value where induction variable - // increments by 1 then we are potentially dealing with an infinite loop. - // Do not index split this loop. - if (ExitCondition) { - ConstantInt *SV = dyn_cast(StartValue); - ConstantInt *EV = - dyn_cast(ExitCondition->getOperand(ExitValueNum)); - if (SV && EV && SV->getSExtValue() > EV->getSExtValue()) - ExitCondition = NULL; - else if (EV && EV->isZero()) - ExitCondition = NULL; - } +// Return V-1 +static Value *getMinusOne(Value *V, bool Sign, Instruction *InsertPt) { + ConstantInt *One = ConstantInt::get(V->getType(), 1, Sign); + return BinaryOperator::CreateSub(V, One, "lsp", InsertPt); } -/// Find condition inside a loop that is suitable candidate for index split. -void LoopIndexSplit::findSplitCondition() { - - SplitInfo SD; - // Check all basic block's terminators. - for (Loop::block_iterator I = L->block_begin(), E = L->block_end(); - I != E; ++I) { - SD.clear(); - BasicBlock *BB = *I; - - // If this basic block does not terminate in a conditional branch - // then terminator is not a suitable split condition. - BranchInst *BR = dyn_cast(BB->getTerminator()); - if (!BR) - continue; - - if (BR->isUnconditional()) - continue; - - if (Instruction *AndI = dyn_cast(BR->getCondition())) { - if (AndI->getOpcode() == Instruction::And) { - ICmpInst *Op0 = dyn_cast(AndI->getOperand(0)); - ICmpInst *Op1 = dyn_cast(AndI->getOperand(1)); - - if (!Op0 || !Op1) - continue; - - if (!safeICmpInst(Op0, SD)) - continue; - SD.clear(); - if (!safeICmpInst(Op1, SD)) - continue; - SD.clear(); - SD.SplitCondition = AndI; - SplitData.push_back(SD); - continue; - } - } - ICmpInst *CI = dyn_cast(BR->getCondition()); - if (!CI || CI == ExitCondition) - continue; - - if (CI->getPredicate() == ICmpInst::ICMP_NE) - continue; - - // If split condition predicate is GT or GE then first execute - // false branch of split condition. - if (CI->getPredicate() == ICmpInst::ICMP_UGT - || CI->getPredicate() == ICmpInst::ICMP_SGT - || CI->getPredicate() == ICmpInst::ICMP_UGE - || CI->getPredicate() == ICmpInst::ICMP_SGE) - SD.UseTrueBranchFirst = false; - - // If one operand is loop invariant and second operand is SCEVAddRecExpr - // based on induction variable then CI is a candidate split condition. - if (safeICmpInst(CI, SD)) - SplitData.push_back(SD); - } +// Return min(V1, V1) +static Value *getMin(Value *V1, Value *V2, bool Sign, Instruction *InsertPt) { + + Value *C = new ICmpInst(Sign ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, + V1, V2, "lsp", InsertPt); + return SelectInst::Create(C, V1, V2, "lsp", InsertPt); } -// safeIcmpInst - CI is considered safe instruction if one of the operand -// is SCEVAddRecExpr based on induction variable and other operand is -// loop invariant. If CI is safe then populate SplitInfo object SD appropriately -// and return true; -bool LoopIndexSplit::safeICmpInst(ICmpInst *CI, SplitInfo &SD) { - - Value *V0 = CI->getOperand(0); - Value *V1 = CI->getOperand(1); - - SCEVHandle SH0 = SE->getSCEV(V0); - SCEVHandle SH1 = SE->getSCEV(V1); - - if (SH0->isLoopInvariant(L) && isa(SH1)) { - SD.SplitValue = V0; - SD.SplitCondition = CI; - if (PHINode *PN = dyn_cast(V1)) { - if (PN == IndVar) - return true; - } - else if (Instruction *Insn = dyn_cast(V1)) { - if (IndVarIncrement && IndVarIncrement == Insn) - return true; - } - } - else if (SH1->isLoopInvariant(L) && isa(SH0)) { - SD.SplitValue = V1; - SD.SplitCondition = CI; - if (PHINode *PN = dyn_cast(V0)) { - if (PN == IndVar) - return true; - } - else if (Instruction *Insn = dyn_cast(V0)) { - if (IndVarIncrement && IndVarIncrement == Insn) - return true; - } - } - - return false; +// Return max(V1, V2) +static Value *getMax(Value *V1, Value *V2, bool Sign, Instruction *InsertPt) { + + Value *C = new ICmpInst(Sign ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, + V1, V2, "lsp", InsertPt); + return SelectInst::Create(C, V2, V1, "lsp", InsertPt); } -/// processOneIterationLoop - Current loop L contains compare instruction -/// that compares induction variable, IndVar, against loop invariant. If -/// entire (i.e. meaningful) loop body is dominated by this compare -/// instruction then loop body is executed only once. In such case eliminate -/// loop structure surrounding this loop body. For example, -/// for (int i = start; i < end; ++i) { -/// if ( i == somevalue) { -/// loop_body -/// } -/// } -/// can be transformed into -/// if (somevalue >= start && somevalue < end) { -/// i = somevalue; -/// loop_body -/// } -bool LoopIndexSplit::processOneIterationLoop(SplitInfo &SD) { - +/// processOneIterationLoop -- Eliminate loop if loop body is executed +/// only once. For example, +/// for (i = 0; i < N; ++i) { +/// if ( i == X) { +/// ... +/// } +/// } +/// +bool LoopIndexSplit::processOneIterationLoop() { + SplitCondition = NULL; + BasicBlock *Latch = L->getLoopLatch(); BasicBlock *Header = L->getHeader(); - - // First of all, check if SplitCondition dominates entire loop body - // or not. - - // If SplitCondition is not in loop header then this loop is not suitable - // for this transformation. - if (SD.SplitCondition->getParent() != Header) - return false; - - // If loop header includes loop variant instruction operands then - // this loop may not be eliminated. - if (!safeHeader(SD, Header)) + BranchInst *BR = dyn_cast(Header->getTerminator()); + if (!BR) return false; + if (!isa(Latch->getTerminator())) return false; + if (BR->isUnconditional()) return false; + SplitCondition = dyn_cast(BR->getCondition()); + if (!SplitCondition) return false; + if (SplitCondition == ExitCondition) return false; + if (SplitCondition->getPredicate() != ICmpInst::ICMP_EQ) return false; + if (BR->getOperand(1) != Latch) return false; + if (!IVBasedValues.count(SplitCondition->getOperand(0)) + && !IVBasedValues.count(SplitCondition->getOperand(1))) return false; - // If Exiting block includes loop variant instructions then this - // loop may not be eliminated. - if (!safeExitingBlock(SD, ExitCondition->getParent())) + // If IV is used outside the loop then this loop traversal is required. + // FIXME: Calculate and use last IV value. + if (isUsedOutsideLoop(IVIncrement, L)) return false; - // Filter loops where split condition's false branch is not empty. - if (ExitCondition->getParent() != Header->getTerminator()->getSuccessor(1)) + // If BR operands are not IV or not loop invariants then skip this loop. + Value *OPV = SplitCondition->getOperand(0); + Value *SplitValue = SplitCondition->getOperand(1); + if (!L->isLoopInvariant(SplitValue)) { + Value *T = SplitValue; + SplitValue = OPV; + OPV = T; + } + if (!L->isLoopInvariant(SplitValue)) return false; - - // If split condition is not safe then do not process this loop. - // For example, - // for(int i = 0; i < N; i++) { - // if ( i == XYZ) { - // A; - // else - // B; - // } - // C; - // D; - // } - if (!safeSplitCondition(SD)) + Instruction *OPI = dyn_cast(OPV); + if (!OPI) return false; + if (OPI->getParent() != Header || isUsedOutsideLoop(OPI, L)) return false; - - BasicBlock *Latch = L->getLoopLatch(); - BranchInst *BR = dyn_cast(Latch->getTerminator()); - if (!BR) + + if (!cleanBlock(Header)) return false; - // Update CFG. + if (!cleanBlock(Latch)) + return false; + + // If the merge point for BR is not loop latch then skip this loop. + if (BR->getSuccessor(0) != Latch) { + DominanceFrontier::iterator DF0 = DF->find(BR->getSuccessor(0)); + assert (DF0 != DF->end() && "Unable to find dominance frontier"); + if (!DF0->second.count(Latch)) + return false; + } + + if (BR->getSuccessor(1) != Latch) { + DominanceFrontier::iterator DF1 = DF->find(BR->getSuccessor(1)); + assert (DF1 != DF->end() && "Unable to find dominance frontier"); + if (!DF1->second.count(Latch)) + return false; + } + + // Now, Current loop L contains compare instruction + // that compares induction variable, IndVar, against loop invariant. And + // entire (i.e. meaningful) loop body is dominated by this compare + // instruction. In such case eliminate + // loop structure surrounding this loop body. For example, + // for (int i = start; i < end; ++i) { + // if ( i == somevalue) { + // loop_body + // } + // } + // can be transformed into + // if (somevalue >= start && somevalue < end) { + // i = somevalue; + // loop_body + // } // Replace index variable with split value in loop body. Loop body is executed // only when index variable is equal to split value. - IndVar->replaceAllUsesWith(SD.SplitValue); - - Instruction *LTerminator = Latch->getTerminator(); - Instruction *Terminator = Header->getTerminator(); - Value *ExitValue = ExitCondition->getOperand(ExitValueNum); + IndVar->replaceAllUsesWith(SplitValue); // Replace split condition in header. // Transform @@ -596,21 +400,19 @@ // c1 = icmp uge i32 SplitValue, StartValue // c2 = icmp ult i32 SplitValue, ExitValue // and i32 c1, c2 - bool SignedPredicate = ExitCondition->isSignedPredicate(); - CmpInst::Predicate C2Predicate = ExitCondition->getPredicate(); - if (LTerminator->getOperand(0) != Header) - C2Predicate = CmpInst::getInversePredicate(C2Predicate); - Instruction *C1 = new ICmpInst(SignedPredicate ? + Instruction *C1 = new ICmpInst(ExitCondition->isSignedPredicate() ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE, - SD.SplitValue, StartValue, "lisplit", - Terminator); - Instruction *C2 = new ICmpInst(C2Predicate, - SD.SplitValue, ExitValue, "lisplit", - Terminator); - Instruction *NSplitCond = BinaryOperator::CreateAnd(C1, C2, "lisplit", - Terminator); - SD.SplitCondition->replaceAllUsesWith(NSplitCond); - SD.SplitCondition->eraseFromParent(); + SplitValue, IVStartValue, "lisplit", BR); + + CmpInst::Predicate C2P = ExitCondition->getPredicate(); + BranchInst *LatchBR = cast(Latch->getTerminator()); + if (LatchBR->getOperand(0) != Header) + C2P = CmpInst::getInversePredicate(C2P); + Instruction *C2 = new ICmpInst(C2P, SplitValue, IVExitValue, "lisplit", BR); + Instruction *NSplitCond = BinaryOperator::CreateAnd(C1, C2, "lisplit", BR); + + SplitCondition->replaceAllUsesWith(NSplitCond); + SplitCondition->eraseFromParent(); // Remove Latch to Header edge. BasicBlock *LatchSucc = NULL; @@ -620,40 +422,12 @@ if (Header != *SI) LatchSucc = *SI; } - BR->setUnconditionalDest(LatchSucc); - - // Now, clear latch block. Remove instructions that are responsible - // to increment induction variable. - for (BasicBlock::iterator LB = Latch->begin(), LE = Latch->end(); - LB != LE; ) { - Instruction *I = LB; - ++LB; - if (isa(I) || I == LTerminator) - continue; - - if (I == IndVarIncrement) { - // Replace induction variable increment if it is not used outside - // the loop. - bool UsedOutsideLoop = false; - for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); - UI != E; ++UI) { - if (Instruction *Use = dyn_cast(UI)) - if (!L->contains(Use->getParent())) { - UsedOutsideLoop = true; - break; - } - } - if (!UsedOutsideLoop) { - I->replaceAllUsesWith(ExitValue); - I->eraseFromParent(); - } - } - else { - I->replaceAllUsesWith(UndefValue::get(I->getType())); - I->eraseFromParent(); - } - } + LatchBR->setUnconditionalDest(LatchSucc); + // Remove IVIncrement + IVIncrement->replaceAllUsesWith(UndefValue::get(IVIncrement->getType())); + IVIncrement->eraseFromParent(); + LPM->deleteLoopFromQueue(L); // Update Dominator Info. @@ -669,330 +443,99 @@ if (LatchDF != DF->end()) DF->removeFromFrontier(LatchDF, Header); } - return true; -} - -// If loop header includes loop variant instruction operands then -// this loop can not be eliminated. This is used by processOneIterationLoop(). -bool LoopIndexSplit::safeHeader(SplitInfo &SD, BasicBlock *Header) { - - Instruction *Terminator = Header->getTerminator(); - for(BasicBlock::iterator BI = Header->begin(), BE = Header->end(); - BI != BE; ++BI) { - Instruction *I = BI; - - // PHI Nodes are OK. - if (isa(I)) - continue; - - // SplitCondition itself is OK. - if (I == SD.SplitCondition) - continue; - - // Induction variable is OK. - if (I == IndVar) - continue; - - // Induction variable increment is OK. - if (I == IndVarIncrement) - continue; - - // Terminator is also harmless. - if (I == Terminator) - continue; - - // Otherwise we have a instruction that may not be safe. - return false; - } - - return true; -} - -// If Exiting block includes loop variant instructions then this -// loop may not be eliminated. This is used by processOneIterationLoop(). -bool LoopIndexSplit::safeExitingBlock(SplitInfo &SD, - BasicBlock *ExitingBlock) { - - for (BasicBlock::iterator BI = ExitingBlock->begin(), - BE = ExitingBlock->end(); BI != BE; ++BI) { - Instruction *I = BI; - - // PHI Nodes are OK. - if (isa(I)) - continue; - - // Induction variable increment is OK. - if (IndVarIncrement && IndVarIncrement == I) - continue; - - // Check if I is induction variable increment instruction. - if (I->getOpcode() == Instruction::Add) { - - Value *Op0 = I->getOperand(0); - Value *Op1 = I->getOperand(1); - PHINode *PN = NULL; - ConstantInt *CI = NULL; - - if ((PN = dyn_cast(Op0))) { - if ((CI = dyn_cast(Op1))) - if (CI->isOne()) { - if (!IndVarIncrement && PN == IndVar) - IndVarIncrement = I; - // else this is another loop induction variable - continue; - } - } else - if ((PN = dyn_cast(Op1))) { - if ((CI = dyn_cast(Op0))) - if (CI->isOne()) { - if (!IndVarIncrement && PN == IndVar) - IndVarIncrement = I; - // else this is another loop induction variable - continue; - } - } - } - - // I is an Exit condition if next instruction is block terminator. - // Exit condition is OK if it compares loop invariant exit value, - // which is checked below. - else if (ICmpInst *EC = dyn_cast(I)) { - if (EC == ExitCondition) - continue; - } - - if (I == ExitingBlock->getTerminator()) - continue; - - // Otherwise we have instruction that may not be safe. - return false; - } - // We could not find any reason to consider ExitingBlock unsafe. + ++NumIndexSplitRemoved; return true; } -void LoopIndexSplit::updateLoopBounds(ICmpInst *CI) { - - Value *V0 = CI->getOperand(0); - Value *V1 = CI->getOperand(1); - Value *NV = NULL; - - SCEVHandle SH0 = SE->getSCEV(V0); - - if (SH0->isLoopInvariant(L)) - NV = V0; - else - NV = V1; - - if (ExitCondition->getPredicate() == ICmpInst::ICMP_SGT - || ExitCondition->getPredicate() == ICmpInst::ICMP_UGT - || ExitCondition->getPredicate() == ICmpInst::ICMP_SGE - || ExitCondition->getPredicate() == ICmpInst::ICMP_UGE) { - ExitCondition->swapOperands(); - if (ExitValueNum) - ExitValueNum = 0; - else - ExitValueNum = 1; +/// restrictLoopBound - Op dominates loop body. Op compares an IV based value +/// with a loop invariant value. Update loop's lower and upper bound based on +/// the loop invariant value. +bool LoopIndexSplit::restrictLoopBound(ICmpInst &Op) { + bool Sign = Op.isSignedPredicate(); + Instruction *PHTerm = L->getLoopPreheader()->getTerminator(); + + if (IVisGT(*ExitCondition) || IVisGE(*ExitCondition)) { + BranchInst *EBR = + cast(ExitCondition->getParent()->getTerminator()); + ExitCondition->setPredicate(ExitCondition->getInversePredicate()); + BasicBlock *T = EBR->getSuccessor(0); + EBR->setSuccessor(0, EBR->getSuccessor(1)); + EBR->setSuccessor(1, T); } - Value *NUB = NULL; + // New upper and lower bounds. Value *NLB = NULL; - Value *UB = ExitCondition->getOperand(ExitValueNum); - const Type *Ty = NV->getType(); - bool Sign = ExitCondition->isSignedPredicate(); - BasicBlock *Preheader = L->getLoopPreheader(); - Instruction *PHTerminator = Preheader->getTerminator(); - - assert (NV && "Unexpected value"); - - switch (CI->getPredicate()) { - case ICmpInst::ICMP_ULE: - case ICmpInst::ICMP_SLE: - // for (i = LB; i < UB; ++i) - // if (i <= NV && ...) - // LOOP_BODY - // - // is transformed into - // NUB = min (NV+1, UB) - // for (i = LB; i < NUB ; ++i) - // LOOP_BODY - // - if (ExitCondition->getPredicate() == ICmpInst::ICMP_SLT - || ExitCondition->getPredicate() == ICmpInst::ICMP_ULT) { - Value *A = BinaryOperator::CreateAdd(NV, ConstantInt::get(Ty, 1, Sign), - "lsplit.add", PHTerminator); - Value *C = new ICmpInst(Sign ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, - A, UB,"lsplit,c", PHTerminator); - NUB = SelectInst::Create(C, A, UB, "lsplit.nub", PHTerminator); - } - - // for (i = LB; i <= UB; ++i) - // if (i <= NV && ...) - // LOOP_BODY - // - // is transformed into - // NUB = min (NV, UB) - // for (i = LB; i <= NUB ; ++i) - // LOOP_BODY - // - else if (ExitCondition->getPredicate() == ICmpInst::ICMP_SLE - || ExitCondition->getPredicate() == ICmpInst::ICMP_ULE) { - Value *C = new ICmpInst(Sign ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, - NV, UB, "lsplit.c", PHTerminator); - NUB = SelectInst::Create(C, NV, UB, "lsplit.nub", PHTerminator); - } - break; - case ICmpInst::ICMP_ULT: - case ICmpInst::ICMP_SLT: - // for (i = LB; i < UB; ++i) - // if (i < NV && ...) - // LOOP_BODY - // - // is transformed into - // NUB = min (NV, UB) - // for (i = LB; i < NUB ; ++i) - // LOOP_BODY - // - if (ExitCondition->getPredicate() == ICmpInst::ICMP_SLT - || ExitCondition->getPredicate() == ICmpInst::ICMP_ULT) { - Value *C = new ICmpInst(Sign ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, - NV, UB, "lsplit.c", PHTerminator); - NUB = SelectInst::Create(C, NV, UB, "lsplit.nub", PHTerminator); - } + Value *NUB = NULL; + if (Value *V = IVisLT(Op)) { + // Restrict upper bound. + if (IVisLE(*ExitCondition)) + V = getMinusOne(V, Sign, PHTerm); + NUB = getMin(V, IVExitValue, Sign, PHTerm); + } else if (Value *V = IVisLE(Op)) { + // Restrict upper bound. + if (IVisLT(*ExitCondition)) + V = getPlusOne(V, Sign, PHTerm); + NUB = getMin(V, IVExitValue, Sign, PHTerm); + } else if (Value *V = IVisGT(Op)) { + // Restrict lower bound. + V = getPlusOne(V, Sign, PHTerm); + NLB = getMax(V, IVStartValue, Sign, PHTerm); + } else if (Value *V = IVisGE(Op)) + // Restrict lower bound. + NLB = getMax(V, IVStartValue, Sign, PHTerm); - // for (i = LB; i <= UB; ++i) - // if (i < NV && ...) - // LOOP_BODY - // - // is transformed into - // NUB = min (NV -1 , UB) - // for (i = LB; i <= NUB ; ++i) - // LOOP_BODY - // - else if (ExitCondition->getPredicate() == ICmpInst::ICMP_SLE - || ExitCondition->getPredicate() == ICmpInst::ICMP_ULE) { - Value *S = BinaryOperator::CreateSub(NV, ConstantInt::get(Ty, 1, Sign), - "lsplit.add", PHTerminator); - Value *C = new ICmpInst(Sign ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, - S, UB, "lsplit.c", PHTerminator); - NUB = SelectInst::Create(C, S, UB, "lsplit.nub", PHTerminator); - } - break; - case ICmpInst::ICMP_UGE: - case ICmpInst::ICMP_SGE: - // for (i = LB; i (< or <=) UB; ++i) - // if (i >= NV && ...) - // LOOP_BODY - // - // is transformed into - // NLB = max (NV, LB) - // for (i = NLB; i (< or <=) UB ; ++i) - // LOOP_BODY - // - { - Value *C = new ICmpInst(Sign ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, - NV, StartValue, "lsplit.c", PHTerminator); - NLB = SelectInst::Create(C, StartValue, NV, "lsplit.nlb", PHTerminator); - } - break; - case ICmpInst::ICMP_UGT: - case ICmpInst::ICMP_SGT: - // for (i = LB; i (< or <=) UB; ++i) - // if (i > NV && ...) - // LOOP_BODY - // - // is transformed into - // NLB = max (NV+1, LB) - // for (i = NLB; i (< or <=) UB ; ++i) - // LOOP_BODY - // - { - Value *A = BinaryOperator::CreateAdd(NV, ConstantInt::get(Ty, 1, Sign), - "lsplit.add", PHTerminator); - Value *C = new ICmpInst(Sign ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, - A, StartValue, "lsplit.c", PHTerminator); - NLB = SelectInst::Create(C, StartValue, A, "lsplit.nlb", PHTerminator); - } - break; - default: - assert ( 0 && "Unexpected split condition predicate"); - } + if (!NLB && !NUB) + return false; if (NLB) { - unsigned i = IndVar->getBasicBlockIndex(Preheader); + unsigned i = IndVar->getBasicBlockIndex(L->getLoopPreheader()); IndVar->setIncomingValue(i, NLB); } if (NUB) { - ExitCondition->setOperand(ExitValueNum, NUB); + unsigned i = (ExitCondition->getOperand(0) != IVExitValue); + ExitCondition->setOperand(i, NUB); } + return true; } -/// updateLoopIterationSpace - Current loop body is covered by an AND -/// instruction whose operands compares induction variables with loop -/// invariants. If possible, hoist this check outside the loop by -/// updating appropriate start and end values for induction variable. -bool LoopIndexSplit::updateLoopIterationSpace(SplitInfo &SD) { - BasicBlock *Header = L->getHeader(); - BasicBlock *ExitingBlock = ExitCondition->getParent(); - BasicBlock *SplitCondBlock = SD.SplitCondition->getParent(); - - ICmpInst *Op0 = cast(SD.SplitCondition->getOperand(0)); - ICmpInst *Op1 = cast(SD.SplitCondition->getOperand(1)); - - if (Op0->getPredicate() == ICmpInst::ICMP_EQ - || Op0->getPredicate() == ICmpInst::ICMP_NE - || Op1->getPredicate() == ICmpInst::ICMP_EQ - || Op1->getPredicate() == ICmpInst::ICMP_NE) - return false; - - // Check if SplitCondition dominates entire loop body - // or not. - - // If SplitCondition is not in loop header then this loop is not suitable - // for this transformation. - if (SD.SplitCondition->getParent() != Header) - return false; - - // If loop header includes loop variant instruction operands then - // this loop may not be eliminated. - Instruction *Terminator = Header->getTerminator(); - for(BasicBlock::iterator BI = Header->begin(), BE = Header->end(); - BI != BE; ++BI) { - Instruction *I = BI; - - // PHI Nodes are OK. - if (isa(I)) - continue; - - // SplitCondition itself is OK. - if (I == SD.SplitCondition) - continue; - if (I == Op0 || I == Op1) - continue; - - // Induction variable is OK. - if (I == IndVar) - continue; - // Induction variable increment is OK. - if (I == IndVarIncrement) - continue; - - // Terminator is also harmless. - if (I == Terminator) - continue; - - // Otherwise we have a instruction that may not be safe. +/// updateLoopIterationSpace -- Update loop's iteration space if loop +/// body is executed for certain IV range only. For example, +/// +/// for (i = 0; i < N; ++i) { +/// if ( i > A && i < B) { +/// ... +/// } +/// } +/// is trnasformed to iterators from A to B, if A > 0 and B < N. +/// +bool LoopIndexSplit::updateLoopIterationSpace() { + SplitCondition = NULL; + if (ExitCondition->getPredicate() == ICmpInst::ICMP_NE + || ExitCondition->getPredicate() == ICmpInst::ICMP_EQ) return false; - } + BasicBlock *Latch = L->getLoopLatch(); + BasicBlock *Header = L->getHeader(); + BranchInst *BR = dyn_cast(Header->getTerminator()); + if (!BR) return false; + if (!isa(Latch->getTerminator())) return false; + if (BR->isUnconditional()) return false; + BinaryOperator *AND = dyn_cast(BR->getCondition()); + if (!AND) return false; + if (AND->getOpcode() != Instruction::And) return false; + ICmpInst *Op0 = dyn_cast(AND->getOperand(0)); + ICmpInst *Op1 = dyn_cast(AND->getOperand(1)); + if (!Op0 || !Op1) + return false; + IVBasedValues.insert(AND); + IVBasedValues.insert(Op0); + IVBasedValues.insert(Op1); + if (!cleanBlock(Header)) return false; + BasicBlock *ExitingBlock = ExitCondition->getParent(); + if (!cleanBlock(ExitingBlock)) return false; - // If Exiting block includes loop variant instructions then this - // loop may not be eliminated. - if (!safeExitingBlock(SD, ExitCondition->getParent())) - return false; - - // Verify that loop exiting block has only two predecessor, where one predecessor + // Verify that loop exiting block has only two predecessor, where one pred // is split condition block. The other predecessor will become exiting block's // dominator after CFG is updated. TODO : Handle CFG's where exiting block has // more then two predecessors. This requires extra work in updating dominator @@ -1001,51 +544,43 @@ for (pred_iterator PI = pred_begin(ExitingBlock), PE = pred_end(ExitingBlock); PI != PE; ++PI) { BasicBlock *BB = *PI; - if (SplitCondBlock == BB) + if (Header == BB) continue; if (ExitingBBPred) return false; else ExitingBBPred = BB; } - - // Update loop bounds to absorb Op0 check. - updateLoopBounds(Op0); - // Update loop bounds to absorb Op1 check. - updateLoopBounds(Op1); - - // Update CFG - - // Unconditionally connect split block to its remaining successor. - BranchInst *SplitTerminator = - cast(SplitCondBlock->getTerminator()); - BasicBlock *Succ0 = SplitTerminator->getSuccessor(0); - BasicBlock *Succ1 = SplitTerminator->getSuccessor(1); - if (Succ0 == ExitCondition->getParent()) - SplitTerminator->setUnconditionalDest(Succ1); + + if (!restrictLoopBound(*Op0)) + return false; + + if (!restrictLoopBound(*Op1)) + return false; + + // Update CFG. + if (BR->getSuccessor(0) == ExitingBlock) + BR->setUnconditionalDest(BR->getSuccessor(1)); else - SplitTerminator->setUnconditionalDest(Succ0); + BR->setUnconditionalDest(BR->getSuccessor(0)); - // Remove split condition. - SD.SplitCondition->eraseFromParent(); + AND->eraseFromParent(); if (Op0->use_empty()) Op0->eraseFromParent(); if (Op1->use_empty()) Op1->eraseFromParent(); - - BranchInst *ExitInsn = - dyn_cast(ExitingBlock->getTerminator()); - assert (ExitInsn && "Unable to find suitable loop exit branch"); - BasicBlock *ExitBlock = ExitInsn->getSuccessor(1); - if (L->contains(ExitBlock)) - ExitBlock = ExitInsn->getSuccessor(0); // Update domiantor info. Now, ExitingBlock has only one predecessor, // ExitingBBPred, and it is ExitingBlock's immediate domiantor. DT->changeImmediateDominator(ExitingBlock, ExitingBBPred); - - // If ExitingBlock is a member of loop BB's DF list then replace it with - // loop header and exit block. + + BasicBlock *ExitBlock = ExitingBlock->getTerminator()->getSuccessor(1); + if (L->contains(ExitBlock)) + ExitBlock = ExitingBlock->getTerminator()->getSuccessor(0); + + // If ExitingBlock is a member of the loop basic blocks' DF list then + // replace ExitingBlock with header and exit block in the DF list + DominanceFrontier::iterator ExitingBlockDF = DF->find(ExitingBlock); for (Loop::block_iterator I = L->block_begin(), E = L->block_end(); I != E; ++I) { BasicBlock *BB = *I; @@ -1060,17 +595,17 @@ BasicBlock *DFBB = *CurrentItr; if (DFBB == ExitingBlock) { BBDF->second.erase(DFBB); - BBDF->second.insert(Header); - if (Header != ExitingBlock) - BBDF->second.insert(ExitBlock); + for (DominanceFrontier::DomSetType::iterator + EBI = ExitingBlockDF->second.begin(), + EBE = ExitingBlockDF->second.end(); EBI != EBE; ++EBI) + BBDF->second.insert(*EBI); } } } - + NumRestrictBounds++; return true; } - /// removeBlocks - Remove basic block DeadBB and all blocks dominated by DeadBB. /// This routine is used to remove split condition's dead branch, dominated by /// DeadBB. LiveBB dominates split conidition's other branch. @@ -1085,7 +620,8 @@ DominanceFrontier::DomSetType DeadBBSet = DeadBBDF->second; for (DominanceFrontier::DomSetType::iterator DeadBBSetI = DeadBBSet.begin(), - DeadBBSetE = DeadBBSet.end(); DeadBBSetI != DeadBBSetE; ++DeadBBSetI) { + DeadBBSetE = DeadBBSet.end(); DeadBBSetI != DeadBBSetE; ++DeadBBSetI) + { BasicBlock *FrontierBB = *DeadBBSetI; FrontierBBs.push_back(FrontierBB); @@ -1165,330 +701,258 @@ } -/// safeSplitCondition - Return true if it is possible to -/// split loop using given split condition. -bool LoopIndexSplit::safeSplitCondition(SplitInfo &SD) { - - BasicBlock *SplitCondBlock = SD.SplitCondition->getParent(); - BasicBlock *Latch = L->getLoopLatch(); - BranchInst *SplitTerminator = - cast(SplitCondBlock->getTerminator()); - BasicBlock *Succ0 = SplitTerminator->getSuccessor(0); - BasicBlock *Succ1 = SplitTerminator->getSuccessor(1); - - // If split block does not dominate the latch then this is not a diamond. - // Such loop may not benefit from index split. - if (!DT->dominates(SplitCondBlock, Latch)) - return false; +// moveExitCondition - Move exit condition EC into split condition block CondBB. +void LoopIndexSplit::moveExitCondition(BasicBlock *CondBB, BasicBlock *ActiveBB, + BasicBlock *ExitBB, ICmpInst *EC, + ICmpInst *SC, PHINode *IV, + Instruction *IVAdd, Loop *LP, + unsigned ExitValueNum) { - // Finally this split condition is safe only if merge point for - // split condition branch is loop latch. This check along with previous - // check, to ensure that exit condition is in either loop latch or header, - // filters all loops with non-empty loop body between merge point - // and exit condition. - DominanceFrontier::iterator Succ0DF = DF->find(Succ0); - assert (Succ0DF != DF->end() && "Unable to find Succ0 dominance frontier"); - if (Succ0DF->second.count(Latch)) - return true; + BasicBlock *ExitingBB = EC->getParent(); + Instruction *CurrentBR = CondBB->getTerminator(); - DominanceFrontier::iterator Succ1DF = DF->find(Succ1); - assert (Succ1DF != DF->end() && "Unable to find Succ1 dominance frontier"); - if (Succ1DF->second.count(Latch)) - return true; - - return false; -} + // Move exit condition into split condition block. + EC->moveBefore(CurrentBR); + EC->setOperand(ExitValueNum == 0 ? 1 : 0, IV); -/// calculateLoopBounds - ALoop exit value and BLoop start values are calculated -/// based on split value. -void LoopIndexSplit::calculateLoopBounds(SplitInfo &SD) { - - ICmpInst *SC = cast(SD.SplitCondition); - ICmpInst::Predicate SP = SC->getPredicate(); - const Type *Ty = SD.SplitValue->getType(); - bool Sign = ExitCondition->isSignedPredicate(); - BasicBlock *Preheader = L->getLoopPreheader(); - Instruction *PHTerminator = Preheader->getTerminator(); - - // Initially use split value as upper loop bound for first loop and lower loop - // bound for second loop. - Value *AEV = SD.SplitValue; - Value *BSV = SD.SplitValue; - - if (ExitCondition->getPredicate() == ICmpInst::ICMP_SGT - || ExitCondition->getPredicate() == ICmpInst::ICMP_UGT - || ExitCondition->getPredicate() == ICmpInst::ICMP_SGE - || ExitCondition->getPredicate() == ICmpInst::ICMP_UGE) { - ExitCondition->swapOperands(); - if (ExitValueNum) - ExitValueNum = 0; - else - ExitValueNum = 1; + // Move exiting block's branch into split condition block. Update its branch + // destination. + BranchInst *ExitingBR = cast(ExitingBB->getTerminator()); + ExitingBR->moveBefore(CurrentBR); + BasicBlock *OrigDestBB = NULL; + if (ExitingBR->getSuccessor(0) == ExitBB) { + OrigDestBB = ExitingBR->getSuccessor(1); + ExitingBR->setSuccessor(1, ActiveBB); } + else { + OrigDestBB = ExitingBR->getSuccessor(0); + ExitingBR->setSuccessor(0, ActiveBB); + } + + // Remove split condition and current split condition branch. + SC->eraseFromParent(); + CurrentBR->eraseFromParent(); - switch (ExitCondition->getPredicate()) { - case ICmpInst::ICMP_SGT: - case ICmpInst::ICMP_UGT: - case ICmpInst::ICMP_SGE: - case ICmpInst::ICMP_UGE: - default: - assert (0 && "Unexpected exit condition predicate"); - - case ICmpInst::ICMP_SLT: - case ICmpInst::ICMP_ULT: - { - switch (SP) { - case ICmpInst::ICMP_SLT: - case ICmpInst::ICMP_ULT: - // - // for (i = LB; i < UB; ++i) { if (i < SV) A; else B; } - // - // is transformed into - // AEV = BSV = SV - // for (i = LB; i < min(UB, AEV); ++i) - // A; - // for (i = max(LB, BSV); i < UB; ++i); - // B; - break; - case ICmpInst::ICMP_SLE: - case ICmpInst::ICMP_ULE: - { - // - // for (i = LB; i < UB; ++i) { if (i <= SV) A; else B; } - // - // is transformed into - // - // AEV = SV + 1 - // BSV = SV + 1 - // for (i = LB; i < min(UB, AEV); ++i) - // A; - // for (i = max(LB, BSV); i < UB; ++i) - // B; - BSV = BinaryOperator::CreateAdd(SD.SplitValue, - ConstantInt::get(Ty, 1, Sign), - "lsplit.add", PHTerminator); - AEV = BSV; - } - break; - case ICmpInst::ICMP_SGE: - case ICmpInst::ICMP_UGE: - // - // for (i = LB; i < UB; ++i) { if (i >= SV) A; else B; } - // - // is transformed into - // AEV = BSV = SV - // for (i = LB; i < min(UB, AEV); ++i) - // B; - // for (i = max(BSV, LB); i < UB; ++i) - // A; - break; - case ICmpInst::ICMP_SGT: - case ICmpInst::ICMP_UGT: - { - // - // for (i = LB; i < UB; ++i) { if (i > SV) A; else B; } - // - // is transformed into - // - // BSV = AEV = SV + 1 - // for (i = LB; i < min(UB, AEV); ++i) - // B; - // for (i = max(LB, BSV); i < UB; ++i) - // A; - BSV = BinaryOperator::CreateAdd(SD.SplitValue, - ConstantInt::get(Ty, 1, Sign), - "lsplit.add", PHTerminator); - AEV = BSV; - } - break; - default: - assert (0 && "Unexpected split condition predicate"); - break; - } // end switch (SP) - } - break; - case ICmpInst::ICMP_SLE: - case ICmpInst::ICMP_ULE: - { - switch (SP) { - case ICmpInst::ICMP_SLT: - case ICmpInst::ICMP_ULT: - // - // for (i = LB; i <= UB; ++i) { if (i < SV) A; else B; } - // - // is transformed into - // AEV = SV - 1; - // BSV = SV; - // for (i = LB; i <= min(UB, AEV); ++i) - // A; - // for (i = max(LB, BSV); i <= UB; ++i) - // B; - AEV = BinaryOperator::CreateSub(SD.SplitValue, - ConstantInt::get(Ty, 1, Sign), - "lsplit.sub", PHTerminator); - break; - case ICmpInst::ICMP_SLE: - case ICmpInst::ICMP_ULE: - // - // for (i = LB; i <= UB; ++i) { if (i <= SV) A; else B; } - // - // is transformed into - // AEV = SV; - // BSV = SV + 1; - // for (i = LB; i <= min(UB, AEV); ++i) - // A; - // for (i = max(LB, BSV); i <= UB; ++i) - // B; - BSV = BinaryOperator::CreateAdd(SD.SplitValue, - ConstantInt::get(Ty, 1, Sign), - "lsplit.add", PHTerminator); - break; - case ICmpInst::ICMP_SGT: - case ICmpInst::ICMP_UGT: - // - // for (i = LB; i <= UB; ++i) { if (i > SV) A; else B; } - // - // is transformed into - // AEV = SV; - // BSV = SV + 1; - // for (i = LB; i <= min(AEV, UB); ++i) - // B; - // for (i = max(LB, BSV); i <= UB; ++i) - // A; - BSV = BinaryOperator::CreateAdd(SD.SplitValue, - ConstantInt::get(Ty, 1, Sign), - "lsplit.add", PHTerminator); - break; - case ICmpInst::ICMP_SGE: - case ICmpInst::ICMP_UGE: - // ** TODO ** - // - // for (i = LB; i <= UB; ++i) { if (i >= SV) A; else B; } - // - // is transformed into - // AEV = SV - 1; - // BSV = SV; - // for (i = LB; i <= min(AEV, UB); ++i) - // B; - // for (i = max(LB, BSV); i <= UB; ++i) - // A; - AEV = BinaryOperator::CreateSub(SD.SplitValue, - ConstantInt::get(Ty, 1, Sign), - "lsplit.sub", PHTerminator); - break; - default: - assert (0 && "Unexpected split condition predicate"); - break; - } // end switch (SP) + // Connect exiting block to original destination. + BranchInst::Create(OrigDestBB, ExitingBB); + + // Update PHINodes + updatePHINodes(ExitBB, ExitingBB, CondBB, IV, IVAdd, LP); + + // Fix dominator info. + // ExitBB is now dominated by CondBB + DT->changeImmediateDominator(ExitBB, CondBB); + DF->changeImmediateDominator(ExitBB, CondBB, DT); + + // Basicblocks dominated by ActiveBB may have ExitingBB or + // a basic block outside the loop in their DF list. If so, + // replace it with CondBB. + DomTreeNode *Node = DT->getNode(ActiveBB); + for (df_iterator DI = df_begin(Node), DE = df_end(Node); + DI != DE; ++DI) { + BasicBlock *BB = DI->getBlock(); + DominanceFrontier::iterator BBDF = DF->find(BB); + DominanceFrontier::DomSetType::iterator DomSetI = BBDF->second.begin(); + DominanceFrontier::DomSetType::iterator DomSetE = BBDF->second.end(); + while (DomSetI != DomSetE) { + DominanceFrontier::DomSetType::iterator CurrentItr = DomSetI; + ++DomSetI; + BasicBlock *DFBB = *CurrentItr; + if (DFBB == ExitingBB || !L->contains(DFBB)) { + BBDF->second.erase(DFBB); + BBDF->second.insert(CondBB); + } } - break; } +} + +/// updatePHINodes - CFG has been changed. +/// Before +/// - ExitBB's single predecessor was Latch +/// - Latch's second successor was Header +/// Now +/// - ExitBB's single predecessor is Header +/// - Latch's one and only successor is Header +/// +/// Update ExitBB PHINodes' to reflect this change. +void LoopIndexSplit::updatePHINodes(BasicBlock *ExitBB, BasicBlock *Latch, + BasicBlock *Header, + PHINode *IV, Instruction *IVIncrement, + Loop *LP) { + + for (BasicBlock::iterator BI = ExitBB->begin(), BE = ExitBB->end(); + BI != BE; ) { + PHINode *PN = dyn_cast(BI); + ++BI; + if (!PN) + break; - // Calculate ALoop induction variable's new exiting value and - // BLoop induction variable's new starting value. Calculuate these - // values in original loop's preheader. - // A_ExitValue = min(SplitValue, OrignalLoopExitValue) - // B_StartValue = max(SplitValue, OriginalLoopStartValue) - Instruction *InsertPt = L->getHeader()->getFirstNonPHI(); - - // If ExitValue operand is also defined in Loop header then - // insert new ExitValue after this operand definition. - if (Instruction *EVN = - dyn_cast(ExitCondition->getOperand(ExitValueNum))) { - if (!isa(EVN)) - if (InsertPt->getParent() == EVN->getParent()) { - BasicBlock::iterator LHBI = L->getHeader()->begin(); - BasicBlock::iterator LHBE = L->getHeader()->end(); - for(;LHBI != LHBE; ++LHBI) { - Instruction *I = LHBI; - if (I == EVN) + Value *V = PN->getIncomingValueForBlock(Latch); + if (PHINode *PHV = dyn_cast(V)) { + // PHV is in Latch. PHV has one use is in ExitBB PHINode. And one use + // in Header which is new incoming value for PN. + Value *NewV = NULL; + for (Value::use_iterator UI = PHV->use_begin(), E = PHV->use_end(); + UI != E; ++UI) + if (PHINode *U = dyn_cast(*UI)) + if (LP->contains(U->getParent())) { + NewV = U; break; - } - InsertPt = ++LHBI; - } + } + + // Add incoming value from header only if PN has any use inside the loop. + if (NewV) + PN->addIncoming(NewV, Header); + + } else if (Instruction *PHI = dyn_cast(V)) { + // If this instruction is IVIncrement then IV is new incoming value + // from header otherwise this instruction must be incoming value from + // header because loop is in LCSSA form. + if (PHI == IVIncrement) + PN->addIncoming(IV, Header); + else + PN->addIncoming(V, Header); + } else + // Otherwise this is an incoming value from header because loop is in + // LCSSA form. + PN->addIncoming(V, Header); + + // Remove incoming value from Latch. + PN->removeIncomingValue(Latch); } - Value *C1 = new ICmpInst(Sign ? - ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, - AEV, - ExitCondition->getOperand(ExitValueNum), - "lsplit.ev", InsertPt); - - SD.A_ExitValue = SelectInst::Create(C1, AEV, - ExitCondition->getOperand(ExitValueNum), - "lsplit.ev", InsertPt); - - Value *C2 = new ICmpInst(Sign ? - ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, - BSV, StartValue, "lsplit.sv", - PHTerminator); - SD.B_StartValue = SelectInst::Create(C2, StartValue, BSV, - "lsplit.sv", PHTerminator); } -/// splitLoop - Split current loop L in two loops using split information -/// SD. Update dominator information. Maintain LCSSA form. -bool LoopIndexSplit::splitLoop(SplitInfo &SD) { - - if (!safeSplitCondition(SD)) +bool LoopIndexSplit::splitLoop() { + SplitCondition = NULL; + if (ExitCondition->getPredicate() == ICmpInst::ICMP_NE + || ExitCondition->getPredicate() == ICmpInst::ICMP_EQ) return false; + BasicBlock *Header = L->getHeader(); + BasicBlock *Latch = L->getLoopLatch(); + BranchInst *SBR = NULL; // Split Condition Branch + BranchInst *EBR = cast(ExitCondition->getParent()->getTerminator()); + // If Exiting block includes loop variant instructions then this + // loop may not be split safely. + BasicBlock *ExitingBlock = ExitCondition->getParent(); + if (!cleanBlock(ExitingBlock)) return false; - // If split condition EQ is not handled. - if (ICmpInst *ICMP = dyn_cast(SD.SplitCondition)) { - if (ICMP->getPredicate() == ICmpInst::ICMP_EQ) + for (Loop::block_iterator I = L->block_begin(), E = L->block_end(); + I != E; ++I) { + BranchInst *BR = dyn_cast((*I)->getTerminator()); + if (!BR || BR->isUnconditional()) continue; + ICmpInst *CI = dyn_cast(BR->getCondition()); + if (!CI || CI == ExitCondition + || CI->getPredicate() == ICmpInst::ICMP_NE + || CI->getPredicate() == ICmpInst::ICMP_EQ) + continue; + + // Unable to handle triangle loops at the moment. + // In triangle loop, split condition is in header and one of the + // the split destination is loop latch. If split condition is EQ + // then such loops are already handle in processOneIterationLoop(). + if (Header == (*I) + && (Latch == BR->getSuccessor(0) || Latch == BR->getSuccessor(1))) + continue; + + // If the block does not dominate the latch then this is not a diamond. + // Such loop may not benefit from index split. + if (!DT->dominates((*I), Latch)) + continue; + + // If split condition branches heads do not have single predecessor, + // SplitCondBlock, then is not possible to remove inactive branch. + if (!BR->getSuccessor(0)->getSinglePredecessor() + || !BR->getSuccessor(1)->getSinglePredecessor()) return false; + + // If the merge point for BR is not loop latch then skip this condition. + if (BR->getSuccessor(0) != Latch) { + DominanceFrontier::iterator DF0 = DF->find(BR->getSuccessor(0)); + assert (DF0 != DF->end() && "Unable to find dominance frontier"); + if (!DF0->second.count(Latch)) + continue; + } + + if (BR->getSuccessor(1) != Latch) { + DominanceFrontier::iterator DF1 = DF->find(BR->getSuccessor(1)); + assert (DF1 != DF->end() && "Unable to find dominance frontier"); + if (!DF1->second.count(Latch)) + continue; + } + SplitCondition = CI; + SBR = BR; + break; } + + if (!SplitCondition) + return false; // If the predicate sign does not match then skip. - ICmpInst *CI = dyn_cast(SD.SplitCondition); - if (CI && (ExitCondition->isSignedPredicate() != CI->isSignedPredicate())) + if (ExitCondition->isSignedPredicate() != SplitCondition->isSignedPredicate()) return false; - BasicBlock *SplitCondBlock = SD.SplitCondition->getParent(); - - // Unable to handle triangle loops at the moment. - // In triangle loop, split condition is in header and one of the - // the split destination is loop latch. If split condition is EQ - // then such loops are already handle in processOneIterationLoop(). - BasicBlock *Latch = L->getLoopLatch(); - BranchInst *SplitTerminator = - cast(SplitCondBlock->getTerminator()); - BasicBlock *Succ0 = SplitTerminator->getSuccessor(0); - BasicBlock *Succ1 = SplitTerminator->getSuccessor(1); - if (L->getHeader() == SplitCondBlock - && (Latch == Succ0 || Latch == Succ1)) + unsigned EVOpNum = (ExitCondition->getOperand(1) == IVExitValue); + unsigned SVOpNum = IVBasedValues.count(SplitCondition->getOperand(0)); + Value *SplitValue = SplitCondition->getOperand(SVOpNum); + if (!L->isLoopInvariant(SplitValue)) return false; - - // If split condition branches heads do not have single predecessor, - // SplitCondBlock, then is not possible to remove inactive branch. - if (!Succ0->getSinglePredecessor() || !Succ1->getSinglePredecessor()) + if (!IVBasedValues.count(SplitCondition->getOperand(!SVOpNum))) return false; - // If Exiting block includes loop variant instructions then this - // loop may not be split safely. - if (!safeExitingBlock(SD, ExitCondition->getParent())) - return false; + // Normalize loop conditions so that it is easier to calculate new loop + // bounds. + if (IVisGT(*ExitCondition) || IVisGE(*ExitCondition)) { + ExitCondition->setPredicate(ExitCondition->getInversePredicate()); + BasicBlock *T = EBR->getSuccessor(0); + EBR->setSuccessor(0, EBR->getSuccessor(1)); + EBR->setSuccessor(1, T); + } + + if (IVisGT(*SplitCondition) || IVisGE(*SplitCondition)) { + SplitCondition->setPredicate(SplitCondition->getInversePredicate()); + BasicBlock *T = SBR->getSuccessor(0); + SBR->setSuccessor(0, SBR->getSuccessor(1)); + SBR->setSuccessor(1, T); + } - // After loop is cloned there are two loops. - // - // First loop, referred as ALoop, executes first part of loop's iteration - // space split. Second loop, referred as BLoop, executes remaining - // part of loop's iteration space. - // - // ALoop's exit edge enters BLoop's header through a forwarding block which - // acts as a BLoop's preheader. - BasicBlock *Preheader = L->getLoopPreheader(); - - // Calculate ALoop induction variable's new exiting value and - // BLoop induction variable's new starting value. - calculateLoopBounds(SD); + //[*] Calculate new loop bounds. + Value *AEV = SplitValue; + Value *BSV = SplitValue; + bool Sign = SplitCondition->isSignedPredicate(); + Instruction *PHTerm = L->getLoopPreheader()->getTerminator(); + + if (IVisLT(*ExitCondition)) { + if (IVisLT(*SplitCondition)) { + /* Do nothing */ + } + else if (IVisLE(*SplitCondition)) { + AEV = getPlusOne(SplitValue, Sign, PHTerm); + BSV = getPlusOne(SplitValue, Sign, PHTerm); + } else { + assert (0 && "Unexpected split condition!"); + } + } + else if (IVisLE(*ExitCondition)) { + if (IVisLT(*SplitCondition)) { + AEV = getMinusOne(SplitValue, Sign, PHTerm); + } + else if (IVisLE(*SplitCondition)) { + BSV = getPlusOne(SplitValue, Sign, PHTerm); + } else { + assert (0 && "Unexpected split condition!"); + } + } else { + assert (0 && "Unexpected exit condition!"); + } + AEV = getMin(AEV, IVExitValue, Sign, PHTerm); + BSV = getMax(BSV, IVStartValue, Sign, PHTerm); - //[*] Clone loop. + // [*] Clone Loop DenseMap ValueMap; Loop *BLoop = CloneLoop(L, LPM, LI, ValueMap, this); Loop *ALoop = L; - BasicBlock *B_Header = BLoop->getHeader(); - //[*] ALoop's exiting edge BLoop's header. + // [*] ALoop's exiting edge enters BLoop's header. // ALoop's original exit block becomes BLoop's exit block. PHINode *B_IndVar = cast(ValueMap[IndVar]); BasicBlock *A_ExitingBlock = ExitCondition->getParent(); @@ -1496,23 +960,24 @@ dyn_cast(A_ExitingBlock->getTerminator()); assert (A_ExitInsn && "Unable to find suitable loop exit branch"); BasicBlock *B_ExitBlock = A_ExitInsn->getSuccessor(1); - if (L->contains(B_ExitBlock)) { + BasicBlock *B_Header = BLoop->getHeader(); + if (ALoop->contains(B_ExitBlock)) { B_ExitBlock = A_ExitInsn->getSuccessor(0); A_ExitInsn->setSuccessor(0, B_Header); } else A_ExitInsn->setSuccessor(1, B_Header); - //[*] Update ALoop's exit value using new exit value. - ExitCondition->setOperand(ExitValueNum, SD.A_ExitValue); - + // [*] Update ALoop's exit value using new exit value. + ExitCondition->setOperand(EVOpNum, AEV); + // [*] Update BLoop's header phi nodes. Remove incoming PHINode's from // original loop's preheader. Add incoming PHINode values from // ALoop's exiting block. Update BLoop header's domiantor info. // Collect inverse map of Header PHINodes. DenseMap InverseMap; - for (BasicBlock::iterator BI = L->getHeader()->begin(), - BE = L->getHeader()->end(); BI != BE; ++BI) { + for (BasicBlock::iterator BI = ALoop->getHeader()->begin(), + BE = ALoop->getHeader()->end(); BI != BE; ++BI) { if (PHINode *PN = dyn_cast(BI)) { PHINode *PNClone = cast(ValueMap[PN]); InverseMap[PNClone] = PN; @@ -1520,21 +985,22 @@ break; } + BasicBlock *A_Preheader = ALoop->getLoopPreheader(); for (BasicBlock::iterator BI = B_Header->begin(), BE = B_Header->end(); BI != BE; ++BI) { if (PHINode *PN = dyn_cast(BI)) { // Remove incoming value from original preheader. - PN->removeIncomingValue(Preheader); + PN->removeIncomingValue(A_Preheader); // Add incoming value from A_ExitingBlock. if (PN == B_IndVar) - PN->addIncoming(SD.B_StartValue, A_ExitingBlock); + PN->addIncoming(BSV, A_ExitingBlock); else { PHINode *OrigPN = cast(InverseMap[PN]); Value *V2 = NULL; // If loop header is also loop exiting block then // OrigPN is incoming value for B loop header. - if (A_ExitingBlock == L->getHeader()) + if (A_ExitingBlock == ALoop->getHeader()) V2 = OrigPN; else V2 = OrigPN->getIncomingValueForBlock(A_ExitingBlock); @@ -1543,6 +1009,7 @@ } else break; } + DT->changeImmediateDominator(B_Header, A_ExitingBlock); DF->changeImmediateDominator(B_Header, A_ExitingBlock, DT); @@ -1564,7 +1031,7 @@ DT->changeImmediateDominator(B_ExitBlock, B_ExitingBlock); DF->changeImmediateDominator(B_ExitBlock, B_ExitingBlock, DT); - //[*] Split ALoop's exit edge. This creates a new block which + //[*] Split ALoop's exit edge. This creates a new block which // serves two purposes. First one is to hold PHINode defnitions // to ensure that ALoop's LCSSA form. Second use it to act // as a preheader for BLoop. @@ -1586,17 +1053,12 @@ } //[*] Eliminate split condition's inactive branch from ALoop. - BasicBlock *A_SplitCondBlock = SD.SplitCondition->getParent(); + BasicBlock *A_SplitCondBlock = SplitCondition->getParent(); BranchInst *A_BR = cast(A_SplitCondBlock->getTerminator()); BasicBlock *A_InactiveBranch = NULL; BasicBlock *A_ActiveBranch = NULL; - if (SD.UseTrueBranchFirst) { - A_ActiveBranch = A_BR->getSuccessor(0); - A_InactiveBranch = A_BR->getSuccessor(1); - } else { - A_ActiveBranch = A_BR->getSuccessor(1); - A_InactiveBranch = A_BR->getSuccessor(0); - } + A_ActiveBranch = A_BR->getSuccessor(0); + A_InactiveBranch = A_BR->getSuccessor(1); A_BR->setUnconditionalDest(A_ActiveBranch); removeBlocks(A_InactiveBranch, L, A_ActiveBranch); @@ -1605,151 +1067,135 @@ BranchInst *B_BR = cast(B_SplitCondBlock->getTerminator()); BasicBlock *B_InactiveBranch = NULL; BasicBlock *B_ActiveBranch = NULL; - if (SD.UseTrueBranchFirst) { - B_ActiveBranch = B_BR->getSuccessor(1); - B_InactiveBranch = B_BR->getSuccessor(0); - } else { - B_ActiveBranch = B_BR->getSuccessor(0); - B_InactiveBranch = B_BR->getSuccessor(1); - } + B_ActiveBranch = B_BR->getSuccessor(1); + B_InactiveBranch = B_BR->getSuccessor(0); B_BR->setUnconditionalDest(B_ActiveBranch); removeBlocks(B_InactiveBranch, BLoop, B_ActiveBranch); - BasicBlock *A_Header = L->getHeader(); + BasicBlock *A_Header = ALoop->getHeader(); if (A_ExitingBlock == A_Header) return true; //[*] Move exit condition into split condition block to avoid // executing dead loop iteration. ICmpInst *B_ExitCondition = cast(ValueMap[ExitCondition]); - Instruction *B_IndVarIncrement = cast(ValueMap[IndVarIncrement]); - ICmpInst *B_SplitCondition = cast(ValueMap[SD.SplitCondition]); + Instruction *B_IndVarIncrement = cast(ValueMap[IVIncrement]); + ICmpInst *B_SplitCondition = cast(ValueMap[SplitCondition]); moveExitCondition(A_SplitCondBlock, A_ActiveBranch, A_ExitBlock, ExitCondition, - cast(SD.SplitCondition), IndVar, IndVarIncrement, - ALoop); + cast(SplitCondition), IndVar, IVIncrement, + ALoop, EVOpNum); - moveExitCondition(B_SplitCondBlock, B_ActiveBranch, B_ExitBlock, B_ExitCondition, - B_SplitCondition, B_IndVar, B_IndVarIncrement, BLoop); + moveExitCondition(B_SplitCondBlock, B_ActiveBranch, + B_ExitBlock, B_ExitCondition, + B_SplitCondition, B_IndVar, B_IndVarIncrement, + BLoop, EVOpNum); + NumIndexSplit++; return true; } -// moveExitCondition - Move exit condition EC into split condition block CondBB. -void LoopIndexSplit::moveExitCondition(BasicBlock *CondBB, BasicBlock *ActiveBB, - BasicBlock *ExitBB, ICmpInst *EC, ICmpInst *SC, - PHINode *IV, Instruction *IVAdd, Loop *LP) { +/// cleanBlock - A block is considered clean if all non terminal instructions +/// are either, PHINodes, IV based. +bool LoopIndexSplit::cleanBlock(BasicBlock *BB) { + Instruction *Terminator = BB->getTerminator(); + for(BasicBlock::iterator BI = BB->begin(), BE = BB->end(); + BI != BE; ++BI) { + Instruction *I = BI; - BasicBlock *ExitingBB = EC->getParent(); - Instruction *CurrentBR = CondBB->getTerminator(); + if (isa(I) || I == Terminator || I == ExitCondition + || I == SplitCondition || IVBasedValues.count(I)) + continue; - // Move exit condition into split condition block. - EC->moveBefore(CurrentBR); - EC->setOperand(ExitValueNum == 0 ? 1 : 0, IV); + if (I->mayWriteToMemory()) + return false; - // Move exiting block's branch into split condition block. Update its branch - // destination. - BranchInst *ExitingBR = cast(ExitingBB->getTerminator()); - ExitingBR->moveBefore(CurrentBR); - BasicBlock *OrigDestBB = NULL; - if (ExitingBR->getSuccessor(0) == ExitBB) { - OrigDestBB = ExitingBR->getSuccessor(1); - ExitingBR->setSuccessor(1, ActiveBB); - } - else { - OrigDestBB = ExitingBR->getSuccessor(0); - ExitingBR->setSuccessor(0, ActiveBB); - } - - // Remove split condition and current split condition branch. - SC->eraseFromParent(); - CurrentBR->eraseFromParent(); + // I is used only inside this block then it is OK. + bool usedOutsideBB = false; + for (Value::use_iterator UI = I->use_begin(), UE = I->use_end(); + UI != UE; ++UI) { + Instruction *U = cast(UI); + if (U->getParent() != BB) + usedOutsideBB = true; + } + if (!usedOutsideBB) + continue; - // Connect exiting block to original destination. - BranchInst::Create(OrigDestBB, ExitingBB); + // Otherwise we have a instruction that may not allow loop spliting. + return false; + } + return true; +} - // Update PHINodes - updatePHINodes(ExitBB, ExitingBB, CondBB, IV, IVAdd, LP); +/// IVisLT - If Op is comparing IV based value with an loop invaraint and +/// IV based value is less than the loop invariant then return the loop +/// invariant. Otherwise return NULL. +Value * LoopIndexSplit::IVisLT(ICmpInst &Op) { + ICmpInst::Predicate P = Op.getPredicate(); + if ((P == ICmpInst::ICMP_SLT || P == ICmpInst::ICMP_ULT) + && IVBasedValues.count(Op.getOperand(0)) + && L->isLoopInvariant(Op.getOperand(1))) + return Op.getOperand(1); + + if ((P == ICmpInst::ICMP_SGT || P == ICmpInst::ICMP_UGT) + && IVBasedValues.count(Op.getOperand(1)) + && L->isLoopInvariant(Op.getOperand(0))) + return Op.getOperand(0); - // Fix dominator info. - // ExitBB is now dominated by CondBB - DT->changeImmediateDominator(ExitBB, CondBB); - DF->changeImmediateDominator(ExitBB, CondBB, DT); - - // Basicblocks dominated by ActiveBB may have ExitingBB or - // a basic block outside the loop in their DF list. If so, - // replace it with CondBB. - DomTreeNode *Node = DT->getNode(ActiveBB); - for (df_iterator DI = df_begin(Node), DE = df_end(Node); - DI != DE; ++DI) { - BasicBlock *BB = DI->getBlock(); - DominanceFrontier::iterator BBDF = DF->find(BB); - DominanceFrontier::DomSetType::iterator DomSetI = BBDF->second.begin(); - DominanceFrontier::DomSetType::iterator DomSetE = BBDF->second.end(); - while (DomSetI != DomSetE) { - DominanceFrontier::DomSetType::iterator CurrentItr = DomSetI; - ++DomSetI; - BasicBlock *DFBB = *CurrentItr; - if (DFBB == ExitingBB || !L->contains(DFBB)) { - BBDF->second.erase(DFBB); - BBDF->second.insert(CondBB); - } - } - } + return NULL; } -/// updatePHINodes - CFG has been changed. -/// Before -/// - ExitBB's single predecessor was Latch -/// - Latch's second successor was Header -/// Now -/// - ExitBB's single predecessor is Header -/// - Latch's one and only successor is Header -/// -/// Update ExitBB PHINodes' to reflect this change. -void LoopIndexSplit::updatePHINodes(BasicBlock *ExitBB, BasicBlock *Latch, - BasicBlock *Header, - PHINode *IV, Instruction *IVIncrement, - Loop *LP) { +/// IVisLE - If Op is comparing IV based value with an loop invaraint and +/// IV based value is less than or equal to the loop invariant then +/// return the loop invariant. Otherwise return NULL. +Value * LoopIndexSplit::IVisLE(ICmpInst &Op) { + ICmpInst::Predicate P = Op.getPredicate(); + if ((P == ICmpInst::ICMP_SLE || P == ICmpInst::ICMP_ULE) + && IVBasedValues.count(Op.getOperand(0)) + && L->isLoopInvariant(Op.getOperand(1))) + return Op.getOperand(1); + + if ((P == ICmpInst::ICMP_SGE || P == ICmpInst::ICMP_UGE) + && IVBasedValues.count(Op.getOperand(1)) + && L->isLoopInvariant(Op.getOperand(0))) + return Op.getOperand(0); - for (BasicBlock::iterator BI = ExitBB->begin(), BE = ExitBB->end(); - BI != BE; ) { - PHINode *PN = dyn_cast(BI); - ++BI; - if (!PN) - break; + return NULL; +} - Value *V = PN->getIncomingValueForBlock(Latch); - if (PHINode *PHV = dyn_cast(V)) { - // PHV is in Latch. PHV has one use is in ExitBB PHINode. And one use - // in Header which is new incoming value for PN. - Value *NewV = NULL; - for (Value::use_iterator UI = PHV->use_begin(), E = PHV->use_end(); - UI != E; ++UI) - if (PHINode *U = dyn_cast(*UI)) - if (LP->contains(U->getParent())) { - NewV = U; - break; - } +/// IVisGT - If Op is comparing IV based value with an loop invaraint and +/// IV based value is greater than the loop invariant then return the loop +/// invariant. Otherwise return NULL. +Value * LoopIndexSplit::IVisGT(ICmpInst &Op) { + ICmpInst::Predicate P = Op.getPredicate(); + if ((P == ICmpInst::ICMP_SGT || P == ICmpInst::ICMP_UGT) + && IVBasedValues.count(Op.getOperand(0)) + && L->isLoopInvariant(Op.getOperand(1))) + return Op.getOperand(1); + + if ((P == ICmpInst::ICMP_SLT || P == ICmpInst::ICMP_ULT) + && IVBasedValues.count(Op.getOperand(1)) + && L->isLoopInvariant(Op.getOperand(0))) + return Op.getOperand(0); - // Add incoming value from header only if PN has any use inside the loop. - if (NewV) - PN->addIncoming(NewV, Header); + return NULL; +} - } else if (Instruction *PHI = dyn_cast(V)) { - // If this instruction is IVIncrement then IV is new incoming value - // from header otherwise this instruction must be incoming value from - // header because loop is in LCSSA form. - if (PHI == IVIncrement) - PN->addIncoming(IV, Header); - else - PN->addIncoming(V, Header); - } else - // Otherwise this is an incoming value from header because loop is in - // LCSSA form. - PN->addIncoming(V, Header); - - // Remove incoming value from Latch. - PN->removeIncomingValue(Latch); - } +/// IVisGE - If Op is comparing IV based value with an loop invaraint and +/// IV based value is greater than or equal to the loop invariant then +/// return the loop invariant. Otherwise return NULL. +Value * LoopIndexSplit::IVisGE(ICmpInst &Op) { + ICmpInst::Predicate P = Op.getPredicate(); + if ((P == ICmpInst::ICMP_SGE || P == ICmpInst::ICMP_UGE) + && IVBasedValues.count(Op.getOperand(0)) + && L->isLoopInvariant(Op.getOperand(1))) + return Op.getOperand(1); + + if ((P == ICmpInst::ICMP_SLE || P == ICmpInst::ICMP_ULE) + && IVBasedValues.count(Op.getOperand(1)) + && L->isLoopInvariant(Op.getOperand(0))) + return Op.getOperand(0); + + return NULL; } + Modified: llvm/trunk/test/Transforms/LoopIndexSplit/2007-09-24-UpdateIterationSpace.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopIndexSplit/2007-09-24-UpdateIterationSpace.ll?rev=60554&r1=60553&r2=60554&view=diff ============================================================================== --- llvm/trunk/test/Transforms/LoopIndexSplit/2007-09-24-UpdateIterationSpace.ll (original) +++ llvm/trunk/test/Transforms/LoopIndexSplit/2007-09-24-UpdateIterationSpace.ll Thu Dec 4 15:38:42 2008 @@ -13,7 +13,7 @@ br label %bb bb: ; preds = %bb.preheader, %cond_next45 - %i.01.0 = phi i32 [ %tmp47, %cond_next45 ], [ %xmin, %bb.preheader ] ; [#uses=6] + %i.01.0 = phi i32 [ %tmp47, %cond_next45 ], [ 0, %bb.preheader ] ; [#uses=6] %tmp2 = icmp sgt i32 %i.01.0, -1 ; [#uses=1] %tmp6 = icmp slt i32 %i.01.0, %ndat ; [#uses=1] %bothcond = and i1 %tmp2, %tmp6 ; [#uses=1] Modified: llvm/trunk/test/Transforms/LoopIndexSplit/2007-09-25-UpdateIterationSpace-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopIndexSplit/2007-09-25-UpdateIterationSpace-2.ll?rev=60554&r1=60553&r2=60554&view=diff ============================================================================== --- llvm/trunk/test/Transforms/LoopIndexSplit/2007-09-25-UpdateIterationSpace-2.ll (original) +++ llvm/trunk/test/Transforms/LoopIndexSplit/2007-09-25-UpdateIterationSpace-2.ll Thu Dec 4 15:38:42 2008 @@ -1,6 +1,7 @@ ; PR714 ; Update loop iteraton space to eliminate condition inside loop. ; RUN: llvm-as < %s | opt -loop-index-split | llvm-dis | not grep bothcond + define void @test(float* %x, i32 %ndat, float** %y, float %xcen, i32 %xmin, i32 %xmax, float %sigmal, float %contribution) { entry: %tmp5310 = icmp sgt i32 %xmin, %xmax ; [#uses=1] @@ -12,9 +13,9 @@ %tmp3839 = fpext float %sigmal to double ; [#uses=1] br label %bb -bb: ; preds = %bb.preheader, %cond_next45 - %i.01.0 = phi i32 [ %tmp47, %cond_next45 ], [ %xmin, %bb.preheader ] ; [#uses=4] - %k.06.0 = phi i32 [ %tmp49, %cond_next45 ], [ 0, %bb.preheader ] ; [#uses=3] +bb: ; preds = %cond_next45, %bb.preheader + %k.06.0 = phi i32 [ 0, %bb.preheader ], [ %indvar.next, %cond_next45 ] ; [#uses=4] + %i.01.0 = add i32 %k.06.0, %xmin ; [#uses=4] %tmp2 = icmp sgt i32 %i.01.0, -1 ; [#uses=1] %tmp6 = icmp slt i32 %i.01.0, %ndat ; [#uses=1] %bothcond = and i1 %tmp2, %tmp6 ; [#uses=1] @@ -24,7 +25,7 @@ %tmp12 = getelementptr float* %x, i32 %i.01.0 ; [#uses=1] %tmp13 = load float* %tmp12, align 4 ; [#uses=1] %tmp15 = sub float %xcen, %tmp13 ; [#uses=1] - %tmp16 = tail call float @fabsf( float %tmp15 ) ; [#uses=1] + %tmp16 = tail call float @fabsf(float %tmp15) ; [#uses=1] %tmp18 = fdiv float %tmp16, %sigmal ; [#uses=1] %tmp21 = load float** %y, align 4 ; [#uses=2] %tmp27 = getelementptr float* %tmp21, i32 %k.06.0 ; [#uses=1] @@ -32,7 +33,7 @@ %tmp2829 = fpext float %tmp28 to double ; [#uses=1] %tmp34 = sub float -0.000000e+00, %tmp18 ; [#uses=1] %tmp3435 = fpext float %tmp34 to double ; [#uses=1] - %tmp36 = tail call double @exp( double %tmp3435 ) ; [#uses=1] + %tmp36 = tail call double @exp(double %tmp3435) ; [#uses=1] %tmp37 = mul double %tmp32, %tmp36 ; [#uses=1] %tmp40 = fdiv double %tmp37, %tmp3839 ; [#uses=1] %tmp41 = add double %tmp2829, %tmp40 ; [#uses=1] @@ -41,10 +42,10 @@ store float %tmp4142, float* %tmp44, align 4 br label %cond_next45 -cond_next45: ; preds = %bb, %cond_true9 - %tmp47 = add i32 %i.01.0, 1 ; [#uses=2] - %tmp49 = add i32 %k.06.0, 1 ; [#uses=1] +cond_next45: ; preds = %cond_true9, %bb + %tmp47 = add i32 %i.01.0, 1 ; [#uses=1] %tmp53 = icmp sgt i32 %tmp47, %xmax ; [#uses=1] + %indvar.next = add i32 %k.06.0, 1 ; [#uses=1] br i1 %tmp53, label %return.loopexit, label %bb return.loopexit: ; preds = %cond_next45 Modified: llvm/trunk/test/Transforms/LoopIndexSplit/2008-10-10-OneIteration.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopIndexSplit/2008-10-10-OneIteration.ll?rev=60554&r1=60553&r2=60554&view=diff ============================================================================== --- llvm/trunk/test/Transforms/LoopIndexSplit/2008-10-10-OneIteration.ll (original) +++ llvm/trunk/test/Transforms/LoopIndexSplit/2008-10-10-OneIteration.ll Thu Dec 4 15:38:42 2008 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | opt -loop-index-split | llvm-dis | grep sle | count 1 +; RUN: llvm-as < %s | opt -loop-index-split -stats -disable-output |& grep "1 loop-index-split" ; PR 2869 @w = external global [2 x [2 x i32]] ; <[2 x [2 x i32]]*> [#uses=5] @@ -10,11 +10,11 @@ br label %bb1.i.outer bb1.i.outer: ; preds = %bb5.i, %entry - %i.0.reg2mem.0.ph.i.ph = phi i32 [ 0, %entry ], [ %4, %bb5.i ] ; [#uses=3] + %i.0.reg2mem.0.ph.i.ph = phi i32 [ 0, %entry ], [ %indvar.next1, %bb5.i ] ; [#uses=3] br label %bb1.i bb1.i: ; preds = %bb3.i, %bb1.i.outer - %j.0.reg2mem.0.i = phi i32 [ %2, %bb3.i ], [ 0, %bb1.i.outer ] ; [#uses=3] + %j.0.reg2mem.0.i = phi i32 [ 0, %bb1.i.outer ], [ %indvar.next, %bb3.i ] ; [#uses=3] %0 = icmp eq i32 %i.0.reg2mem.0.ph.i.ph, %j.0.reg2mem.0.i ; [#uses=1] br i1 %0, label %bb2.i, label %bb3.i @@ -24,34 +24,34 @@ br label %bb3.i bb3.i: ; preds = %bb2.i, %bb1.i - %2 = add i32 %j.0.reg2mem.0.i, 1 ; [#uses=2] - %3 = icmp sgt i32 %2, 1 ; [#uses=1] - br i1 %3, label %bb5.i, label %bb1.i + %indvar.next = add i32 %j.0.reg2mem.0.i, 1 ; [#uses=2] + %exitcond = icmp eq i32 %indvar.next, 2 ; [#uses=1] + br i1 %exitcond, label %bb5.i, label %bb1.i bb5.i: ; preds = %bb3.i - %4 = add i32 %i.0.reg2mem.0.ph.i.ph, 1 ; [#uses=2] - %5 = icmp sgt i32 %4, 1 ; [#uses=1] - br i1 %5, label %f.exit, label %bb1.i.outer + %indvar.next1 = add i32 %i.0.reg2mem.0.ph.i.ph, 1 ; [#uses=2] + %exitcond2 = icmp eq i32 %indvar.next1, 2 ; [#uses=1] + br i1 %exitcond2, label %f.exit, label %bb1.i.outer f.exit: ; preds = %bb5.i - %6 = load i32* getelementptr ([2 x [2 x i32]]* @w, i32 0, i32 0, i32 0), align 4 ; [#uses=1] - %7 = icmp eq i32 %6, 1 ; [#uses=1] - br i1 %7, label %bb, label %bb3 + %2 = load i32* getelementptr ([2 x [2 x i32]]* @w, i32 0, i32 0, i32 0), align 4 ; [#uses=1] + %3 = icmp eq i32 %2, 1 ; [#uses=1] + br i1 %3, label %bb, label %bb3 bb: ; preds = %f.exit - %8 = load i32* getelementptr ([2 x [2 x i32]]* @w, i32 0, i32 1, i32 1), align 4 ; [#uses=1] - %9 = icmp eq i32 %8, 1 ; [#uses=1] - br i1 %9, label %bb1, label %bb3 + %4 = load i32* getelementptr ([2 x [2 x i32]]* @w, i32 0, i32 1, i32 1), align 4 ; [#uses=1] + %5 = icmp eq i32 %4, 1 ; [#uses=1] + br i1 %5, label %bb1, label %bb3 bb1: ; preds = %bb - %10 = load i32* getelementptr ([2 x [2 x i32]]* @w, i32 0, i32 1, i32 0), align 4 ; [#uses=1] - %11 = icmp eq i32 %10, 0 ; [#uses=1] - br i1 %11, label %bb2, label %bb3 + %6 = load i32* getelementptr ([2 x [2 x i32]]* @w, i32 0, i32 1, i32 0), align 4 ; [#uses=1] + %7 = icmp eq i32 %6, 0 ; [#uses=1] + br i1 %7, label %bb2, label %bb3 bb2: ; preds = %bb1 - %12 = load i32* getelementptr ([2 x [2 x i32]]* @w, i32 0, i32 0, i32 1), align 4 ; [#uses=1] - %13 = icmp eq i32 %12, 0 ; [#uses=1] - br i1 %13, label %bb4, label %bb3 + %8 = load i32* getelementptr ([2 x [2 x i32]]* @w, i32 0, i32 0, i32 1), align 4 ; [#uses=1] + %9 = icmp eq i32 %8, 0 ; [#uses=1] + br i1 %9, label %bb4, label %bb3 bb3: ; preds = %bb2, %bb1, %bb, %f.exit tail call void @abort() noreturn nounwind Modified: llvm/trunk/test/Transforms/LoopIndexSplit/OneIterLoop-2007-08-17.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopIndexSplit/OneIterLoop-2007-08-17.ll?rev=60554&r1=60553&r2=60554&view=diff ============================================================================== --- llvm/trunk/test/Transforms/LoopIndexSplit/OneIterLoop-2007-08-17.ll (original) +++ llvm/trunk/test/Transforms/LoopIndexSplit/OneIterLoop-2007-08-17.ll Thu Dec 4 15:38:42 2008 @@ -13,7 +13,7 @@ define void @foo() { entry: - %tmp = load i32* @S1, align 4 ; [#uses=2] + %tmp = load i32* @S1, align 4 ; [#uses=4] %tmp266 = load i32* @N2, align 4 ; [#uses=1] %tmp288 = icmp ult i32 %tmp, %tmp266 ; [#uses=1] br i1 %tmp288, label %bb.preheader, label %return @@ -22,13 +22,19 @@ %tmp1 = load i32* @W1, align 4 ; [#uses=1] %tmp13 = load i32* @ti, align 4 ; [#uses=1] %tmp18 = load i32* @d, align 4 ; [#uses=1] - %tmp26 = load i32* @N2, align 4 ; [#uses=1] + %tmp26 = load i32* @N2, align 4 ; [#uses=2] %T1.promoted = load i32* @T1 ; [#uses=1] + %tmp2 = add i32 %tmp, 1 ; [#uses=2] + %tmp4 = icmp ugt i32 %tmp2, %tmp26 ; [#uses=1] + %umax = select i1 %tmp4, i32 %tmp2, i32 %tmp26 ; [#uses=1] + %tmp5 = sub i32 0, %tmp ; [#uses=1] + %tmp6 = add i32 %umax, %tmp5 ; [#uses=1] br label %bb -bb: ; preds = %bb.preheader, %bb25 +bb: ; preds = %bb25, %bb.preheader + %indvar = phi i32 [ 0, %bb.preheader ], [ %indvar.next, %bb25 ] ; [#uses=2] %T1.tmp.1 = phi i32 [ %T1.promoted, %bb.preheader ], [ %T1.tmp.0, %bb25 ] ; [#uses=3] - %tj.01.0 = phi i32 [ %tmp24, %bb25 ], [ %tmp, %bb.preheader ] ; [#uses=4] + %tj.01.0 = add i32 %indvar, %tmp ; [#uses=3] %tmp3 = icmp eq i32 %tj.01.0, %tmp1 ; [#uses=1] br i1 %tmp3, label %cond_true, label %bb25 @@ -45,11 +51,11 @@ %tmp21 = add i32 %tmp19, %T1.tmp.1 ; [#uses=1] br label %bb25 -bb25: ; preds = %cond_true, %bb, %cond_true12 +bb25: ; preds = %cond_true12, %cond_true, %bb %T1.tmp.0 = phi i32 [ %T1.tmp.1, %bb ], [ %T1.tmp.1, %cond_true ], [ %tmp21, %cond_true12 ] ; [#uses=2] - %tmp24 = add i32 %tj.01.0, 1 ; [#uses=2] - %tmp28 = icmp ult i32 %tmp24, %tmp26 ; [#uses=1] - br i1 %tmp28, label %bb, label %return.loopexit + %indvar.next = add i32 %indvar, 1 ; [#uses=2] + %exitcond = icmp ne i32 %indvar.next, %tmp6 ; [#uses=1] + br i1 %exitcond, label %bb, label %return.loopexit return.loopexit: ; preds = %bb25 %T1.tmp.0.lcssa = phi i32 [ %T1.tmp.0, %bb25 ] ; [#uses=1] Modified: llvm/trunk/test/Transforms/LoopIndexSplit/OneIterLoop2-2007-08-17.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopIndexSplit/OneIterLoop2-2007-08-17.ll?rev=60554&r1=60553&r2=60554&view=diff ============================================================================== --- llvm/trunk/test/Transforms/LoopIndexSplit/OneIterLoop2-2007-08-17.ll (original) +++ llvm/trunk/test/Transforms/LoopIndexSplit/OneIterLoop2-2007-08-17.ll Thu Dec 4 15:38:42 2008 @@ -14,7 +14,7 @@ define void @foo() { entry: - %tmp = load i32* @S1, align 4 ; [#uses=2] + %tmp = load i32* @S1, align 4 ; [#uses=4] %tmp266 = load i32* @N1, align 4 ; [#uses=1] %tmp288 = icmp ult i32 %tmp, %tmp266 ; [#uses=1] br i1 %tmp288, label %bb.preheader, label %return @@ -23,14 +23,20 @@ %tmp1 = load i32* @W1, align 4 ; [#uses=1] %tmp13 = load i32* @ti, align 4 ; [#uses=1] %tmp18 = load i32* @d, align 4 ; [#uses=1] - %tmp26 = load i32* @N1, align 4 ; [#uses=1] + %tmp26 = load i32* @N1, align 4 ; [#uses=2] %T1.promoted = load i32* @T1 ; [#uses=1] + %tmp2 = add i32 %tmp, 1 ; [#uses=2] + %tmp4 = icmp ugt i32 %tmp2, %tmp26 ; [#uses=1] + %umax = select i1 %tmp4, i32 %tmp2, i32 %tmp26 ; [#uses=1] + %tmp5 = sub i32 0, %tmp ; [#uses=1] + %tmp6 = add i32 %umax, %tmp5 ; [#uses=1] br label %bb -bb: ; preds = %bb.preheader, %bb25 +bb: ; preds = %bb25, %bb.preheader + %indvar = phi i32 [ 0, %bb.preheader ], [ %indvar.next, %bb25 ] ; [#uses=2] %T1.tmp.1 = phi i32 [ %T1.promoted, %bb.preheader ], [ %T1.tmp.0, %bb25 ] ; [#uses=3] - %tj.01.0 = phi i32 [ %tmp24, %bb25 ], [ %tmp, %bb.preheader ] ; [#uses=4] - %tmp24 = add i32 %tj.01.0, 1 ; [#uses=2] + %tj.01.0 = add i32 %indvar, %tmp ; [#uses=3] + %tmp24 = add i32 %tj.01.0, 1 ; [#uses=1] %tmp3 = icmp eq i32 %tmp24, %tmp1 ; [#uses=1] br i1 %tmp3, label %cond_true, label %bb25 @@ -47,10 +53,11 @@ %tmp21 = add i32 %tmp19, %T1.tmp.1 ; [#uses=1] br label %bb25 -bb25: ; preds = %cond_true, %bb, %cond_true12 +bb25: ; preds = %cond_true12, %cond_true, %bb %T1.tmp.0 = phi i32 [ %T1.tmp.1, %bb ], [ %T1.tmp.1, %cond_true ], [ %tmp21, %cond_true12 ] ; [#uses=2] - %tmp28 = icmp ult i32 %tmp24, %tmp26 ; [#uses=1] - br i1 %tmp28, label %bb, label %return.loopexit + %indvar.next = add i32 %indvar, 1 ; [#uses=2] + %exitcond = icmp ne i32 %indvar.next, %tmp6 ; [#uses=1] + br i1 %exitcond, label %bb, label %return.loopexit return.loopexit: ; preds = %bb25 %T1.tmp.0.lcssa = phi i32 [ %T1.tmp.0, %bb25 ] ; [#uses=1] From dpatel at apple.com Thu Dec 4 15:40:32 2008 From: dpatel at apple.com (Devang Patel) Date: Thu, 04 Dec 2008 21:40:32 -0000 Subject: [llvm-commits] [llvm] r60555 - /llvm/trunk/tools/opt/opt.cpp Message-ID: <200812042140.mB4LeW1m021365@zion.cs.uiuc.edu> Author: dpatel Date: Thu Dec 4 15:40:31 2008 New Revision: 60555 URL: http://llvm.org/viewvc/llvm-project?rev=60555&view=rev Log: Enable LoopIndexSplit pass. Modified: llvm/trunk/tools/opt/opt.cpp Modified: llvm/trunk/tools/opt/opt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/opt.cpp?rev=60555&r1=60554&r2=60555&view=diff ============================================================================== --- llvm/trunk/tools/opt/opt.cpp (original) +++ llvm/trunk/tools/opt/opt.cpp Thu Dec 4 15:40:31 2008 @@ -311,7 +311,7 @@ MPM.add(createLoopRotatePass()); // Rotate Loop MPM.add(createLICMPass()); // Hoist loop invariants MPM.add(createLoopUnswitchPass()); - // MPM.add(createLoopIndexSplitPass()); // Split loop index + MPM.add(createLoopIndexSplitPass()); // Split loop index MPM.add(createInstructionCombiningPass()); MPM.add(createIndVarSimplifyPass()); // Canonicalize indvars MPM.add(createLoopDeletionPass()); // Delete dead loops @@ -383,7 +383,7 @@ addPass(PM, createLoopRotatePass()); addPass(PM, createLICMPass()); // Hoist loop invariants addPass(PM, createLoopUnswitchPass()); // Unswitch loops. - // addPass(PM, createLoopIndexSplitPass()); // Index split loops. + addPass(PM, createLoopIndexSplitPass()); // Index split loops. // FIXME : Removing instcombine causes nestedloop regression. addPass(PM, createInstructionCombiningPass()); addPass(PM, createIndVarSimplifyPass()); // Canonicalize indvars From kremenek at apple.com Thu Dec 4 16:51:11 2008 From: kremenek at apple.com (Ted Kremenek) Date: Thu, 04 Dec 2008 22:51:11 -0000 Subject: [llvm-commits] [llvm] r60560 - in /llvm/trunk: include/llvm/Support/raw_ostream.h lib/Support/raw_ostream.cpp Message-ID: <200812042251.mB4MpB1S024384@zion.cs.uiuc.edu> Author: kremenek Date: Thu Dec 4 16:51:11 2008 New Revision: 60560 URL: http://llvm.org/viewvc/llvm-project?rev=60560&view=rev Log: Have raw_fd_ostream keep track of the position in the file to make tell() go faster by not requiring a flush(). Modified: llvm/trunk/include/llvm/Support/raw_ostream.h llvm/trunk/lib/Support/raw_ostream.cpp Modified: llvm/trunk/include/llvm/Support/raw_ostream.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/raw_ostream.h?rev=60560&r1=60559&r2=60560&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/raw_ostream.h (original) +++ llvm/trunk/include/llvm/Support/raw_ostream.h Thu Dec 4 16:51:11 2008 @@ -151,6 +151,7 @@ class raw_fd_ostream : public raw_ostream { int FD; bool ShouldClose; + uint64_t pos; public: /// raw_fd_ostream - Open the specified file for writing. If an /// error occurs, information about the error is put into ErrorInfo, @@ -178,7 +179,9 @@ void close(); /// tell - Return the current offset with the file. - uint64_t tell(); + uint64_t tell() { + return pos + (OutBufCur - OutBufStart); + } }; /// raw_stdout_ostream - This is a stream that always prints to stdout. Modified: llvm/trunk/lib/Support/raw_ostream.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/raw_ostream.cpp?rev=60560&r1=60559&r2=60560&view=diff ============================================================================== --- llvm/trunk/lib/Support/raw_ostream.cpp (original) +++ llvm/trunk/lib/Support/raw_ostream.cpp Thu Dec 4 16:51:11 2008 @@ -202,7 +202,7 @@ /// stream should be immediately destroyed; the string will be empty /// if no error occurred. raw_fd_ostream::raw_fd_ostream(const char *Filename, bool Binary, - std::string &ErrorInfo) { + std::string &ErrorInfo) : pos(0) { ErrorInfo.clear(); // Handle "-" as stdout. @@ -240,8 +240,10 @@ void raw_fd_ostream::flush_impl() { assert (FD >= 0 && "File already closed."); - if (OutBufCur-OutBufStart) + if (OutBufCur-OutBufStart) { + pos += (OutBufCur - OutBufStart); ::write(FD, OutBufStart, OutBufCur-OutBufStart); + } HandleFlush(); } @@ -253,14 +255,6 @@ FD = -1; } -uint64_t raw_fd_ostream::tell() { - // We have to take into account the bytes waiting in the buffer. For now - // we do the easy thing and just flush the buffer before getting the - // current file offset. - flush(); - return (uint64_t) lseek(FD, 0, SEEK_CUR); -} - //===----------------------------------------------------------------------===// // raw_stdout/err_ostream //===----------------------------------------------------------------------===// From scottm at aero.org Thu Dec 4 18:01:00 2008 From: scottm at aero.org (Scott Michel) Date: Fri, 05 Dec 2008 00:01:00 -0000 Subject: [llvm-commits] [llvm] r60566 - in /llvm/trunk/test/CodeGen/CellSPU/useful-harnesses: ./ README.txt vecoperations.c Message-ID: <200812050001.mB5010kv026397@zion.cs.uiuc.edu> Author: pingbak Date: Thu Dec 4 18:01:00 2008 New Revision: 60566 URL: http://llvm.org/viewvc/llvm-project?rev=60566&view=rev Log: CellSPU: Add new directory under tests/CodeGen/CellSPU to retain tests that aren't part of the test suite but are generally useful nonetheless, and can be expanded later to test the backend against the actual Cell SPU system. There's basically no other good place to put this code, so put it here for the time being. - vecoperations.c: Vector shuffles for all supported vector types, tests for v16i8 add and multiply. Added: llvm/trunk/test/CodeGen/CellSPU/useful-harnesses/ llvm/trunk/test/CodeGen/CellSPU/useful-harnesses/README.txt llvm/trunk/test/CodeGen/CellSPU/useful-harnesses/vecoperations.c Added: llvm/trunk/test/CodeGen/CellSPU/useful-harnesses/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/useful-harnesses/README.txt?rev=60566&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/useful-harnesses/README.txt (added) +++ llvm/trunk/test/CodeGen/CellSPU/useful-harnesses/README.txt Thu Dec 4 18:01:00 2008 @@ -0,0 +1,5 @@ +This directory contains code that's not part of the DejaGNU test suite, +but is generally useful as various test harnesses. + +vecoperations.c: Various vector operation sanity checks, e.g., shuffles, + 8-bit vector add and multiply. Added: llvm/trunk/test/CodeGen/CellSPU/useful-harnesses/vecoperations.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/useful-harnesses/vecoperations.c?rev=60566&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/useful-harnesses/vecoperations.c (added) +++ llvm/trunk/test/CodeGen/CellSPU/useful-harnesses/vecoperations.c Thu Dec 4 18:01:00 2008 @@ -0,0 +1,179 @@ +#include + +typedef unsigned char v16i8 __attribute__((ext_vector_type(16))); +typedef short v8i16 __attribute__((ext_vector_type(16))); +typedef int v4i32 __attribute__((ext_vector_type(4))); +typedef float v4f32 __attribute__((ext_vector_type(4))); +typedef long long v2i64 __attribute__((ext_vector_type(2))); +typedef double v2f64 __attribute__((ext_vector_type(2))); + +void print_v16i8(const char *str, const v16i8 v) { + union { + unsigned char elts[16]; + v16i8 vec; + } tv; + tv.vec = v; + printf("%s = { %hhu, %hhu, %hhu, %hhu, %hhu, %hhu, %hhu, " + "%hhu, %hhu, %hhu, %hhu, %hhu, %hhu, %hhu, " + "%hhu, %hhu }\n", + str, tv.elts[0], tv.elts[1], tv.elts[2], tv.elts[3], tv.elts[4], tv.elts[5], + tv.elts[6], tv.elts[7], tv.elts[8], tv.elts[9], tv.elts[10], tv.elts[11], + tv.elts[12], tv.elts[13], tv.elts[14], tv.elts[15]); +} + +void print_v16i8_hex(const char *str, const v16i8 v) { + union { + unsigned char elts[16]; + v16i8 vec; + } tv; + tv.vec = v; + printf("%s = { 0x%02hhx, 0x%02hhx, 0x%02hhx, 0x%02hhx, 0x%02hhx, 0x%02hhx, 0x%02hhx, " + "0x%02hhx, 0x%02hhx, 0x%02hhx, 0x%02hhx, 0x%02hhx, 0x%02hhx, 0x%02hhx, " + "0x%02hhx, 0x%02hhx }\n", + str, tv.elts[0], tv.elts[1], tv.elts[2], tv.elts[3], tv.elts[4], tv.elts[5], + tv.elts[6], tv.elts[7], tv.elts[8], tv.elts[9], tv.elts[10], tv.elts[11], + tv.elts[12], tv.elts[13], tv.elts[14], tv.elts[15]); +} + +void print_v8i16_hex(const char *str, v8i16 v) { + union { + short elts[8]; + v8i16 vec; + } tv; + tv.vec = v; + printf("%s = { 0x%04hx, 0x%04hx, 0x%04hx, 0x%04hx, 0x%04hx, " + "0x%04hx, 0x%04hx, 0x%04hx }\n", + str, tv.elts[0], tv.elts[1], tv.elts[2], tv.elts[3], tv.elts[4], + tv.elts[5], tv.elts[6], tv.elts[7]); +} + +void print_v4i32(const char *str, v4i32 v) { + printf("%s = { %d, %d, %d, %d }\n", str, v.x, v.y, v.z, v.w); +} + +void print_v4f32(const char *str, v4f32 v) { + printf("%s = { %f, %f, %f, %f }\n", str, v.x, v.y, v.z, v.w); +} + +void print_v2i64(const char *str, v2i64 v) { + printf("%s = { %lld, %lld }\n", str, v.x, v.y); +} + +void print_v2f64(const char *str, v2f64 v) { + printf("%s = { %g, %g }\n", str, v.x, v.y); +} + +/*----------------------------------------------------------------------*/ + +v16i8 v16i8_mpy(v16i8 v1, v16i8 v2) { + return v1 * v2; +} + +v16i8 v16i8_add(v16i8 v1, v16i8 v2) { + return v1 + v2; +} + +v4i32 v4i32_shuffle_1(v4i32 a) { + v4i32 c2 = a.yzwx; + return c2; +} + +v4i32 v4i32_shuffle_2(v4i32 a) { + v4i32 c2 = a.zwxy; + return c2; +} + +v4i32 v4i32_shuffle_3(v4i32 a) { + v4i32 c2 = a.wxyz; + return c2; +} + +v4i32 v4i32_shuffle_4(v4i32 a) { + v4i32 c2 = a.xyzw; + return c2; +} + +v4i32 v4i32_shuffle_5(v4i32 a) { + v4i32 c2 = a.xwzy; + return c2; +} + +v4f32 v4f32_shuffle_1(v4f32 a) { + v4f32 c2 = a.yzwx; + return c2; +} + +v4f32 v4f32_shuffle_2(v4f32 a) { + v4f32 c2 = a.zwxy; + return c2; +} + +v4f32 v4f32_shuffle_3(v4f32 a) { + v4f32 c2 = a.wxyz; + return c2; +} + +v4f32 v4f32_shuffle_4(v4f32 a) { + v4f32 c2 = a.xyzw; + return c2; +} + +v4f32 v4f32_shuffle_5(v4f32 a) { + v4f32 c2 = a.xwzy; + return c2; +} + +v2i64 v2i64_shuffle(v2i64 a) { + v2i64 c2 = a.yx; + return c2; +} + +v2f64 v2f64_shuffle(v2f64 a) { + v2f64 c2 = a.yx; + return c2; +} + +int main(void) { + v16i8 v00 = { 0xf4, 0xad, 0x01, 0xe9, 0x51, 0x78, 0xc1, 0x8a, + 0x94, 0x7c, 0x49, 0x6c, 0x21, 0x32, 0xb2, 0x04 }; + v16i8 va0 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 }; + v16i8 va1 = { 0x11, 0x83, 0x4b, 0x63, 0xff, 0x90, 0x32, 0xe5, + 0x5a, 0xaa, 0x20, 0x01, 0x0d, 0x15, 0x77, 0x05 }; + v8i16 v01 = { 0x1a87, 0x0a14, 0x5014, 0xfff0, + 0xe194, 0x0184, 0x801e, 0x5940 }; + v4i32 v1 = { 1, 2, 3, 4 }; + v4f32 v2 = { 1.0, 2.0, 3.0, 4.0 }; + v2i64 v3 = { 691043ll, 910301513ll }; + v2f64 v4 = { 5.8e56, 9.103e-62 }; + + puts("---- vector tests start ----"); + + print_v16i8_hex("v00 ", v00); + print_v16i8_hex("va0 ", va0); + print_v16i8_hex("va1 ", va1); + print_v16i8_hex("va0 x va1 ", v16i8_mpy(va0, va1)); + print_v16i8_hex("va0 + va1 ", v16i8_add(va0, va1)); + print_v8i16_hex("v01 ", v01); + + print_v4i32("v4i32_shuffle_1(1, 2, 3, 4)", v4i32_shuffle_1(v1)); + print_v4i32("v4i32_shuffle_2(1, 2, 3, 4)", v4i32_shuffle_2(v1)); + print_v4i32("v4i32_shuffle_3(1, 2, 3, 4)", v4i32_shuffle_3(v1)); + print_v4i32("v4i32_shuffle_4(1, 2, 3, 4)", v4i32_shuffle_4(v1)); + print_v4i32("v4i32_shuffle_5(1, 2, 3, 4)", v4i32_shuffle_5(v1)); + + print_v4f32("v4f32_shuffle_1(1, 2, 3, 4)", v4f32_shuffle_1(v2)); + print_v4f32("v4f32_shuffle_2(1, 2, 3, 4)", v4f32_shuffle_2(v2)); + print_v4f32("v4f32_shuffle_3(1, 2, 3, 4)", v4f32_shuffle_3(v2)); + print_v4f32("v4f32_shuffle_4(1, 2, 3, 4)", v4f32_shuffle_4(v2)); + print_v4f32("v4f32_shuffle_5(1, 2, 3, 4)", v4f32_shuffle_5(v2)); + + print_v2i64("v3 ", v3); + print_v2i64("v2i64_shuffle ", v2i64_shuffle(v3)); + print_v2f64("v4 ", v4); + print_v2f64("v2f64_shuffle ", v2f64_shuffle(v4)); + + puts("---- vector tests end ----"); + + return 0; +} From dpatel at apple.com Thu Dec 4 18:22:36 2008 From: dpatel at apple.com (Devang Patel) Date: Fri, 05 Dec 2008 00:22:36 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60569 - /llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Message-ID: <200812050022.mB50Maj7027105@zion.cs.uiuc.edu> Author: dpatel Date: Thu Dec 4 18:22:36 2008 New Revision: 60569 URL: http://llvm.org/viewvc/llvm-project?rev=60569&view=rev Log: Don't forget objective-c and objective-c++! Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp?rev=60569&r1=60568&r2=60569&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Thu Dec 4 18:22:36 2008 @@ -869,6 +869,10 @@ Unit->setLanguage(DW_LANG_Pascal83); else if (LanguageName == "GNU Java") Unit->setLanguage(DW_LANG_Java); + else if (LanguageName == "GNU Objective-C") + Unit->setLanguage(DW_LANG_ObjC); + else if (LanguageName == "GNU Objective-C++") + Unit->setLanguage(DW_LANG_ObjC_plus_plus); else Unit->setLanguage(DW_LANG_C89); From lattner at apple.com Thu Dec 4 19:01:45 2008 From: lattner at apple.com (Tanya Lattner) Date: Thu, 4 Dec 2008 17:01:45 -0800 Subject: [llvm-commits] [llvm] r60566 - in /llvm/trunk/test/CodeGen/CellSPU/useful-harnesses: ./ README.txt vecoperations.c In-Reply-To: <200812050001.mB5010kv026397@zion.cs.uiuc.edu> References: <200812050001.mB5010kv026397@zion.cs.uiuc.edu> Message-ID: <6129E781-3970-435C-9F91-D1CF1E7B3F87@apple.com> I don't really think this should be stored in the test directory. Things in the test directory should be tests only. Why can't you just make this an actual test and XFAIL if its not working or put it in a README in the Cell Target? I believe other targets have READMEs in their directories that mention potential optimizations or TODO items. -Tanya On Dec 4, 2008, at 4:01 PM, Scott Michel wrote: > Author: pingbak > Date: Thu Dec 4 18:01:00 2008 > New Revision: 60566 > > URL: http://llvm.org/viewvc/llvm-project?rev=60566&view=rev > Log: > CellSPU: Add new directory under tests/CodeGen/CellSPU to retain > tests that > aren't part of the test suite but are generally useful nonetheless, > and can > be expanded later to test the backend against the actual Cell SPU > system. > > There's basically no other good place to put this code, so put it > here for > the time being. > > - vecoperations.c: Vector shuffles for all supported vector types, > tests > for v16i8 add and multiply. > > Added: > llvm/trunk/test/CodeGen/CellSPU/useful-harnesses/ > llvm/trunk/test/CodeGen/CellSPU/useful-harnesses/README.txt > llvm/trunk/test/CodeGen/CellSPU/useful-harnesses/vecoperations.c > > Added: llvm/trunk/test/CodeGen/CellSPU/useful-harnesses/README.txt > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/useful-harnesses/README.txt?rev=60566&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/CellSPU/useful-harnesses/README.txt > (added) > +++ llvm/trunk/test/CodeGen/CellSPU/useful-harnesses/README.txt Thu > Dec 4 18:01:00 2008 > @@ -0,0 +1,5 @@ > +This directory contains code that's not part of the DejaGNU test > suite, > +but is generally useful as various test harnesses. > + > +vecoperations.c: Various vector operation sanity checks, e.g., > shuffles, > + 8-bit vector add and multiply. > > Added: llvm/trunk/test/CodeGen/CellSPU/useful-harnesses/ > vecoperations.c > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/useful-harnesses/vecoperations.c?rev=60566&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/CellSPU/useful-harnesses/vecoperations.c > (added) > +++ llvm/trunk/test/CodeGen/CellSPU/useful-harnesses/vecoperations.c > Thu Dec 4 18:01:00 2008 > @@ -0,0 +1,179 @@ > +#include > + > +typedef unsigned char v16i8 __attribute__((ext_vector_type(16))); > +typedef short v8i16 __attribute__((ext_vector_type(16))); > +typedef int v4i32 __attribute__((ext_vector_type(4))); > +typedef float v4f32 __attribute__((ext_vector_type(4))); > +typedef long long v2i64 __attribute__((ext_vector_type(2))); > +typedef double v2f64 __attribute__((ext_vector_type(2))); > + > +void print_v16i8(const char *str, const v16i8 v) { > + union { > + unsigned char elts[16]; > + v16i8 vec; > + } tv; > + tv.vec = v; > + printf("%s = { %hhu, %hhu, %hhu, %hhu, %hhu, %hhu, %hhu, " > + "%hhu, %hhu, %hhu, %hhu, %hhu, %hhu, %hhu, " > + "%hhu, %hhu }\n", > + str, tv.elts[0], tv.elts[1], tv.elts[2], tv.elts[3], tv.elts[4], > tv.elts[5], > + tv.elts[6], tv.elts[7], tv.elts[8], tv.elts[9], tv.elts[10], > tv.elts[11], > + tv.elts[12], tv.elts[13], tv.elts[14], tv.elts[15]); > +} > + > +void print_v16i8_hex(const char *str, const v16i8 v) { > + union { > + unsigned char elts[16]; > + v16i8 vec; > + } tv; > + tv.vec = v; > + printf("%s = { 0x%02hhx, 0x%02hhx, 0x%02hhx, 0x%02hhx, 0x%02hhx, > 0x%02hhx, 0x%02hhx, " > + "0x%02hhx, 0x%02hhx, 0x%02hhx, 0x%02hhx, 0x%02hhx, > 0x%02hhx, 0x%02hhx, " > + "0x%02hhx, 0x%02hhx }\n", > + str, tv.elts[0], tv.elts[1], tv.elts[2], tv.elts[3], tv.elts[4], > tv.elts[5], > + tv.elts[6], tv.elts[7], tv.elts[8], tv.elts[9], tv.elts[10], > tv.elts[11], > + tv.elts[12], tv.elts[13], tv.elts[14], tv.elts[15]); > +} > + > +void print_v8i16_hex(const char *str, v8i16 v) { > + union { > + short elts[8]; > + v8i16 vec; > + } tv; > + tv.vec = v; > + printf("%s = { 0x%04hx, 0x%04hx, 0x%04hx, 0x%04hx, 0x%04hx, " > + "0x%04hx, 0x%04hx, 0x%04hx }\n", > + str, tv.elts[0], tv.elts[1], tv.elts[2], tv.elts[3], tv.elts[4], > + tv.elts[5], tv.elts[6], tv.elts[7]); > +} > + > +void print_v4i32(const char *str, v4i32 v) { > + printf("%s = { %d, %d, %d, %d }\n", str, v.x, v.y, v.z, v.w); > +} > + > +void print_v4f32(const char *str, v4f32 v) { > + printf("%s = { %f, %f, %f, %f }\n", str, v.x, v.y, v.z, v.w); > +} > + > +void print_v2i64(const char *str, v2i64 v) { > + printf("%s = { %lld, %lld }\n", str, v.x, v.y); > +} > + > +void print_v2f64(const char *str, v2f64 v) { > + printf("%s = { %g, %g }\n", str, v.x, v.y); > +} > + > +/ > *----------------------------------------------------------------------*/ > + > +v16i8 v16i8_mpy(v16i8 v1, v16i8 v2) { > + return v1 * v2; > +} > + > +v16i8 v16i8_add(v16i8 v1, v16i8 v2) { > + return v1 + v2; > +} > + > +v4i32 v4i32_shuffle_1(v4i32 a) { > + v4i32 c2 = a.yzwx; > + return c2; > +} > + > +v4i32 v4i32_shuffle_2(v4i32 a) { > + v4i32 c2 = a.zwxy; > + return c2; > +} > + > +v4i32 v4i32_shuffle_3(v4i32 a) { > + v4i32 c2 = a.wxyz; > + return c2; > +} > + > +v4i32 v4i32_shuffle_4(v4i32 a) { > + v4i32 c2 = a.xyzw; > + return c2; > +} > + > +v4i32 v4i32_shuffle_5(v4i32 a) { > + v4i32 c2 = a.xwzy; > + return c2; > +} > + > +v4f32 v4f32_shuffle_1(v4f32 a) { > + v4f32 c2 = a.yzwx; > + return c2; > +} > + > +v4f32 v4f32_shuffle_2(v4f32 a) { > + v4f32 c2 = a.zwxy; > + return c2; > +} > + > +v4f32 v4f32_shuffle_3(v4f32 a) { > + v4f32 c2 = a.wxyz; > + return c2; > +} > + > +v4f32 v4f32_shuffle_4(v4f32 a) { > + v4f32 c2 = a.xyzw; > + return c2; > +} > + > +v4f32 v4f32_shuffle_5(v4f32 a) { > + v4f32 c2 = a.xwzy; > + return c2; > +} > + > +v2i64 v2i64_shuffle(v2i64 a) { > + v2i64 c2 = a.yx; > + return c2; > +} > + > +v2f64 v2f64_shuffle(v2f64 a) { > + v2f64 c2 = a.yx; > + return c2; > +} > + > +int main(void) { > + v16i8 v00 = { 0xf4, 0xad, 0x01, 0xe9, 0x51, 0x78, 0xc1, 0x8a, > + 0x94, 0x7c, 0x49, 0x6c, 0x21, 0x32, 0xb2, 0x04 }; > + v16i8 va0 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, > + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 }; > + v16i8 va1 = { 0x11, 0x83, 0x4b, 0x63, 0xff, 0x90, 0x32, 0xe5, > + 0x5a, 0xaa, 0x20, 0x01, 0x0d, 0x15, 0x77, 0x05 }; > + v8i16 v01 = { 0x1a87, 0x0a14, 0x5014, 0xfff0, > + 0xe194, 0x0184, 0x801e, 0x5940 }; > + v4i32 v1 = { 1, 2, 3, 4 }; > + v4f32 v2 = { 1.0, 2.0, 3.0, 4.0 }; > + v2i64 v3 = { 691043ll, 910301513ll }; > + v2f64 v4 = { 5.8e56, 9.103e-62 }; > + > + puts("---- vector tests start ----"); > + > + print_v16i8_hex("v00 ", v00); > + print_v16i8_hex("va0 ", va0); > + print_v16i8_hex("va1 ", va1); > + print_v16i8_hex("va0 x va1 ", v16i8_mpy(va0, > va1)); > + print_v16i8_hex("va0 + va1 ", v16i8_add(va0, > va1)); > + print_v8i16_hex("v01 ", v01); > + > + print_v4i32("v4i32_shuffle_1(1, 2, 3, 4)", v4i32_shuffle_1(v1)); > + print_v4i32("v4i32_shuffle_2(1, 2, 3, 4)", v4i32_shuffle_2(v1)); > + print_v4i32("v4i32_shuffle_3(1, 2, 3, 4)", v4i32_shuffle_3(v1)); > + print_v4i32("v4i32_shuffle_4(1, 2, 3, 4)", v4i32_shuffle_4(v1)); > + print_v4i32("v4i32_shuffle_5(1, 2, 3, 4)", v4i32_shuffle_5(v1)); > + > + print_v4f32("v4f32_shuffle_1(1, 2, 3, 4)", v4f32_shuffle_1(v2)); > + print_v4f32("v4f32_shuffle_2(1, 2, 3, 4)", v4f32_shuffle_2(v2)); > + print_v4f32("v4f32_shuffle_3(1, 2, 3, 4)", v4f32_shuffle_3(v2)); > + print_v4f32("v4f32_shuffle_4(1, 2, 3, 4)", v4f32_shuffle_4(v2)); > + print_v4f32("v4f32_shuffle_5(1, 2, 3, 4)", v4f32_shuffle_5(v2)); > + > + print_v2i64("v3 ", v3); > + print_v2i64("v2i64_shuffle ", v2i64_shuffle(v3)); > + print_v2f64("v4 ", v4); > + print_v2f64("v2f64_shuffle ", v2f64_shuffle(v4)); > + > + puts("---- vector tests end ----"); > + > + return 0; > +} > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081204/3e5b1c83/attachment.html From evan.cheng at apple.com Thu Dec 4 19:06:40 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 05 Dec 2008 01:06:40 -0000 Subject: [llvm-commits] [llvm] r60571 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp lib/Target/PowerPC/PPCSubtarget.cpp lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h lib/Target/X86/X86Subtarget.cpp test/CodeGen/PowerPC/hidden-vis-2.ll test/CodeGen/PowerPC/hidden-vis.ll test/CodeGen/X86/hidden-vis-2.ll test/CodeGen/X86/hidden-vis-3.ll test/CodeGen/X86/hidden-vis-4.ll Message-ID: <200812050106.mB516fiR028466@zion.cs.uiuc.edu> Author: evancheng Date: Thu Dec 4 19:06:39 2008 New Revision: 60571 URL: http://llvm.org/viewvc/llvm-project?rev=60571&view=rev Log: Re-did 60519. It turns out Darwin's handling of hidden visibility symbols are a bit more complicate than I expected. Both declarations and weak definitions still need a stub indirection. However, the stubs are in data section and they contain the addresses of the actual symbols. Added: llvm/trunk/test/CodeGen/PowerPC/hidden-vis-2.ll llvm/trunk/test/CodeGen/PowerPC/hidden-vis.ll llvm/trunk/test/CodeGen/X86/hidden-vis-3.ll llvm/trunk/test/CodeGen/X86/hidden-vis-4.ll Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h llvm/trunk/lib/Target/X86/X86Subtarget.cpp llvm/trunk/test/CodeGen/X86/hidden-vis-2.ll Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=60571&r1=60570&r2=60571&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Thu Dec 4 19:06:39 2008 @@ -830,9 +830,12 @@ /// GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol /// even in non-static mode. static bool GVIsIndirectSymbol(GlobalValue *GV, Reloc::Model RelocM) { - return RelocM != Reloc::Static && - (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || - (GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode())); + // If symbol visibility is hidden, the extra load is not needed if + // the symbol is definitely defined in the current translation unit. + bool isDecl = GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode(); + if (GV->hasHiddenVisibility() && (!isDecl && !GV->hasCommonLinkage())) + return false; + return RelocM != Reloc::Static && (isDecl || GV->mayBeOverridden()); } SDValue ARMTargetLowering::LowerGlobalAddressDarwin(SDValue Op, Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp?rev=60571&r1=60570&r2=60571&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Thu Dec 4 19:06:39 2008 @@ -32,6 +32,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringSet.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Mangler.h" #include "llvm/Support/MathExtras.h" @@ -73,11 +74,15 @@ /// GVNonLazyPtrs - Keeps the set of GlobalValues that require /// non-lazy-pointers for indirect access. - std::set GVNonLazyPtrs; + StringSet<> GVNonLazyPtrs; + + /// HiddenGVNonLazyPtrs - Keeps the set of GlobalValues with hidden + /// visibility that require non-lazy-pointers for indirect access. + StringSet<> HiddenGVNonLazyPtrs; /// FnStubs - Keeps the set of external function GlobalAddresses that the /// asm printer should generate stubs for. - std::set FnStubs; + StringSet<> FnStubs; /// PCRelGVs - Keeps the set of GlobalValues used in pc relative /// constantpool. @@ -141,7 +146,10 @@ if (!GV) Name += ACPV->getSymbol(); if (ACPV->isNonLazyPointer()) { - GVNonLazyPtrs.insert(Name); + if (GV->hasHiddenVisibility()) + HiddenGVNonLazyPtrs.insert(Name); + else + GVNonLazyPtrs.insert(Name); printSuffixedName(Name, "$non_lazy_ptr"); } else if (ACPV->isStub()) { FnStubs.insert(Name); @@ -927,9 +935,8 @@ SwitchToDataSection(""); // Output stubs for dynamically-linked functions - unsigned j = 1; - for (std::set::iterator i = FnStubs.begin(), e = FnStubs.end(); - i != e; ++i, ++j) { + for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end(); + i != e; ++i) { if (TM.getRelocationModel() == Reloc::PIC_) SwitchToTextSection(".section __TEXT,__picsymbolstub4,symbol_stubs," "none,16", 0); @@ -940,10 +947,10 @@ EmitAlignment(2); O << "\t.code\t32\n"; - std::string p = *i; + const char *p = i->getKeyData(); printSuffixedName(p, "$stub"); O << ":\n"; - O << "\t.indirect_symbol " << *i << "\n"; + O << "\t.indirect_symbol " << p << "\n"; O << "\tldr ip, "; printSuffixedName(p, "$slp"); O << "\n"; @@ -966,23 +973,37 @@ SwitchToDataSection(".lazy_symbol_pointer", 0); printSuffixedName(p, "$lazy_ptr"); O << ":\n"; - O << "\t.indirect_symbol " << *i << "\n"; + O << "\t.indirect_symbol " << p << "\n"; O << "\t.long\tdyld_stub_binding_helper\n"; } O << "\n"; // Output non-lazy-pointers for external and common global variables. - if (!GVNonLazyPtrs.empty()) + if (!GVNonLazyPtrs.empty()) { SwitchToDataSection(".non_lazy_symbol_pointer", 0); - for (std::set::iterator i = GVNonLazyPtrs.begin(), - e = GVNonLazyPtrs.end(); i != e; ++i) { - std::string p = *i; - printSuffixedName(p, "$non_lazy_ptr"); - O << ":\n"; - O << "\t.indirect_symbol " << *i << "\n"; - O << "\t.long\t0\n"; + for (StringSet<>::iterator i = GVNonLazyPtrs.begin(), + e = GVNonLazyPtrs.end(); i != e; ++i) { + const char *p = i->getKeyData(); + printSuffixedName(p, "$non_lazy_ptr"); + O << ":\n"; + O << "\t.indirect_symbol " << p << "\n"; + O << "\t.long\t0\n"; + } } + if (!HiddenGVNonLazyPtrs.empty()) { + SwitchToSection(TAI->getDataSection()); + for (StringSet<>::iterator i = HiddenGVNonLazyPtrs.begin(), + e = HiddenGVNonLazyPtrs.end(); i != e; ++i) { + const char *p = i->getKeyData(); + EmitAlignment(2); + printSuffixedName(p, "$non_lazy_ptr"); + O << ":\n"; + O << "\t.long " << p << "\n"; + } + } + + // Emit initial debug information. // FIXME: Dwarf support. //DW.EndModule(); Modified: llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp?rev=60571&r1=60570&r2=60571&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp Thu Dec 4 19:06:39 2008 @@ -43,14 +43,14 @@ #include "llvm/Target/TargetOptions.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" -#include +#include "llvm/ADT/StringSet.h" using namespace llvm; STATISTIC(EmittedInsts, "Number of machine instrs printed"); namespace { struct VISIBILITY_HIDDEN PPCAsmPrinter : public AsmPrinter { - std::set FnStubs, GVStubs; + StringSet<> FnStubs, GVStubs, HiddenGVStubs; const PPCSubtarget &Subtarget; PPCAsmPrinter(raw_ostream &O, TargetMachine &TM, const TargetAsmInfo *T) @@ -387,10 +387,18 @@ // External or weakly linked global variables need non-lazily-resolved stubs if (TM.getRelocationModel() != Reloc::Static) { - if (((GV->isDeclaration() || GV->hasWeakLinkage() || - GV->hasLinkOnceLinkage() || GV->hasCommonLinkage()))) { - GVStubs.insert(Name); - printSuffixedName(Name, "$non_lazy_ptr"); + if (GV->isDeclaration() || GV->mayBeOverridden()) { + if (GV->hasHiddenVisibility()) { + if (!GV->isDeclaration() && !GV->hasCommonLinkage()) + O << Name; + else { + HiddenGVStubs.insert(Name); + printSuffixedName(Name, "$non_lazy_ptr"); + } + } else { + GVStubs.insert(Name); + printSuffixedName(Name, "$non_lazy_ptr"); + } if (GV->hasExternalWeakLinkage()) ExtWeakSymbols.insert(GV); return; @@ -416,7 +424,10 @@ void PPCAsmPrinter::EmitExternalGlobal(const GlobalVariable *GV) { std::string Name = getGlobalLinkName(GV); if (TM.getRelocationModel() != Reloc::Static) { - GVStubs.insert(Name); + if (GV->hasHiddenVisibility()) + HiddenGVStubs.insert(Name); + else + GVStubs.insert(Name); printSuffixedName(Name, "$non_lazy_ptr"); return; } @@ -979,51 +990,70 @@ // Output stubs for dynamically-linked functions if (TM.getRelocationModel() == Reloc::PIC_) { - for (std::set::iterator i = FnStubs.begin(), e = FnStubs.end(); + for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end(); i != e; ++i) { SwitchToTextSection("\t.section __TEXT,__picsymbolstub1,symbol_stubs," "pure_instructions,32"); EmitAlignment(4); - std::string p = *i; - std::string L0p = (p[0]=='\"') ? "\"L0$" + p.substr(1) : "L0$" + p ; + const char *p = i->getKeyData(); + bool hasQuote = p[0]=='\"'; printSuffixedName(p, "$stub"); O << ":\n"; - O << "\t.indirect_symbol " << *i << '\n'; + O << "\t.indirect_symbol " << p << '\n'; O << "\tmflr r0\n"; - O << "\tbcl 20,31," << L0p << '\n'; - O << L0p << ":\n"; + O << "\tbcl 20,31,"; + if (hasQuote) + O << "\"L0$" << &p[1]; + else + O << "L0$" << p; + O << '\n'; + if (hasQuote) + O << "\"L0$" << &p[1]; + else + O << "L0$" << p; + O << ":\n"; O << "\tmflr r11\n"; O << "\taddis r11,r11,ha16("; printSuffixedName(p, "$lazy_ptr"); - O << "-" << L0p << ")\n"; + O << "-"; + if (hasQuote) + O << "\"L0$" << &p[1]; + else + O << "L0$" << p; + O << ")\n"; O << "\tmtlr r0\n"; if (isPPC64) O << "\tldu r12,lo16("; else O << "\tlwzu r12,lo16("; printSuffixedName(p, "$lazy_ptr"); - O << "-" << L0p << ")(r11)\n"; + O << "-"; + if (hasQuote) + O << "\"L0$" << &p[1]; + else + O << "L0$" << p; + O << ")(r11)\n"; O << "\tmtctr r12\n"; O << "\tbctr\n"; SwitchToDataSection(".lazy_symbol_pointer"); printSuffixedName(p, "$lazy_ptr"); O << ":\n"; - O << "\t.indirect_symbol " << *i << '\n'; + O << "\t.indirect_symbol " << p << '\n'; if (isPPC64) O << "\t.quad dyld_stub_binding_helper\n"; else O << "\t.long dyld_stub_binding_helper\n"; } } else { - for (std::set::iterator i = FnStubs.begin(), e = FnStubs.end(); + for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end(); i != e; ++i) { SwitchToTextSection("\t.section __TEXT,__symbol_stub1,symbol_stubs," "pure_instructions,16"); EmitAlignment(4); - std::string p = *i; + const char *p = i->getKeyData(); printSuffixedName(p, "$stub"); O << ":\n"; - O << "\t.indirect_symbol " << *i << '\n'; + O << "\t.indirect_symbol " << p << '\n'; O << "\tlis r11,ha16("; printSuffixedName(p, "$lazy_ptr"); O << ")\n"; @@ -1038,7 +1068,7 @@ SwitchToDataSection(".lazy_symbol_pointer"); printSuffixedName(p, "$lazy_ptr"); O << ":\n"; - O << "\t.indirect_symbol " << *i << '\n'; + O << "\t.indirect_symbol " << p << '\n'; if (isPPC64) O << "\t.quad dyld_stub_binding_helper\n"; else @@ -1061,12 +1091,12 @@ // Output stubs for external and common global variables. if (!GVStubs.empty()) { SwitchToDataSection(".non_lazy_symbol_pointer"); - for (std::set::iterator I = GVStubs.begin(), - E = GVStubs.end(); I != E; ++I) { - std::string p = *I; + for (StringSet<>::iterator i = GVStubs.begin(), e = GVStubs.end(); + i != e; ++i) { + std::string p = i->getKeyData(); printSuffixedName(p, "$non_lazy_ptr"); O << ":\n"; - O << "\t.indirect_symbol " << *I << '\n'; + O << "\t.indirect_symbol " << p << '\n'; if (isPPC64) O << "\t.quad\t0\n"; else @@ -1074,6 +1104,23 @@ } } + if (!HiddenGVStubs.empty()) { + SwitchToSection(TAI->getDataSection()); + for (StringSet<>::iterator i = HiddenGVStubs.begin(), e = HiddenGVStubs.end(); + i != e; ++i) { + std::string p = i->getKeyData(); + EmitAlignment(isPPC64 ? 3 : 2); + printSuffixedName(p, "$non_lazy_ptr"); + O << ":\n"; + if (isPPC64) + O << "\t.quad\t"; + else + O << "\t.long\t"; + O << p << '\n'; + } + } + + // Emit initial debug information. DW.EndModule(); Modified: llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp?rev=60571&r1=60570&r2=60571&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp Thu Dec 4 19:06:39 2008 @@ -141,8 +141,11 @@ // We never hae stubs if HasLazyResolverStubs=false or if in static mode. if (!HasLazyResolverStubs || TM.getRelocationModel() == Reloc::Static) return false; - + // If symbol visibility is hidden, the extra load is not needed if + // the symbol is definitely defined in the current translation unit. + bool isDecl = GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode(); + if (GV->hasHiddenVisibility() && !isDecl && !GV->hasCommonLinkage()) + return false; return GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || - GV->hasCommonLinkage() || - (GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode()); + GV->hasCommonLinkage() || isDecl; } Modified: llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp?rev=60571&r1=60570&r2=60571&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp Thu Dec 4 19:06:39 2008 @@ -391,6 +391,14 @@ FnStubs.insert(Name); printSuffixedName(Name, "$stub"); } + } else if (GV->hasHiddenVisibility()) { + if (!GV->isDeclaration() && !GV->hasCommonLinkage()) + // Definition is not definitely in the current translation unit. + O << Name; + else { + HiddenGVStubs.insert(Name); + printSuffixedName(Name, "$non_lazy_ptr"); + } } else { GVStubs.insert(Name); printSuffixedName(Name, "$non_lazy_ptr"); @@ -875,6 +883,15 @@ O << GV << "\n\t.long\t0\n"; } +/// printHiddenGVStub - Print stub for a hidden global value. +/// +void X86ATTAsmPrinter::printHiddenGVStub(const char *GV, const char *Prefix) { + EmitAlignment(2); + printSuffixedName(GV, "$non_lazy_ptr", Prefix); + if (Prefix) O << Prefix; + O << ":\n" << TAI->getData32bitsDirective() << GV << '\n'; +} + bool X86ATTAsmPrinter::doFinalization(Module &M) { // Print out module-level global variables here. @@ -908,9 +925,8 @@ SwitchToDataSection(""); // Output stubs for dynamically-linked functions - unsigned j = 1; for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end(); - i != e; ++i, ++j) { + i != e; ++i) { SwitchToDataSection("\t.section __IMPORT,__jump_table,symbol_stubs," "self_modifying_code+pure_instructions,5", 0); const char *p = i->getKeyData(); @@ -949,6 +965,13 @@ i != e; ++i) printGVStub(i->getKeyData()); + if (!HiddenGVStubs.empty()) { + SwitchToSection(TAI->getDataSection()); + for (StringSet<>::iterator i = HiddenGVStubs.begin(), e = HiddenGVStubs.end(); + i != e; ++i) + printHiddenGVStub(i->getKeyData()); + } + // Emit final debug information. DW.EndModule(); Modified: llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h?rev=60571&r1=60570&r2=60571&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h (original) +++ llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h Thu Dec 4 19:06:39 2008 @@ -121,13 +121,14 @@ void printModuleLevelGV(const GlobalVariable* GVar); void printGVStub(const char *GV, const char *Prefix = NULL); + void printHiddenGVStub(const char *GV, const char *Prefix = NULL); bool runOnMachineFunction(MachineFunction &F); void emitFunctionHeader(const MachineFunction &MF); // Necessary for Darwin to print out the apprioriate types of linker stubs - StringSet<> FnStubs, GVStubs, LinkOnceStubs; + StringSet<> FnStubs, GVStubs, HiddenGVStubs; // Necessary for dllexport support StringSet<> DLLExportedFns, DLLExportedGVs; Modified: llvm/trunk/lib/Target/X86/X86Subtarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.cpp?rev=60571&r1=60570&r2=60571&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Subtarget.cpp (original) +++ llvm/trunk/lib/Target/X86/X86Subtarget.cpp Thu Dec 4 19:06:39 2008 @@ -40,10 +40,14 @@ if (TM.getRelocationModel() != Reloc::Static && TM.getCodeModel() != CodeModel::Large) { if (isTargetDarwin()) { - return (!isDirectCall && - (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || - GV->hasCommonLinkage() || - (GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode()))); + bool isDecl = GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode(); + if (GV->hasHiddenVisibility() && + (Is64Bit || (!isDecl && !GV->hasCommonLinkage()))) + // If symbol visibility is hidden, the extra load is not needed if + // target is x86-64 or the symbol is definitely defined in the current + // translation unit. + return false; + return !isDirectCall && (isDecl || GV->mayBeOverridden()); } else if (isTargetELF()) { // Extra load is needed for all externally visible. if (isDirectCall) Added: llvm/trunk/test/CodeGen/PowerPC/hidden-vis-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/hidden-vis-2.ll?rev=60571&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/PowerPC/hidden-vis-2.ll (added) +++ llvm/trunk/test/CodeGen/PowerPC/hidden-vis-2.ll Thu Dec 4 19:06:39 2008 @@ -0,0 +1,12 @@ +; RUN: llvm-as < %s | llc -mtriple=powerpc-apple-darwin9 | grep non_lazy_ptr | count 6 + + at x = external hidden global i32 ; [#uses=1] + at y = extern_weak hidden global i32 ; [#uses=1] + +define i32 @t() nounwind readonly { +entry: + %0 = load i32* @x, align 4 ; [#uses=1] + %1 = load i32* @y, align 4 ; [#uses=1] + %2 = add i32 %1, %0 ; [#uses=1] + ret i32 %2 +} Added: llvm/trunk/test/CodeGen/PowerPC/hidden-vis.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/hidden-vis.ll?rev=60571&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/PowerPC/hidden-vis.ll (added) +++ llvm/trunk/test/CodeGen/PowerPC/hidden-vis.ll Thu Dec 4 19:06:39 2008 @@ -0,0 +1,9 @@ +; RUN: llvm-as < %s | llc -mtriple=powerpc-apple-darwin9 | not grep non_lazy_ptr + + at x = weak hidden global i32 0 ; [#uses=1] + +define i32 @t() nounwind readonly { +entry: + %0 = load i32* @x, align 4 ; [#uses=1] + ret i32 %0 +} Modified: llvm/trunk/test/CodeGen/X86/hidden-vis-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/hidden-vis-2.ll?rev=60571&r1=60570&r2=60571&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/hidden-vis-2.ll (original) +++ llvm/trunk/test/CodeGen/X86/hidden-vis-2.ll Thu Dec 4 19:06:39 2008 @@ -1,6 +1,5 @@ ; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep mov | count 1 ; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin9 | not grep GOT -; XFAIL: * @x = weak hidden global i32 0 ; [#uses=1] Added: llvm/trunk/test/CodeGen/X86/hidden-vis-3.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/hidden-vis-3.ll?rev=60571&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/hidden-vis-3.ll (added) +++ llvm/trunk/test/CodeGen/X86/hidden-vis-3.ll Thu Dec 4 19:06:39 2008 @@ -0,0 +1,15 @@ +; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep mov | count 3 +; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep non_lazy_ptr +; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep long | count 2 +; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin9 | not grep GOT + + at x = external hidden global i32 ; [#uses=1] + at y = extern_weak hidden global i32 ; [#uses=1] + +define i32 @t() nounwind readonly { +entry: + %0 = load i32* @x, align 4 ; [#uses=1] + %1 = load i32* @y, align 4 ; [#uses=1] + %2 = add i32 %1, %0 ; [#uses=1] + ret i32 %2 +} Added: llvm/trunk/test/CodeGen/X86/hidden-vis-4.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/hidden-vis-4.ll?rev=60571&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/hidden-vis-4.ll (added) +++ llvm/trunk/test/CodeGen/X86/hidden-vis-4.ll Thu Dec 4 19:06:39 2008 @@ -0,0 +1,11 @@ +; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep non_lazy_ptr +; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep long +; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep comm + + at x = common hidden global i32 0 ; [#uses=1] + +define i32 @t() nounwind readonly { +entry: + %0 = load i32* @x, align 4 ; [#uses=1] + ret i32 %0 +} From gohman at apple.com Thu Dec 4 23:30:02 2008 From: gohman at apple.com (Dan Gohman) Date: Fri, 05 Dec 2008 05:30:02 -0000 Subject: [llvm-commits] [llvm] r60583 - /llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Message-ID: <200812050530.mB55U2sx003751@zion.cs.uiuc.edu> Author: djg Date: Thu Dec 4 23:30:02 2008 New Revision: 60583 URL: http://llvm.org/viewvc/llvm-project?rev=60583&view=rev Log: Ignore IMPLICIT_DEF instructions when computing physreg liveness. While they appear to provide a normal clobbering def, they don't in the case of the awkward IMPLICIT_DEF+INSERT_SUBREG idiom. It would be good to change INSERT_SUBREG; until then, this change allows post-regalloc scheduling to cope in a mildly conservative way. Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=60583&r1=60582&r2=60583&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Thu Dec 4 23:30:02 2008 @@ -353,6 +353,13 @@ I != E; ++I, --Count) { MachineInstr *MI = &*I; + // After regalloc, IMPLICIT_DEF instructions aren't safe to treat as + // dependence-breaking. In the case of an INSERT_SUBREG, the IMPLICIT_DEF + // is left behind appearing to clobber the super-register, while the + // subregister needs to remain live. So we just ignore them. + if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) + continue; + // Check if this instruction has an anti-dependence that we're // interested in. DenseMap::iterator C = CriticalAntiDeps.find(MI); From gohman at apple.com Thu Dec 4 23:31:14 2008 From: gohman at apple.com (Dan Gohman) Date: Fri, 05 Dec 2008 05:31:14 -0000 Subject: [llvm-commits] [llvm] r60584 - /llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Message-ID: <200812050531.mB55VEhi003797@zion.cs.uiuc.edu> Author: djg Date: Thu Dec 4 23:31:14 2008 New Revision: 60584 URL: http://llvm.org/viewvc/llvm-project?rev=60584&view=rev Log: Teach StackSlotColoring to update MachineMemOperands when changing the stack slots on an instruction, to keep them consistent with the actual memory addresses. Modified: llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Modified: llvm/trunk/lib/CodeGen/StackSlotColoring.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackSlotColoring.cpp?rev=60584&r1=60583&r2=60584&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StackSlotColoring.cpp (original) +++ llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Thu Dec 4 23:31:14 2008 @@ -15,6 +15,7 @@ #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/LiveStackAnalysis.h" #include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" @@ -225,10 +226,26 @@ int FI = MO.getIndex(); if (FI < 0) continue; - FI = SlotMapping[FI]; - if (FI == -1) + int NewFI = SlotMapping[FI]; + if (NewFI == -1) continue; - MO.setIndex(FI); + MO.setIndex(NewFI); + + // Update the MachineMemOperand for the new memory location. + // FIXME: We need a better method of managing these too. + SmallVector MMOs(MI.memoperands_begin(), + MI.memoperands_end()); + MI.clearMemOperands(MF); + const Value *OldSV = PseudoSourceValue::getFixedStack(FI); + for (unsigned i = 0, e = MMOs.size(); i != e; ++i) { + if (MMOs[i].getValue() == OldSV) { + MachineMemOperand MMO(PseudoSourceValue::getFixedStack(NewFI), + MMOs[i].getFlags(), MMOs[i].getOffset(), + MMOs[i].getSize(), MMOs[i].getAlignment()); + MI.addMemOperand(MF, MMO); + } else + MI.addMemOperand(MF, MMOs[i]); + } } } } From gohman at apple.com Thu Dec 4 23:35:21 2008 From: gohman at apple.com (Dan Gohman) Date: Fri, 05 Dec 2008 05:35:21 -0000 Subject: [llvm-commits] [llvm] r60585 - /llvm/trunk/include/llvm/Analysis/AliasAnalysis.h Message-ID: <200812050535.mB55ZLPl003916@zion.cs.uiuc.edu> Author: djg Date: Thu Dec 4 23:35:21 2008 New Revision: 60585 URL: http://llvm.org/viewvc/llvm-project?rev=60585&view=rev Log: Update comments. There is no getArgumentAccesses. Modified: llvm/trunk/include/llvm/Analysis/AliasAnalysis.h Modified: llvm/trunk/include/llvm/Analysis/AliasAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/AliasAnalysis.h?rev=60585&r1=60584&r2=60585&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/AliasAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/AliasAnalysis.h Thu Dec 4 23:35:21 2008 @@ -129,16 +129,16 @@ // AccessesArguments - This function accesses function arguments in // non-volatile and well known ways, but does not access any other memory. // - // Clients may call getArgumentAccesses to get specific information about - // how pointer arguments are used. + // Clients may use the Info parameter of getModRefBehavior to get specific + // information about how pointer arguments are used. AccessesArguments, // AccessesArgumentsAndGlobals - This function has accesses function // arguments and global variables in non-volatile and well-known ways, but // does not access any other memory. // - // Clients may call getArgumentAccesses to get specific information about - // how pointer arguments and globals are used. + // Clients may use the Info parameter of getModRefBehavior to get specific + // information about how pointer arguments are used. AccessesArgumentsAndGlobals, // OnlyReadsMemory - This function does not perform any non-local stores or From gohman at apple.com Thu Dec 4 23:45:43 2008 From: gohman at apple.com (Dan Gohman) Date: Fri, 05 Dec 2008 05:45:43 -0000 Subject: [llvm-commits] [llvm] r60586 - in /llvm/trunk: include/llvm/CodeGen/MachineInstr.h lib/CodeGen/LiveIntervalAnalysis.cpp lib/CodeGen/MachineInstr.cpp lib/CodeGen/PostRASchedulerList.cpp lib/CodeGen/RegAllocLocal.cpp Message-ID: <200812050545.mB55jhbf004206@zion.cs.uiuc.edu> Author: djg Date: Thu Dec 4 23:45:42 2008 New Revision: 60586 URL: http://llvm.org/viewvc/llvm-project?rev=60586&view=rev Log: Drop the reg argument to isRegReDefinedByTwoAddr, which was redundant. Modified: llvm/trunk/include/llvm/CodeGen/MachineInstr.h llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp llvm/trunk/lib/CodeGen/MachineInstr.cpp llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp llvm/trunk/lib/CodeGen/RegAllocLocal.cpp Modified: llvm/trunk/include/llvm/CodeGen/MachineInstr.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineInstr.h?rev=60586&r1=60585&r2=60586&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineInstr.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineInstr.h Thu Dec 4 23:45:42 2008 @@ -219,9 +219,9 @@ /// none is found. int findFirstPredOperandIdx() const; - /// isRegReDefinedByTwoAddr - Given the defined register and the operand index, + /// isRegReDefinedByTwoAddr - Given the index of a register def operand, /// check if the register def is a re-definition due to two addr elimination. - bool isRegReDefinedByTwoAddr(unsigned Reg, unsigned DefIdx) const; + bool isRegReDefinedByTwoAddr(unsigned DefIdx) const; /// copyKillDeadInfo - Copies kill / dead operand properties from MI. /// Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=60586&r1=60585&r2=60586&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Thu Dec 4 23:45:42 2008 @@ -426,7 +426,7 @@ // must be due to phi elimination or two addr elimination. If this is // the result of two address elimination, then the vreg is one of the // def-and-use register operand. - if (mi->isRegReDefinedByTwoAddr(interval.reg, MOIdx)) { + if (mi->isRegReDefinedByTwoAddr(MOIdx)) { // If this is a two-address definition, then we have already processed // the live range. The only problem is that we didn't realize there // are actually two values in the live interval. Because of this we Modified: llvm/trunk/lib/CodeGen/MachineInstr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineInstr.cpp?rev=60586&r1=60585&r2=60586&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineInstr.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineInstr.cpp Thu Dec 4 23:45:42 2008 @@ -646,13 +646,14 @@ return -1; } -/// isRegReDefinedByTwoAddr - Given the defined register and the operand index, +/// isRegReDefinedByTwoAddr - Given the index of a register def operand, /// check if the register def is a re-definition due to two addr elimination. -bool MachineInstr::isRegReDefinedByTwoAddr(unsigned Reg, unsigned DefIdx) const{ +bool MachineInstr::isRegReDefinedByTwoAddr(unsigned DefIdx) const{ + assert(getOperand(DefIdx).isDef() && "DefIdx is not a def!"); const TargetInstrDesc &TID = getDesc(); for (unsigned i = 0, e = TID.getNumOperands(); i != e; ++i) { const MachineOperand &MO = getOperand(i); - if (MO.isReg() && MO.isUse() && MO.getReg() == Reg && + if (MO.isReg() && MO.isUse() && TID.getOperandConstraint(i, TOI::TIED_TO) == (int)DefIdx) return true; } Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=60586&r1=60585&r2=60586&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Thu Dec 4 23:45:42 2008 @@ -478,7 +478,7 @@ if (Reg == 0) continue; if (!MO.isDef()) continue; // Ignore two-addr defs. - if (MI->isRegReDefinedByTwoAddr(Reg, i)) continue; + if (MI->isRegReDefinedByTwoAddr(i)) continue; DefIndices[Reg] = Count; KillIndices[Reg] = -1; Modified: llvm/trunk/lib/CodeGen/RegAllocLocal.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocLocal.cpp?rev=60586&r1=60585&r2=60586&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocLocal.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocLocal.cpp Thu Dec 4 23:45:42 2008 @@ -609,7 +609,7 @@ // Check if this is a two address instruction. If so, then // the def does not kill the use. if (last->second.first == I && - I->isRegReDefinedByTwoAddr(MO.getReg(), i)) + I->isRegReDefinedByTwoAddr(i)) continue; MachineOperand& lastUD = From sabre at nondot.org Fri Dec 5 01:11:06 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 05 Dec 2008 07:11:06 -0000 Subject: [llvm-commits] [llvm] r60587 - /llvm/trunk/include/llvm/ADT/SmallVector.h Message-ID: <200812050711.mB57B6KA006804@zion.cs.uiuc.edu> Author: lattner Date: Fri Dec 5 01:11:05 2008 New Revision: 60587 URL: http://llvm.org/viewvc/llvm-project?rev=60587&view=rev Log: add a new pop_back_val method which returns the value popped. This is heretical from a STL standpoint, but is oh-so-useful for things that can't throw exceptions when copied, like, well, everything in LLVM. Modified: llvm/trunk/include/llvm/ADT/SmallVector.h Modified: llvm/trunk/include/llvm/ADT/SmallVector.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/SmallVector.h?rev=60587&r1=60586&r2=60587&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/SmallVector.h (original) +++ llvm/trunk/include/llvm/ADT/SmallVector.h Fri Dec 5 01:11:05 2008 @@ -162,6 +162,12 @@ End->~T(); } + T pop_back_val() { + T Result = back(); + pop_back(); + return Result; + } + void clear() { destroy_range(Begin, End); End = Begin; From sabre at nondot.org Fri Dec 5 01:49:08 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 05 Dec 2008 07:49:08 -0000 Subject: [llvm-commits] [llvm] r60588 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp Message-ID: <200812050749.mB57n8DB007969@zion.cs.uiuc.edu> Author: lattner Date: Fri Dec 5 01:49:08 2008 New Revision: 60588 URL: http://llvm.org/viewvc/llvm-project?rev=60588&view=rev Log: Make IsValueFullyAvailableInBlock safe. Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=60588&r1=60587&r2=60588&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Fri Dec 5 01:49:08 2008 @@ -1,4 +1,4 @@ -//===- GVN.cpp - Eliminate redundant values and loads ------------===// +//===- GVN.cpp - Eliminate redundant values and loads ---------------------===// // // The LLVM Compiler Infrastructure // @@ -47,7 +47,7 @@ static cl::opt EnablePRE("enable-pre", cl::init(true), cl::Hidden); -cl::opt EnableLoadPRE("enable-load-pre"); +cl::opt EnableLoadPRE("enable-load-pre"/*, cl::init(true)*/); //===----------------------------------------------------------------------===// // ValueTable Class @@ -867,34 +867,79 @@ /// IsValueFullyAvailableInBlock - Return true if we can prove that the value /// we're analyzing is fully available in the specified block. As we go, keep -/// track of which blocks we know it is fully alive or not in -/// FullyAvailableBlocks. +/// track of which blocks we know are fully alive in FullyAvailableBlocks. This +/// map is actually a tri-state map with the following values: +/// 0) we know the block *is not* fully available. +/// 1) we know the block *is* fully available. +/// 2) we do not know whether the block is fully available or not, but we are +/// currently speculating that it will be. +/// 3) we are speculating for this block and have used that to speculate for +/// other blocks. static bool IsValueFullyAvailableInBlock(BasicBlock *BB, - DenseMap &FullyAvailableBlocks) { + DenseMap &FullyAvailableBlocks) { // Optimistically assume that the block is fully available and check to see // if we already know about this block in one lookup. - std::pair::iterator, bool> IV = - FullyAvailableBlocks.insert(std::make_pair(BB, true)); + std::pair::iterator, char> IV = + FullyAvailableBlocks.insert(std::make_pair(BB, 2)); // If the entry already existed for this block, return the precomputed value. - if (!IV.second) - return IV.first->second; + if (!IV.second) { + // If this is a speculative "available" value, mark it as being used for + // speculation of other blocks. + if (IV.first->second == 2) + IV.first->second = 3; + return IV.first->second != 0; + } // Otherwise, see if it is fully available in all predecessors. pred_iterator PI = pred_begin(BB), PE = pred_end(BB); // If this block has no predecessors, it isn't live-in here. if (PI == PE) - return FullyAvailableBlocks[BB] = false; + goto SpeculationFailure; for (; PI != PE; ++PI) // If the value isn't fully available in one of our predecessors, then it // isn't fully available in this block either. Undo our previous // optimistic assumption and bail out. if (!IsValueFullyAvailableInBlock(*PI, FullyAvailableBlocks)) - return FullyAvailableBlocks[BB] = false; + goto SpeculationFailure; return true; + +// SpeculationFailure - If we get here, we found out that this is not, after +// all, a fully-available block. We have a problem if we speculated on this and +// used the speculation to mark other blocks as available. +SpeculationFailure: + char &BBVal = FullyAvailableBlocks[BB]; + + // If we didn't speculate on this, just return with it set to false. + if (BBVal == 2) { + BBVal = 0; + return false; + } + + // If we did speculate on this value, we could have blocks set to 1 that are + // incorrect. Walk the (transitive) successors of this block and mark them as + // 0 if set to one. + SmallVector BBWorklist; + BBWorklist.push_back(BB); + + while (!BBWorklist.empty()) { + BasicBlock *Entry = BBWorklist.pop_back_val(); + // Note that this sets blocks to 0 (unavailable) if they happen to not + // already be in FullyAvailableBlocks. This is safe. + char &EntryVal = FullyAvailableBlocks[Entry]; + if (EntryVal == 0) continue; // Already unavailable. + + // Mark as unavailable. + EntryVal = 0; + + for (succ_iterator I = succ_begin(Entry), E = succ_end(Entry); I != E; ++I) + BBWorklist.push_back(*I); + } + + return false; } /// processNonLocalLoad - Attempt to eliminate a load whose dependencies are @@ -1047,7 +1092,7 @@ // that one block. BasicBlock *UnavailablePred = 0; - DenseMap FullyAvailableBlocks; + DenseMap FullyAvailableBlocks; for (unsigned i = 0, e = ValuesPerBlock.size(); i != e; ++i) FullyAvailableBlocks[ValuesPerBlock[i].first] = true; for (unsigned i = 0, e = UnavailableBlocks.size(); i != e; ++i) @@ -1086,11 +1131,11 @@ << UnavailablePred->getName() << "': " << *LI); return false; } - + // Okay, we can eliminate this load by inserting a reload in the predecessor // and using PHI construction to get the value in the other predecessors, do // it. - DEBUG(cerr << "GVN REMOVING PRE LOAD: " << *LI); + /*DEBUG*/(cerr << "GVN REMOVING PRE LOAD: " << *LI); Value *NewLoad = new LoadInst(LoadPtr, LI->getName()+".pre", false, LI->getAlignment(), @@ -1103,6 +1148,7 @@ // Perform PHI construction. Value* v = GetValueForBlock(LI->getParent(), LI, BlockReplValues, true); LI->replaceAllUsesWith(v); + v->takeName(LI); toErase.push_back(LI); NumPRELoad++; return true; From baldrick at free.fr Fri Dec 5 01:50:57 2008 From: baldrick at free.fr (Duncan Sands) Date: Fri, 5 Dec 2008 08:50:57 +0100 Subject: [llvm-commits] [llvm] r60554 - in /llvm/trunk: lib/Transforms/Scalar/LoopIndexSplit.cpp test/Transforms/LoopIndexSplit/2007-09-24-UpdateIterationSpace.ll test/Transforms/LoopIndexSplit/2007-09-25-UpdateIterationSpace-2.ll test/Transforms/LoopIndexSplit/2008-10-10-OneIteration.ll test/Transforms/LoopIndexSplit/OneIterLoop-2007-08-17.ll test/Transforms/LoopIndexSplit/OneIterLoop2-2007-08-17.ll In-Reply-To: <200812042138.mB4LchmP021296@zion.cs.uiuc.edu> References: <200812042138.mB4LchmP021296@zion.cs.uiuc.edu> Message-ID: <200812050850.57904.baldrick@free.fr> Hi Devang, > +// is trnasformed to iterators from A to B, if A > 0 and B < N. trnasformed -> transformed Occurs again below. > + /// IVisLT - If Op is comparing IV based value with an loop invaraint and invaraint -> invariant More of these elsewhere. Ciao, Duncan. From echeng at apple.com Fri Dec 5 02:13:15 2008 From: echeng at apple.com (Evan Cheng) Date: Fri, 5 Dec 2008 00:13:15 -0800 Subject: [llvm-commits] [llvm] r60519 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp lib/Target/PowerPC/PPCSubtarget.cpp lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp lib/Target/X86/X86Subtarget.cpp test/CodeGen/X86/hidden-vis-2.ll In-Reply-To: <1C01C792-5B21-4E8C-8941-0B55E7EDE55A@apple.com> References: <200812040156.mB41up9h008099@zion.cs.uiuc.edu> <1C01C792-5B21-4E8C-8941-0B55E7EDE55A@apple.com> Message-ID: <75AE7ED4-1412-4043-A312-C18EFD91AB58@apple.com> No. This is a Darwin specific patch that deals with non-lazy-ptr. llvm does not generate a stub for linkonce hidden function. This behavior differs from gcc. I am not sure who is right. Evan On Dec 3, 2008, at 8:02 PM, Chris Lattner wrote: > > On Dec 3, 2008, at 5:56 PM, Evan Cheng wrote: > >> Author: evancheng >> Date: Wed Dec 3 19:56:50 2008 >> New Revision: 60519 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=60519&view=rev >> Log: >> Visibility hidden GVs do not require extra load of symbol address >> from the GOT or non-lazy-ptr. > > Nifty, does this fix: > http://llvm.org/bugs/show_bug.cgi?id=3148 > > ? > > -Chris > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From echeng at apple.com Fri Dec 5 02:13:19 2008 From: echeng at apple.com (Evan Cheng) Date: Fri, 5 Dec 2008 00:13:19 -0800 Subject: [llvm-commits] [llvm] r60519 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp lib/Target/PowerPC/PPCSubtarget.cpp lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp lib/Target/X86/X86Subtarget.cpp test/CodeGen/X86/hidden-vis-2.ll In-Reply-To: <49378295.8060803@mxc.ca> References: <200812040156.mB41up9h008099@zion.cs.uiuc.edu> <49378295.8060803@mxc.ca> Message-ID: <95EB29AB-020D-4AFD-AB12-553B4B089DAF@apple.com> On Dec 3, 2008, at 11:11 PM, Nick Lewycky wrote: > Evan Cheng wrote: >> Author: evancheng >> Date: Wed Dec 3 19:56:50 2008 >> New Revision: 60519 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=60519&view=rev >> Log: >> Visibility hidden GVs do not require extra load of symbol address >> from the GOT or non-lazy-ptr. > > Thanks! > > You missed that the same optimization applies to protected symbols as > well, probably because Darwin doesn't have them. Please update PR3148. Right. Darwin doesn't have protected visibility. > > Does this fix the issue on Linux as well? No. I don't feel comfortable changing Linux subtarget. Evan > > > Nick > >> Added: >> llvm/trunk/test/CodeGen/X86/hidden-vis-2.ll >> Modified: >> llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp >> llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp >> llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp >> llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp >> llvm/trunk/lib/Target/X86/X86Subtarget.cpp >> >> Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=60519&r1=60518&r2=60519&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) >> +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Wed Dec 3 >> 19:56:50 2008 >> @@ -830,7 +830,7 @@ >> /// GVIsIndirectSymbol - true if the GV will be accessed via an >> indirect symbol >> /// even in non-static mode. >> static bool GVIsIndirectSymbol(GlobalValue *GV, Reloc::Model >> RelocM) { >> - return RelocM != Reloc::Static && >> + return RelocM != Reloc::Static && !GV->hasHiddenVisibility() && >> (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || >> (GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode())); >> } >> >> Modified: llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp?rev=60519&r1=60518&r2=60519&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp >> (original) >> +++ llvm/trunk/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp Wed >> Dec 3 19:56:50 2008 >> @@ -387,8 +387,9 @@ >> >> // External or weakly linked global variables need non-lazily- >> resolved stubs >> if (TM.getRelocationModel() != Reloc::Static) { >> - if (((GV->isDeclaration() || GV->hasWeakLinkage() || >> - GV->hasLinkOnceLinkage() || GV->hasCommonLinkage()))) { >> + if (!GV->hasHiddenVisibility() && >> + (GV->isDeclaration() || GV->hasWeakLinkage() || >> + GV->hasLinkOnceLinkage() || GV->hasCommonLinkage())) { >> GVStubs.insert(Name); >> printSuffixedName(Name, "$non_lazy_ptr"); >> if (GV->hasExternalWeakLinkage()) >> >> Modified: llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp?rev=60519&r1=60518&r2=60519&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp (original) >> +++ llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp Wed Dec 3 >> 19:56:50 2008 >> @@ -141,7 +141,9 @@ >> // We never hae stubs if HasLazyResolverStubs=false or if in >> static mode. >> if (!HasLazyResolverStubs || TM.getRelocationModel() == >> Reloc::Static) >> return false; >> - >> + // Extra load is not needed for symbols with hidden visibility. >> + if (GV->hasHiddenVisibility()) >> + return false; >> return GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || >> GV->hasCommonLinkage() || >> (GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode()); >> >> Modified: llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp?rev=60519&r1=60518&r2=60519&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp >> (original) >> +++ llvm/trunk/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp Wed >> Dec 3 19:56:50 2008 >> @@ -391,6 +391,8 @@ >> FnStubs.insert(Name); >> printSuffixedName(Name, "$stub"); >> } >> + } else if (GV->hasHiddenVisibility()) { >> + O << Name; >> } else { >> GVStubs.insert(Name); >> printSuffixedName(Name, "$non_lazy_ptr"); >> >> Modified: llvm/trunk/lib/Target/X86/X86Subtarget.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.cpp?rev=60519&r1=60518&r2=60519&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/lib/Target/X86/X86Subtarget.cpp (original) >> +++ llvm/trunk/lib/Target/X86/X86Subtarget.cpp Wed Dec 3 19:56:50 >> 2008 >> @@ -40,6 +40,9 @@ >> if (TM.getRelocationModel() != Reloc::Static && >> TM.getCodeModel() != CodeModel::Large) { >> if (isTargetDarwin()) { >> + if (GV->hasHiddenVisibility()) >> + // Extra load is not needed for symbols with hidden >> visibility. >> + return false; >> return (!isDirectCall && >> (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || >> GV->hasCommonLinkage() || >> >> Added: llvm/trunk/test/CodeGen/X86/hidden-vis-2.ll >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/hidden-vis-2.ll?rev=60519&view=auto >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- llvm/trunk/test/CodeGen/X86/hidden-vis-2.ll (added) >> +++ llvm/trunk/test/CodeGen/X86/hidden-vis-2.ll Wed Dec 3 19:56:50 >> 2008 >> @@ -0,0 +1,10 @@ >> +; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep mov >> | count 1 >> +; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin9 | not grep >> GOT >> + >> + at x = weak hidden global i32 0 ; [#uses=1] >> + >> +define i32 @t() nounwind readonly { >> +entry: >> + %0 = load i32* @x, align 4 ; [#uses=1] >> + ret i32 %0 >> +} >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From echeng at apple.com Fri Dec 5 02:16:29 2008 From: echeng at apple.com (Evan Cheng) Date: Fri, 5 Dec 2008 00:16:29 -0800 Subject: [llvm-commits] [llvm] r60519 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp lib/Target/PowerPC/PPCSubtarget.cpp lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp lib/Target/X86/X86Subtarget.cpp test/CodeGen/X86/hidden-vis-2.ll In-Reply-To: <75AE7ED4-1412-4043-A312-C18EFD91AB58@apple.com> References: <200812040156.mB41up9h008099@zion.cs.uiuc.edu> <1C01C792-5B21-4E8C-8941-0B55E7EDE55A@apple.com> <75AE7ED4-1412-4043-A312-C18EFD91AB58@apple.com> Message-ID: No I remember. For 10.5 and up function stubs are no longer needed. They are automatically synthesized by dyld. Evan On Dec 5, 2008, at 12:13 AM, Evan Cheng wrote: > No. This is a Darwin specific patch that deals with non-lazy-ptr. llvm > does not generate a stub for linkonce hidden function. This behavior > differs from gcc. I am not sure who is right. > > Evan > > On Dec 3, 2008, at 8:02 PM, Chris Lattner wrote: > >> >> On Dec 3, 2008, at 5:56 PM, Evan Cheng wrote: >> >>> Author: evancheng >>> Date: Wed Dec 3 19:56:50 2008 >>> New Revision: 60519 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=60519&view=rev >>> Log: >>> Visibility hidden GVs do not require extra load of symbol address >>> from the GOT or non-lazy-ptr. >> >> Nifty, does this fix: >> http://llvm.org/bugs/show_bug.cgi?id=3148 >> >> ? >> >> -Chris >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From rafael.espindola at gmail.com Fri Dec 5 05:41:28 2008 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Fri, 05 Dec 2008 11:41:28 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60589 - in /llvm-gcc-4.2/trunk/gcc: c-common.c c-common.h c.opt config/i386/darwin.h config/rs6000/darwin.h Message-ID: <200812051141.mB5BfWsG025294@zion.cs.uiuc.edu> Author: rafael Date: Fri Dec 5 05:41:15 2008 New Revision: 60589 URL: http://llvm.org/viewvc/llvm-project?rev=60589&view=rev Log: Fix bug 2843. -Wformat-security is the default for darwin but not linux. Modified: llvm-gcc-4.2/trunk/gcc/c-common.c llvm-gcc-4.2/trunk/gcc/c-common.h llvm-gcc-4.2/trunk/gcc/c.opt llvm-gcc-4.2/trunk/gcc/config/i386/darwin.h llvm-gcc-4.2/trunk/gcc/config/rs6000/darwin.h Modified: llvm-gcc-4.2/trunk/gcc/c-common.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/c-common.c?rev=60589&r1=60588&r2=60589&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/c-common.c (original) +++ llvm-gcc-4.2/trunk/gcc/c-common.c Fri Dec 5 05:41:15 2008 @@ -294,12 +294,6 @@ int warn_unknown_pragmas; /* Tri state variable. */ -/* Warn about format/argument anomalies in calls to formatted I/O functions - (*printf, *scanf, strftime, strfmon, etc.). */ - -/* APPLE LOCAL default to Wformat-security 5764921 */ -int warn_format = 1; - /* Warn about using __null (as NULL in C++) as sentinel. For code compiled with GCC this doesn't matter as __null is guaranteed to have the right size. */ Modified: llvm-gcc-4.2/trunk/gcc/c-common.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/c-common.h?rev=60589&r1=60588&r2=60589&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/c-common.h (original) +++ llvm-gcc-4.2/trunk/gcc/c-common.h Fri Dec 5 05:41:15 2008 @@ -461,11 +461,6 @@ extern int warn_unknown_pragmas; /* Tri state variable. */ -/* Warn about format/argument anomalies in calls to formatted I/O functions - (*printf, *scanf, strftime, strfmon, etc.). */ - -extern int warn_format; - /* APPLE LOCAL begin disable_typechecking_for_spec_flag */ /* This makes type conflicts a warning, instead of an error, to work around some problems with SPEC. */ Modified: llvm-gcc-4.2/trunk/gcc/c.opt URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/c.opt?rev=60589&r1=60588&r2=60589&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/c.opt (original) +++ llvm-gcc-4.2/trunk/gcc/c.opt Fri Dec 5 05:41:15 2008 @@ -225,8 +225,8 @@ Warn if testing floating point numbers for equality Wformat -C ObjC C++ ObjC++ -Warn about printf/scanf/strftime/strfmon format string anomalies +C ObjC C++ ObjC++ Var(warn_format) Warning +Warn about format strings Wformat-extra-args C ObjC C++ ObjC++ Var(warn_format_extra_args) @@ -236,11 +236,9 @@ C ObjC C++ ObjC++ Var(warn_format_nonliteral) Warn about format strings that are not literals -; APPLE LOCAL begin default to Wformat-security 5764921 Wformat-security -C ObjC C++ ObjC++ Var(warn_format_security) Init(1) +C ObjC C++ ObjC++ Var(warn_format_security) Warn about possible security problems with format functions -; APPLE LOCAL end default to Wformat-security 5764921 Wformat-y2k C ObjC C++ ObjC++ Var(warn_format_y2k) Modified: llvm-gcc-4.2/trunk/gcc/config/i386/darwin.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/darwin.h?rev=60589&r1=60588&r2=60589&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/i386/darwin.h (original) +++ llvm-gcc-4.2/trunk/gcc/config/i386/darwin.h Fri Dec 5 05:41:15 2008 @@ -101,6 +101,9 @@ %{!mmacosx-version-min=*: %{!miphoneos-version-min=*: %(darwin_cc1_minversion)}} \ "/* APPLE LOCAL ignore -mcpu=G4 -mcpu=G5 */"\ % Author: venet Date: Fri Dec 5 07:37:30 2008 New Revision: 60590 URL: http://llvm.org/viewvc/llvm-project?rev=60590&view=rev Log: The use of the construct: for(Type1 B = ...;;) { Type2 B ; ... } is bad: code is hard to read and VS VS don't like it (it ignore the second declaration of B). This patch fix the problem in tablegen. Please don't write code like this. Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=60590&r1=60589&r2=60590&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Fri Dec 5 07:37:30 2008 @@ -1548,9 +1548,9 @@ StringMap::iterator IAE = ToolToOutLang.end(); StringMap >::iterator IBE = ToolToInLang.end(); - for (RecordVector::const_iterator B = EdgeVector.begin(), - E = EdgeVector.end(); B != E; ++B) { - const Record* Edge = *B; + for (RecordVector::const_iterator Beg = EdgeVector.begin(), + E = EdgeVector.end(); Beg != E; ++Beg) { + const Record* Edge = *Beg; const std::string& A = Edge->getValueAsString("a"); const std::string& B = Edge->getValueAsString("b"); StringMap::iterator IA = ToolToOutLang.find(A); @@ -1615,9 +1615,9 @@ const GlobalOptionDescriptions& OptDescs, std::ostream& O) { int i = 0; - for (RecordVector::const_iterator B = EdgeVector.begin(), - E = EdgeVector.end(); B != E; ++B) { - const Record* Edge = *B; + for (RecordVector::const_iterator Beg = EdgeVector.begin(), + E = EdgeVector.end(); Beg != E; ++Beg) { + const Record* Edge = *Beg; const std::string& B = Edge->getValueAsString("b"); DagInit* Weight = Edge->getValueAsDag("weight"); @@ -1645,9 +1645,9 @@ // Insert edges. int i = 0; - for (RecordVector::const_iterator B = EdgeVector.begin(), - E = EdgeVector.end(); B != E; ++B) { - const Record* Edge = *B; + for (RecordVector::const_iterator Beg = EdgeVector.begin(), + E = EdgeVector.end(); Beg != E; ++Beg) { + const Record* Edge = *Beg; const std::string& A = Edge->getValueAsString("a"); const std::string& B = Edge->getValueAsString("b"); DagInit* Weight = Edge->getValueAsDag("weight"); @@ -1800,10 +1800,10 @@ // List all tools mentioned in the graph. llvm::StringSet<> ToolsInGraph; - for (RecordVector::const_iterator B = EdgeVector.begin(), - E = EdgeVector.end(); B != E; ++B) { + for (RecordVector::const_iterator Beg = EdgeVector.begin(), + E = EdgeVector.end(); Beg != E; ++Beg) { - const Record* Edge = *B; + const Record* Edge = *Beg; const std::string& A = Edge->getValueAsString("a"); const std::string& B = Edge->getValueAsString("b"); From evan.cheng at apple.com Fri Dec 5 11:00:25 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 05 Dec 2008 17:00:25 -0000 Subject: [llvm-commits] [llvm] r60592 - /llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <200812051700.mB5H0QM0002859@zion.cs.uiuc.edu> Author: evancheng Date: Fri Dec 5 11:00:16 2008 New Revision: 60592 URL: http://llvm.org/viewvc/llvm-project?rev=60592&view=rev Log: Fix comment. Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=60592&r1=60591&r2=60592&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Fri Dec 5 11:00:16 2008 @@ -1800,7 +1800,7 @@ // Spill slot weight. SSWeight = 0.0f; - // Each bit specify whether it a spill is required in the MBB. + // Each bit specify whether a spill is required in the MBB. BitVector SpillMBBs(mf_->getNumBlockIDs()); DenseMap > SpillIdxes; BitVector RestoreMBBs(mf_->getNumBlockIDs()); From sabre at nondot.org Fri Dec 5 11:04:13 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 05 Dec 2008 17:04:13 -0000 Subject: [llvm-commits] [llvm] r60594 - in /llvm/trunk: lib/Transforms/Scalar/GVN.cpp test/Transforms/GVN/pre-load.ll Message-ID: <200812051704.mB5H4DXS003077@zion.cs.uiuc.edu> Author: lattner Date: Fri Dec 5 11:04:12 2008 New Revision: 60594 URL: http://llvm.org/viewvc/llvm-project?rev=60594&view=rev Log: Fix test/Transforms/GVN/pre-load.ll Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp llvm/trunk/test/Transforms/GVN/pre-load.ll Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=60594&r1=60593&r2=60594&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Fri Dec 5 11:04:12 2008 @@ -1135,7 +1135,7 @@ // Okay, we can eliminate this load by inserting a reload in the predecessor // and using PHI construction to get the value in the other predecessors, do // it. - /*DEBUG*/(cerr << "GVN REMOVING PRE LOAD: " << *LI); + DEBUG(cerr << "GVN REMOVING PRE LOAD: " << *LI); Value *NewLoad = new LoadInst(LoadPtr, LI->getName()+".pre", false, LI->getAlignment(), Modified: llvm/trunk/test/Transforms/GVN/pre-load.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/pre-load.ll?rev=60594&r1=60593&r2=60594&view=diff ============================================================================== --- llvm/trunk/test/Transforms/GVN/pre-load.ll (original) +++ llvm/trunk/test/Transforms/GVN/pre-load.ll Fri Dec 5 11:04:12 2008 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | opt -gvn -enable-load-pre | llvm-dis | grep {%PRE.rle = phi} +; RUN: llvm-as < %s | opt -gvn -enable-load-pre | llvm-dis | grep {%PRE = phi} define i32 @test(i32* %p, i1 %C) { block1: From evan.cheng at apple.com Fri Dec 5 11:23:50 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 05 Dec 2008 17:23:50 -0000 Subject: [llvm-commits] [llvm] r60595 - in /llvm/trunk: lib/Target/X86/X86InstrInfo.cpp test/CodeGen/X86/2008-12-05-SpillerCrash.ll Message-ID: <200812051723.mB5HNo5N003637@zion.cs.uiuc.edu> Author: evancheng Date: Fri Dec 5 11:23:48 2008 New Revision: 60595 URL: http://llvm.org/viewvc/llvm-project?rev=60595&view=rev Log: Effectively undo 60461 in PIC mode which simply transform V_SET0 / V_SETALLONES into a load from constpool in order to fold into restores. This is not safe to do when PIC base is being used for a number of reasons: 1. GlobalBaseReg may have been spilled. 2. It may not be live at the use. 3. Spiller doesn't know this is happening so it won't prevent GlobalBaseReg from being spilled later (That by itself is a nasty hack. It's needed because we don't insert the reload until later). Added: llvm/trunk/test/CodeGen/X86/2008-12-05-SpillerCrash.ll Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=60595&r1=60594&r2=60595&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Fri Dec 5 11:23:48 2008 @@ -2137,7 +2137,13 @@ unsigned PICBase = 0; if (TM.getRelocationModel() == Reloc::PIC_ && !TM.getSubtarget().is64Bit()) - PICBase = TM.getInstrInfo()->getGlobalBaseReg(&MF); + // FIXME: PICBase = TM.getInstrInfo()->getGlobalBaseReg(&MF); + // This doesn't work for several reasons. + // 1. GlobalBaseReg may have been spilled. + // 2. It may not be live at MI. + // 3. If this is used during register allocation / spilling, the spiller + // must know not to spill GlobalBaseReg (which is a temporary nasty hack). + return false; // Create a v4i32 constant-pool entry. MachineConstantPool &MCP = *MF.getConstantPool(); Added: llvm/trunk/test/CodeGen/X86/2008-12-05-SpillerCrash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2008-12-05-SpillerCrash.ll?rev=60595&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2008-12-05-SpillerCrash.ll (added) +++ llvm/trunk/test/CodeGen/X86/2008-12-05-SpillerCrash.ll Fri Dec 5 11:23:48 2008 @@ -0,0 +1,237 @@ +; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9.5 -relocation-model=pic + + %struct.XXActiveTextureTargets = type { i64, i64, i64, i64, i64, i64 } + %struct.XXAlphaTest = type { float, i16, i8, i8 } + %struct.XXArrayRange = type { i8, i8, i8, i8 } + %struct.XXBlendMode = type { i16, i16, i16, i16, %struct.ZZIColor4, i16, i16, i8, i8, i8, i8 } + %struct.XXBBRec = type opaque + %struct.XXBBstate = type { %struct.ZZGTransformKey, %struct.ZZGTransformKey, %struct.XXProgramLimits, %struct.XXProgramLimits, i8, i8, i8, i8, %struct.ZZSBB, %struct.ZZSBB, [4 x %struct.ZZSBB], %struct.ZZSBB, %struct.ZZSBB, %struct.ZZSBB, [8 x %struct.ZZSBB], %struct.ZZSBB } + %struct.XXClearColor = type { double, %struct.ZZIColor4, %struct.ZZIColor4, float, i32 } + %struct.XXClipPlane = type { i32, [6 x %struct.ZZIColor4] } + %struct.XXColorBB = type { i16, i8, i8, [8 x i16], i8, i8, i8, i8 } + %struct.XXColorMatrix = type { [16 x float]*, %struct.XXImagingColorScale } + %struct.XXConfig = type { i32, float, %struct.ZZGTransformKey, %struct.ZZGTransformKey, i8, i8, i8, i8, i8, i8, i16, i32, i32, i32, %struct.XXPixelFormatInfo, %struct.XXPointLineLimits, %struct.XXPointLineLimits, %struct.XXRenderFeatures, i32, i32, i32, i32, i32, i32, i32, i32, i32, %struct.XXTextureLimits, [3 x %struct.XXPipelineProgramLimits], %struct.XXFragmentProgramLimits, %struct.XXVertexProgramLimits, %struct.XXGeometryShaderLimits, %struct.XXProgramLimits, %struct.XXGeometryShaderLimits, %struct.XXVertexDescriptor*, %struct.XXVertexDescriptor*, [3 x i32], [4 x i32], [0 x i32] } + %struct.XXContextRec = type { float, float, float, float, float, float, float, float, %struct.ZZIColor4, %struct.ZZIColor4, %struct.YYFPContext, [16 x [2 x %struct.PPStreamToken]], %struct.ZZGProcessor, %struct._YYConstants*, void (%struct.XXContextRec*, i32, i32, %struct.YYFragmentAttrib*, %struct.YYFragmentAttrib*, i32)*, %struct._YYFunction*, %struct.PPStreamToken*, void (%struct.XXContextRec*, %struct.XXVertex*)*, void (%struct.XXContextRec*, %struct.XXVertex*, %struct.XXVertex*)*, void (%struct.XXContextRec*, %struct.XXVertex*, %struct.XXVertex*, %struct.XXVertex*)*, %struct._YYFunction*, %struct._YYFunction*, %struct._YYFunction*, [4 x i32], [3 x i32], [3 x i32], float, float, float, %struct.PPStreamToken, i32, %struct.ZZSDrawable, %struct.XXFramebufferRec*, %struct.XXFramebufferRec*, %struct.XXRect, %struct.XXFormat, %struct.XXFormat, %struct.XXFormat, %struct.XXConfig*, %struct.XXBBstate, %struct.XXBBstate, %struct.XXSharedRec*, %struct.XXState*, %struct.XXPluginSt! ate*, %struct.XXVertex*, %struct.YYFragmentAttrib*, %struct.YYFragmentAttrib*, %struct.YYFragmentAttrib*, %struct.XXProgramRec*, %struct.XXPipelineProgramRec*, %struct.YYTextures, %struct.XXStippleData, i8, i16, i8, i32, i32, i32, %struct.XXQueryRec*, %struct.XXQueryRec*, %struct.XXFallback, { void (i8*, i8*, i32, i8*)* } } + %struct.XXConvolution = type { %struct.ZZIColor4, %struct.XXImagingColorScale, i16, i16, [0 x i32], float*, i32, i32 } + %struct.XXCurrent16A = type { [8 x %struct.ZZIColor4], [16 x %struct.ZZIColor4], %struct.ZZIColor4, %struct.XXPointLineLimits, float, %struct.XXPointLineLimits, float, [4 x float], %struct.XXPointLineLimits, float, float, float, float, i8, i8, i8, i8 } + %struct.XXDepthTest = type { i16, i16, i8, i8, i8, i8, double, double } + %struct.XXDrawableWindow = type { i32, i32, i32 } + %struct.XXFallback = type { float*, %struct.XXRenderDispatch*, %struct.XXConfig*, i8*, i8*, i32, i32 } + %struct.XXFenceRec = type opaque + %struct.XXFixedFunction = type { %struct.PPStreamToken* } + %struct.XXFogMode = type { %struct.ZZIColor4, float, float, float, float, float, i16, i16, i16, i8, i8 } + %struct.XXFormat = type { i32, i32, i32, i32, i32, i32, i32, i32, i8, i8, i8, i8, i32, i32, i32 } + %struct.XXFragmentProgramLimits = type { i32, i32, i32, i16, i16, i32, i32 } + %struct.XXFramebufferAttachment = type { i16, i16, i32, i32, i32 } + %struct.XXFramebufferData = type { [10 x %struct.XXFramebufferAttachment], [8 x i16], i16, i16, i16, i8, i8, i32, i32 } + %struct.XXFramebufferRec = type { %struct.XXFramebufferData*, %struct.XXPluginFramebufferData*, %struct.XXFormat, i8, i8, i8, i8 } + %struct.XXGeometryShaderLimits = type { i32, i32, i32, i32, i32 } + %struct.XXHintMode = type { i16, i16, i16, i16, i16, i16, i16, i16, i16, i16 } + %struct.XXHistogram = type { %struct.XXProgramLimits*, i32, i16, i8, i8 } + %struct.XXImagingColorScale = type { %struct.ZZTCoord2, %struct.ZZTCoord2, %struct.ZZTCoord2, %struct.ZZTCoord2 } + %struct.XXImagingSubset = type { %struct.XXConvolution, %struct.XXConvolution, %struct.XXConvolution, %struct.XXColorMatrix, %struct.XXMinmax, %struct.XXHistogram, %struct.XXImagingColorScale, %struct.XXImagingColorScale, %struct.XXImagingColorScale, %struct.XXImagingColorScale, i32, [0 x i32] } + %struct.XXLight = type { %struct.ZZIColor4, %struct.ZZIColor4, %struct.ZZIColor4, %struct.ZZIColor4, %struct.XXPointLineLimits, float, float, float, float, float, %struct.XXPointLineLimits, float, %struct.XXPointLineLimits, float, %struct.XXPointLineLimits, float, float, float, float, float } + %struct.XXLightModel = type { %struct.ZZIColor4, [8 x %struct.XXLight], [2 x %struct.XXMaterial], i32, i16, i16, i16, i8, i8, i8, i8, i8, i8 } + %struct.XXLightProduct = type { %struct.ZZIColor4, %struct.ZZIColor4, %struct.ZZIColor4 } + %struct.XXLineMode = type { float, i32, i16, i16, i8, i8, i8, i8 } + %struct.XXLogicOp = type { i16, i8, i8 } + %struct.XXMaskMode = type { i32, [3 x i32], i8, i8, i8, i8, i8, i8, i8, i8 } + %struct.XXMaterial = type { %struct.ZZIColor4, %struct.ZZIColor4, %struct.ZZIColor4, %struct.ZZIColor4, float, float, float, float, [8 x %struct.XXLightProduct], %struct.ZZIColor4, [8 x i32] } + %struct.XXMinmax = type { %struct.XXMinmaxTable*, i16, i8, i8, [0 x i32] } + %struct.XXMinmaxTable = type { %struct.ZZIColor4, %struct.ZZIColor4 } + %struct.XXMipmaplevel = type { [4 x i32], [4 x i32], [4 x float], [4 x i32], i32, i32, float*, i8*, i16, i16, i16, i16, [2 x float] } + %struct.XXMultisample = type { float, i8, i8, i8, i8, i8, i8, i8, i8 } + %struct.XXPipelineProgramData = type { i16, i8, i8, i32, %struct.PPStreamToken*, i64, %struct.ZZIColor4*, i32, [0 x i32] } + %struct.XXPipelineProgramLimits = type { i32, i16, i16, i32, i16, i16, i32, i32 } + %struct.XXPipelineProgramRec = type { %struct.XXPipelineProgramData*, %struct.PPStreamToken*, %struct.XXContextRec*, { %struct._YYFunction*, \2, \2, [20 x i32], [64 x i32], i32, i32, i32 }*, i32, i32 } + %struct.XXPipelineProgramState = type { i8, i8, i8, i8, [0 x i32], %struct.ZZIColor4* } + %struct.XXPixelFormatInfo = type { i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8 } + %struct.XXPixelMap = type { i32*, float*, float*, float*, float*, float*, float*, float*, float*, i32*, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } + %struct.XXPixelMode = type { float, float, %struct.XXPixelStore, %struct.XXPixelTransfer, %struct.XXPixelMap, %struct.XXImagingSubset, i32, i32 } + %struct.XXPixelPack = type { i32, i32, i32, i32, i32, i32, i32, i32, i8, i8, i8, i8 } + %struct.XXPixelStore = type { %struct.XXPixelPack, %struct.XXPixelPack } + %struct.XXPixelTransfer = type { float, float, float, float, float, float, float, float, float, float, i32, i32, float, float, float, float, float, float, float, float, float, float, float, float } + %struct.XXPluginFramebufferData = type { [10 x %struct.XXTextureRec*], i8, i8, i8, i8 } + %struct.XXPluginProgramData = type { [3 x %struct.XXPipelineProgramRec*], %struct.XXBBRec**, i32, [0 x i32] } + %struct.XXPluginState = type { [16 x [5 x %struct.XXTextureRec*]], [3 x %struct.XXTextureRec*], [3 x %struct.XXPipelineProgramRec*], [3 x %struct.XXPipelineProgramRec*], %struct.XXProgramRec*, %struct.XXVertexArrayRec*, [16 x %struct.XXBBRec*], %struct.XXFramebufferRec*, %struct.XXFramebufferRec* } + %struct.XXPointLineLimits = type { float, float, float } + %struct.XXPointMode = type { float, float, float, float, %struct.XXPointLineLimits, float, i8, i8, i8, i8, i16, i16, i32, i16, i16 } + %struct.XXPolygonMode = type { [128 x i8], float, float, i16, i16, i16, i16, i8, i8, i8, i8, i8, i8, i8, i8 } + %struct.XXProgramData = type { i32, i32, i32, i32, %struct.PPStreamToken*, i32*, i32, i32, i32, i32, i8, i8, i8, i8, [0 x i32] } + %struct.XXProgramLimits = type { i32, i32, i32, i32 } + %struct.XXProgramRec = type { %struct.XXProgramData*, %struct.XXPluginProgramData*, %struct.ZZIColor4**, i32 } + %struct.XXQueryRec = type { i32, i32, %struct.XXQueryRec* } + %struct.XXRect = type { i32, i32, i32, i32, i32, i32 } + %struct.XXRegisterCombiners = type { i8, i8, i8, i8, i32, [2 x %struct.ZZIColor4], [8 x %struct.XXRegisterCombinersPerStageState], %struct.XXRegisterCombinersFinalStageState } + %struct.XXRegisterCombinersFinalStageState = type { i8, i8, i8, i8, [7 x %struct.XXRegisterCombinersPerVariableState] } + %struct.XXRegisterCombinersPerPortionState = type { [4 x %struct.XXRegisterCombinersPerVariableState], i8, i8, i8, i8, i16, i16, i16, i16, i16, i16 } + %struct.XXRegisterCombinersPerStageState = type { [2 x %struct.XXRegisterCombinersPerPortionState], [2 x %struct.ZZIColor4] } + %struct.XXRegisterCombinersPerVariableState = type { i16, i16, i16, i16 } + %struct.XXRenderDispatch = type { void (%struct.XXContextRec*, i32, float)*, void (%struct.XXContextRec*, i32)*, i32 (%struct.XXContextRec*, i32, i32, i32, i32, i32, i32, i8*, i32, %struct.XXBBRec*)*, i32 (%struct.XXContextRec*, %struct.XXVertex*, i32, i32, i32, i32, i8*, i32, %struct.XXBBRec*)*, void (%struct.XXContextRec*, %struct.XXVertex*, i32, i32, i32, i32, i32)*, void (%struct.XXContextRec*, %struct.XXVertex*, i32, i32, float, float, i8*, i32)*, void (%struct.XXContextRec*, %struct.XXVertex*, i32, i32)*, void (%struct.XXContextRec*, %struct.XXVertex*, i32, i32)*, void (%struct.XXContextRec*, %struct.XXVertex*, i32, i32)*, void (%struct.XXContextRec*, %struct.XXVertex*, i32, i32)*, void (%struct.XXContextRec*, %struct.XXVertex*, i32, i32)*, void (%struct.XXContextRec*, %struct.XXVertex*, i32, i32)*, void (%struct.XXContextRec*, %struct.XXVertex*, %struct.XXVertex*, i32, i32)*, void (%struct.XXContextRec*, %struct.XXVertex*, i32, i32)*, void (%struct.XXContextRec*, %s! truct.XXVertex*, i32, i32)*, void (%struct.XXContextRec*, %struct.XXVertex*, i32, i32)*, void (%struct.XXContextRec*, %struct.XXVertex*, i32, i32)*, void (%struct.XXContextRec*, %struct.XXVertex*, i32, i32)*, void (%struct.XXContextRec*, %struct.XXVertex*, i32, i32)*, void (%struct.XXContextRec*, %struct.XXVertex*, i32, i32)*, void (%struct.XXContextRec*, %struct.XXVertex**, i32)*, void (%struct.XXContextRec*, %struct.XXVertex**, i32, i32)*, void (%struct.XXContextRec*, %struct.XXVertex**, i32, i32)*, i8* (%struct.XXContextRec*, i32, i32*)*, void (%struct.XXContextRec*, i32, i32, i32)*, i8* (%struct.XXContextRec*, i32, i32, i32, i32, i32)*, void (%struct.XXContextRec*, i32, i32, i32, i32, i32, i8*)*, void (%struct.XXContextRec*)*, void (%struct.XXContextRec*)*, void (%struct.XXContextRec*)*, void (%struct.XXContextRec*, %struct.XXFenceRec*)*, void (%struct.XXContextRec*, i32, %struct.XXQueryRec*)*, void (%struct.XXContextRec*, %struct.XXQueryRec*)*, i32 (%struct.XXContextRe! c*, i32, i32, i32, i32, i32, i8*, %struct.ZZIColor4*, %struct.! XXCurren t16A*)*, i32 (%struct.XXContextRec*, %struct.XXTextureRec*, i32, i32, i32, i32, i32, i32, i32, i32, i32)*, i32 (%struct.XXContextRec*, %struct.XXTextureRec*, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i8*, i32, %struct.XXBBRec*)*, i32 (%struct.XXContextRec*, %struct.XXTextureRec*, i32)*, i32 (%struct.XXContextRec*, %struct.XXBBRec*, i32, i32, i8*)*, void (%struct.XXContextRec*, i32)*, void (%struct.XXContextRec*)*, void (%struct.XXContextRec*, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32)*, i32 (%struct.XXContextRec*, %struct.XXQueryRec*)*, void (%struct.XXContextRec*)* } + %struct.XXRenderFeatures = type { i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8 } + %struct.XXSWRSurfaceRec = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i8*, i8*, i8*, [4 x i8*], i32 } + %struct.XXScissorTest = type { %struct.XXProgramLimits, i8, i8, i8, i8 } + %struct.XXSharedData = type { } + %struct.XXSharedRec = type { %struct.__ZZarrayelementDrawInfoListType, %struct.XXSharedData*, i32, i8, i8, i8, i8 } + %struct.XXState = type <{ i16, i16, i16, i16, i32, i32, [256 x %struct.ZZIColor4], [128 x %struct.ZZIColor4], %struct.XXViewport, %struct.XXTransform, %struct.XXLightModel, %struct.XXActiveTextureTargets, %struct.XXAlphaTest, %struct.XXBlendMode, %struct.XXClearColor, %struct.XXColorBB, %struct.XXDepthTest, %struct.XXArrayRange, %struct.XXFogMode, %struct.XXHintMode, %struct.XXLineMode, %struct.XXLogicOp, %struct.XXMaskMode, %struct.XXPixelMode, %struct.XXPointMode, %struct.XXPolygonMode, %struct.XXScissorTest, i32, %struct.XXStencilTest, [8 x %struct.XXTextureMode], [16 x %struct.XXTextureImageMode], %struct.XXArrayRange, [8 x %struct.XXTextureCoordGen], %struct.XXClipPlane, %struct.XXMultisample, %struct.XXRegisterCombiners, %struct.XXArrayRange, %struct.XXArrayRange, [3 x %struct.XXPipelineProgramState], %struct.XXArrayRange, %struct.XXTransformFeedback, i32*, %struct.XXFixedFunction, [1 x i32] }> + %struct.XXStencilTest = type { [3 x { i32, i32, i16, i16, i16, i16 }], i32, [4 x i8] } + %struct.XXStippleData = type { i32, i16, i16, [32 x [32 x i8]] } + %struct.XXTextureCoordGen = type { { i16, i16, %struct.ZZIColor4, %struct.ZZIColor4 }, { i16, i16, %struct.ZZIColor4, %struct.ZZIColor4 }, { i16, i16, %struct.ZZIColor4, %struct.ZZIColor4 }, { i16, i16, %struct.ZZIColor4, %struct.ZZIColor4 }, i8, i8, i8, i8 } + %struct.XXTextureGeomState = type { i16, i16, i16, i16, i16, i8, i8, i8, i8, i16, i16, i16, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, [6 x i16], [6 x i16] } + %struct.XXTextureImageMode = type { float } + %struct.XXTextureLevel = type { i32, i32, i16, i16, i16, i8, i8, i16, i16, i16, i16, i8* } + %struct.XXTextureLimits = type { float, float, i16, i16, i16, i16, i16, i16, i16, i16, i16, i8, i8, [16 x i16], i32 } + %struct.XXTextureMode = type { %struct.ZZIColor4, i32, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, float, float, i16, i16, i16, i16, i16, i16, [4 x i16], i8, i8, i8, i8, [3 x float], [4 x float], float, float } + %struct.XXTextureParamState = type { i16, i16, i16, i16, i16, i16, %struct.ZZIColor4, float, float, float, float, i16, i16, i16, i16, float, i16, i8, i8, i32, i8* } + %struct.XXTextureRec = type { [4 x float], %struct.XXTextureState*, %struct.XXMipmaplevel*, %struct.XXMipmaplevel*, float, float, float, float, i8, i8, i8, i8, i16, i16, i16, i16, i32, float, [2 x %struct.PPStreamToken] } + %struct.XXTextureState = type { i16, i8, i8, i16, i16, float, i32, %struct.XXSWRSurfaceRec*, %struct.XXTextureParamState, %struct.XXTextureGeomState, i16, i16, i8*, %struct.XXTextureLevel, [1 x [15 x %struct.XXTextureLevel]] } + %struct.XXTransform = type <{ [24 x [16 x float]], [24 x [16 x float]], [16 x float], float, float, float, float, float, i8, i8, i8, i8, i32, i32, i32, i16, i16, i8, i8, i8, i8, i32 }> + %struct.XXTransformFeedback = type { i8, i8, i8, i8, [0 x i32], [16 x i32], [16 x i32] } + %struct.XXVertex = type { %struct.ZZIColor4, %struct.ZZIColor4, %struct.ZZIColor4, %struct.ZZIColor4, %struct.ZZIColor4, %struct.XXPointLineLimits, float, %struct.ZZIColor4, float, i8, i8, i8, i8, float, float, i32, i32, i32, i32, [4 x float], [2 x %struct.XXMaterial*], [2 x i32], [8 x %struct.ZZIColor4] } + %struct.XXVertexArrayRec = type opaque + %struct.XXVertexDescriptor = type { i8, i8, i8, i8, [0 x i32] } + %struct.XXVertexProgramLimits = type { i16, i16, i32, i32 } + %struct.XXViewport = type { float, float, float, float, float, float, float, float, float, float, float, float, float, float, float, float, double, double, i32, i32, i32, i32, float, float, float, float } + %struct.ZZGColorTable = type { i32, i32, i32, i8* } + %struct.ZZGOperation = type { i8*, i8*, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, float, float, %struct.ZZGColorTable, %struct.ZZGColorTable, %struct.ZZGColorTable } + %struct.ZZGProcessor = type { void (%struct.XXPixelMode*, %struct.ZZGOperation*, %struct._ZZGProcessorData*, %union._ZZGFunctionKey*)*, %struct._YYFunction*, %union._ZZGFunctionKey*, %struct._ZZGProcessorData* } + %struct.ZZGTransformKey = type { i32, i32 } + %struct.ZZIColor4 = type { float, float, float, float } + %struct.ZZSBB = type { i8* } + %struct.ZZSDrawable = type { %struct.ZZSWindowRec* } + %struct.ZZSWindowRec = type { %struct.ZZGTransformKey, %struct.ZZGTransformKey, i32, i32, %struct.ZZSDrawable, i8*, i8*, i8*, i8*, i8*, [4 x i8*], i32, i16, i16, i16, i16, i8, i8, i8, i8, i8, i8, i8, i8, %struct.XXDrawableWindow, i32, i32, i8*, i8* } + %struct.ZZTCoord2 = type { float, float } + %struct.YYFPContext = type { float, i32, i32, i32, float, [3 x float] } + %struct.YYFragmentAttrib = type { <4 x float>, <4 x float>, <4 x float>, <4 x float>, <4 x float>, [8 x <4 x float>] } + %struct.YYTextures = type { [16 x %struct.XXTextureRec*] } + %struct.PPStreamToken = type { { i16, i16, i32 } } + %struct._ZZGProcessorData = type { void (i8*, i8*, i32, i32, i32, i32, i32, i32, i32)*, void (i8*, i8*, i32, i32, i32, i32, i32, i32, i32)*, i8* (i32)*, void (i8*)* } + %struct._YYConstants = type { <4 x float>, <4 x float>, <4 x float>, <4 x float>, <4 x float>, <4 x float>, <4 x float>, <4 x float>, <4 x float>, <4 x float>, float, float, float, float, float, float, float, float, float, float, float, float, [256 x float], [4096 x i8], [8 x float], [48 x float], [128 x float], [528 x i8], { void (i8*, i8*, i32, i8*)*, float (float)*, float (float)*, float (float)*, i32 (float)* } } + %struct._YYFunction = type opaque + %struct.__ZZarrayelementDrawInfoListType = type { i32, [40 x i8] } + %union._ZZGFunctionKey = type opaque + at llvm.used = appending global [1 x i8*] [ i8* bitcast (void (%struct.XXContextRec*, i32, i32, %struct.YYFragmentAttrib*, %struct.YYFragmentAttrib*, i32)* @t to i8*) ], section "llvm.metadata" ; <[1 x i8*]*> [#uses=0] + +define void @t(%struct.XXContextRec* %ctx, i32 %x, i32 %y, %struct.YYFragmentAttrib* %start, %struct.YYFragmentAttrib* %deriv, i32 %num_frags) nounwind { +entry: + %tmp7485.i.i.i = xor <4 x i32> zeroinitializer, < i32 -1, i32 -1, i32 -1, i32 -1 > ; <<4 x i32>> [#uses=1] + %tmp8382.i.i.i = extractelement <4 x i32> zeroinitializer, i32 1 ; [#uses=1] + %tmp8383.i.i.i = extractelement <4 x i32> zeroinitializer, i32 2 ; [#uses=2] + %tmp8384.i.i.i = extractelement <4 x i32> zeroinitializer, i32 3 ; [#uses=2] + br label %bb7551.i.i.i + +bb4426.i.i.i: ; preds = %bb7551.i.i.i + %0 = getelementptr %struct.XXMipmaplevel* null, i32 %tmp8383.i.i.i, i32 3 ; <[4 x i32]*> [#uses=1] + %1 = bitcast [4 x i32]* %0 to <4 x i32>* ; <<4 x i32>*> [#uses=1] + %2 = load <4 x i32>* %1, align 16 ; <<4 x i32>> [#uses=1] + %3 = getelementptr %struct.XXMipmaplevel* null, i32 %tmp8384.i.i.i, i32 3 ; <[4 x i32]*> [#uses=1] + %4 = bitcast [4 x i32]* %3 to <4 x i32>* ; <<4 x i32>*> [#uses=1] + %5 = load <4 x i32>* %4, align 16 ; <<4 x i32>> [#uses=1] + %6 = shufflevector <4 x i32> %2, <4 x i32> %5, <4 x i32> < i32 0, i32 4, i32 1, i32 5 > ; <<4 x i32>> [#uses=1] + %7 = bitcast <4 x i32> %6 to <2 x i64> ; <<2 x i64>> [#uses=1] + %8 = shufflevector <2 x i64> zeroinitializer, <2 x i64> %7, <2 x i32> < i32 1, i32 3 > ; <<2 x i64>> [#uses=1] + %9 = getelementptr %struct.XXMipmaplevel* null, i32 %tmp8382.i.i.i, i32 6 ; [#uses=1] + %10 = load float** %9, align 4 ; [#uses=1] + %11 = bitcast float* %10 to i8* ; [#uses=1] + %12 = getelementptr %struct.XXMipmaplevel* null, i32 %tmp8383.i.i.i, i32 6 ; [#uses=1] + %13 = load float** %12, align 4 ; [#uses=1] + %14 = bitcast float* %13 to i8* ; [#uses=1] + %15 = getelementptr %struct.XXMipmaplevel* null, i32 %tmp8384.i.i.i, i32 6 ; [#uses=1] + %16 = load float** %15, align 4 ; [#uses=1] + %17 = bitcast float* %16 to i8* ; [#uses=1] + %tmp7308.i.i.i = and <2 x i64> zeroinitializer, %8 ; <<2 x i64>> [#uses=1] + %18 = bitcast <2 x i64> %tmp7308.i.i.i to <4 x i32> ; <<4 x i32>> [#uses=1] + %19 = mul <4 x i32> %18, zeroinitializer ; <<4 x i32>> [#uses=1] + %20 = add <4 x i32> %19, zeroinitializer ; <<4 x i32>> [#uses=3] + %21 = load i32* null, align 4 ; [#uses=0] + %22 = call <4 x float> @llvm.x86.sse2.cvtdq2ps(<4 x i32> zeroinitializer) nounwind readnone ; <<4 x float>> [#uses=1] + %23 = mul <4 x float> %22, < float 0x3F70101020000000, float 0x3F70101020000000, float 0x3F70101020000000, float 0x3F70101020000000 > ; <<4 x float>> [#uses=1] + %tmp2114.i119.i.i = extractelement <4 x i32> %20, i32 1 ; [#uses=1] + %24 = shl i32 %tmp2114.i119.i.i, 2 ; [#uses=1] + %25 = getelementptr i8* %11, i32 %24 ; [#uses=1] + %26 = bitcast i8* %25 to i32* ; [#uses=1] + %27 = load i32* %26, align 4 ; [#uses=1] + %28 = or i32 %27, -16777216 ; [#uses=1] + %tmp1927.i120.i.i = insertelement <4 x i32> undef, i32 %28, i32 0 ; <<4 x i32>> [#uses=1] + %29 = bitcast <4 x i32> %tmp1927.i120.i.i to <16 x i8> ; <<16 x i8>> [#uses=1] + %30 = shufflevector <16 x i8> %29, <16 x i8> < i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef >, <16 x i32> < i32 0, i32 16, i32 1, i32 17, i32 2, i32 18, i32 3, i32 19, i32 4, i32 20, i32 5, i32 21, i32 6, i32 22, i32 7, i32 23 > ; <<16 x i8>> [#uses=1] + %31 = bitcast <16 x i8> %30 to <8 x i16> ; <<8 x i16>> [#uses=1] + %32 = shufflevector <8 x i16> %31, <8 x i16> < i16 0, i16 0, i16 0, i16 0, i16 undef, i16 undef, i16 undef, i16 undef >, <8 x i32> < i32 0, i32 8, i32 1, i32 9, i32 2, i32 10, i32 3, i32 11 > ; <<8 x i16>> [#uses=1] + %33 = bitcast <8 x i16> %32 to <4 x i32> ; <<4 x i32>> [#uses=1] + %34 = shufflevector <4 x i32> %33, <4 x i32> undef, <4 x i32> < i32 2, i32 1, i32 0, i32 3 > ; <<4 x i32>> [#uses=1] + %35 = call <4 x float> @llvm.x86.sse2.cvtdq2ps(<4 x i32> %34) nounwind readnone ; <<4 x float>> [#uses=1] + %36 = mul <4 x float> %35, < float 0x3F70101020000000, float 0x3F70101020000000, float 0x3F70101020000000, float 0x3F70101020000000 > ; <<4 x float>> [#uses=1] + %tmp2113.i124.i.i = extractelement <4 x i32> %20, i32 2 ; [#uses=1] + %37 = shl i32 %tmp2113.i124.i.i, 2 ; [#uses=1] + %38 = getelementptr i8* %14, i32 %37 ; [#uses=1] + %39 = bitcast i8* %38 to i32* ; [#uses=1] + %40 = load i32* %39, align 4 ; [#uses=1] + %41 = or i32 %40, -16777216 ; [#uses=1] + %tmp1963.i125.i.i = insertelement <4 x i32> undef, i32 %41, i32 0 ; <<4 x i32>> [#uses=1] + %42 = bitcast <4 x i32> %tmp1963.i125.i.i to <16 x i8> ; <<16 x i8>> [#uses=1] + %43 = shufflevector <16 x i8> %42, <16 x i8> < i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef >, <16 x i32> < i32 0, i32 16, i32 1, i32 17, i32 2, i32 18, i32 3, i32 19, i32 4, i32 20, i32 5, i32 21, i32 6, i32 22, i32 7, i32 23 > ; <<16 x i8>> [#uses=1] + %44 = bitcast <16 x i8> %43 to <8 x i16> ; <<8 x i16>> [#uses=1] + %45 = shufflevector <8 x i16> %44, <8 x i16> < i16 0, i16 0, i16 0, i16 0, i16 undef, i16 undef, i16 undef, i16 undef >, <8 x i32> < i32 0, i32 8, i32 1, i32 9, i32 2, i32 10, i32 3, i32 11 > ; <<8 x i16>> [#uses=1] + %46 = bitcast <8 x i16> %45 to <4 x i32> ; <<4 x i32>> [#uses=1] + %47 = shufflevector <4 x i32> %46, <4 x i32> undef, <4 x i32> < i32 2, i32 1, i32 0, i32 3 > ; <<4 x i32>> [#uses=1] + %48 = call <4 x float> @llvm.x86.sse2.cvtdq2ps(<4 x i32> %47) nounwind readnone ; <<4 x float>> [#uses=1] + %49 = mul <4 x float> %48, < float 0x3F70101020000000, float 0x3F70101020000000, float 0x3F70101020000000, float 0x3F70101020000000 > ; <<4 x float>> [#uses=1] + %tmp2112.i129.i.i = extractelement <4 x i32> %20, i32 3 ; [#uses=1] + %50 = shl i32 %tmp2112.i129.i.i, 2 ; [#uses=1] + %51 = getelementptr i8* %17, i32 %50 ; [#uses=1] + %52 = bitcast i8* %51 to i32* ; [#uses=1] + %53 = load i32* %52, align 4 ; [#uses=1] + %54 = or i32 %53, -16777216 ; [#uses=1] + %tmp1999.i130.i.i = insertelement <4 x i32> undef, i32 %54, i32 0 ; <<4 x i32>> [#uses=1] + %55 = bitcast <4 x i32> %tmp1999.i130.i.i to <16 x i8> ; <<16 x i8>> [#uses=1] + %56 = shufflevector <16 x i8> %55, <16 x i8> < i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef >, <16 x i32> < i32 0, i32 16, i32 1, i32 17, i32 2, i32 18, i32 3, i32 19, i32 4, i32 20, i32 5, i32 21, i32 6, i32 22, i32 7, i32 23 > ; <<16 x i8>> [#uses=1] + %57 = bitcast <16 x i8> %56 to <8 x i16> ; <<8 x i16>> [#uses=1] + %58 = shufflevector <8 x i16> %57, <8 x i16> < i16 0, i16 0, i16 0, i16 0, i16 undef, i16 undef, i16 undef, i16 undef >, <8 x i32> < i32 0, i32 8, i32 1, i32 9, i32 2, i32 10, i32 3, i32 11 > ; <<8 x i16>> [#uses=1] + %59 = bitcast <8 x i16> %58 to <4 x i32> ; <<4 x i32>> [#uses=1] + %60 = shufflevector <4 x i32> %59, <4 x i32> undef, <4 x i32> < i32 2, i32 1, i32 0, i32 3 > ; <<4 x i32>> [#uses=1] + %61 = call <4 x float> @llvm.x86.sse2.cvtdq2ps(<4 x i32> %60) nounwind readnone ; <<4 x float>> [#uses=1] + %62 = mul <4 x float> %61, < float 0x3F70101020000000, float 0x3F70101020000000, float 0x3F70101020000000, float 0x3F70101020000000 > ; <<4 x float>> [#uses=1] + %63 = mul <4 x float> %23, zeroinitializer ; <<4 x float>> [#uses=1] + %64 = add <4 x float> zeroinitializer, %63 ; <<4 x float>> [#uses=1] + %65 = mul <4 x float> %36, zeroinitializer ; <<4 x float>> [#uses=1] + %66 = add <4 x float> zeroinitializer, %65 ; <<4 x float>> [#uses=1] + %67 = mul <4 x float> %49, zeroinitializer ; <<4 x float>> [#uses=1] + %68 = add <4 x float> zeroinitializer, %67 ; <<4 x float>> [#uses=1] + %69 = mul <4 x float> %62, zeroinitializer ; <<4 x float>> [#uses=1] + %70 = add <4 x float> zeroinitializer, %69 ; <<4 x float>> [#uses=1] + %tmp7452.i.i.i = bitcast <4 x float> %64 to <4 x i32> ; <<4 x i32>> [#uses=1] + %tmp7454.i.i.i = and <4 x i32> %tmp7452.i.i.i, zeroinitializer ; <<4 x i32>> [#uses=1] + %tmp7459.i.i.i = or <4 x i32> %tmp7454.i.i.i, zeroinitializer ; <<4 x i32>> [#uses=1] + %tmp7460.i.i.i = bitcast <4 x i32> %tmp7459.i.i.i to <4 x float> ; <<4 x float>> [#uses=1] + %tmp7468.i.i.i = bitcast <4 x float> %66 to <4 x i32> ; <<4 x i32>> [#uses=1] + %tmp7470.i.i.i = and <4 x i32> %tmp7468.i.i.i, zeroinitializer ; <<4 x i32>> [#uses=1] + %tmp7475.i.i.i = or <4 x i32> %tmp7470.i.i.i, zeroinitializer ; <<4 x i32>> [#uses=1] + %tmp7476.i.i.i = bitcast <4 x i32> %tmp7475.i.i.i to <4 x float> ; <<4 x float>> [#uses=1] + %tmp7479.i.i.i = bitcast <4 x float> %.279.1.i to <4 x i32> ; <<4 x i32>> [#uses=1] + %tmp7480.i.i.i = and <4 x i32> zeroinitializer, %tmp7479.i.i.i ; <<4 x i32>> [#uses=1] + %tmp7484.i.i.i = bitcast <4 x float> %68 to <4 x i32> ; <<4 x i32>> [#uses=1] + %tmp7486.i.i.i = and <4 x i32> %tmp7484.i.i.i, %tmp7485.i.i.i ; <<4 x i32>> [#uses=1] + %tmp7491.i.i.i = or <4 x i32> %tmp7486.i.i.i, %tmp7480.i.i.i ; <<4 x i32>> [#uses=1] + %tmp7492.i.i.i = bitcast <4 x i32> %tmp7491.i.i.i to <4 x float> ; <<4 x float>> [#uses=1] + %tmp7495.i.i.i = bitcast <4 x float> %.380.1.i to <4 x i32> ; <<4 x i32>> [#uses=1] + %tmp7496.i.i.i = and <4 x i32> zeroinitializer, %tmp7495.i.i.i ; <<4 x i32>> [#uses=1] + %tmp7500.i.i.i = bitcast <4 x float> %70 to <4 x i32> ; <<4 x i32>> [#uses=1] + %tmp7502.i.i.i = and <4 x i32> %tmp7500.i.i.i, zeroinitializer ; <<4 x i32>> [#uses=1] + %tmp7507.i.i.i = or <4 x i32> %tmp7502.i.i.i, %tmp7496.i.i.i ; <<4 x i32>> [#uses=1] + %tmp7508.i.i.i = bitcast <4 x i32> %tmp7507.i.i.i to <4 x float> ; <<4 x float>> [#uses=1] + %indvar.next.i.i.i = add i32 %aniso.0.i.i.i, 1 ; [#uses=1] + br label %bb7551.i.i.i + +bb7551.i.i.i: ; preds = %bb4426.i.i.i, %entry + %.077.1.i = phi <4 x float> [ undef, %entry ], [ %tmp7460.i.i.i, %bb4426.i.i.i ] ; <<4 x float>> [#uses=0] + %.178.1.i = phi <4 x float> [ undef, %entry ], [ %tmp7476.i.i.i, %bb4426.i.i.i ] ; <<4 x float>> [#uses=0] + %.279.1.i = phi <4 x float> [ undef, %entry ], [ %tmp7492.i.i.i, %bb4426.i.i.i ] ; <<4 x float>> [#uses=1] + %.380.1.i = phi <4 x float> [ undef, %entry ], [ %tmp7508.i.i.i, %bb4426.i.i.i ] ; <<4 x float>> [#uses=1] + %aniso.0.i.i.i = phi i32 [ 0, %entry ], [ %indvar.next.i.i.i, %bb4426.i.i.i ] ; [#uses=1] + br i1 false, label %glvmInterpretFPTransformFour6.exit, label %bb4426.i.i.i + +glvmInterpretFPTransformFour6.exit: ; preds = %bb7551.i.i.i + unreachable +} + +declare <4 x float> @llvm.x86.sse2.cvtdq2ps(<4 x i32>) nounwind readnone From echeng at apple.com Fri Dec 5 11:29:01 2008 From: echeng at apple.com (Evan Cheng) Date: Fri, 5 Dec 2008 09:29:01 -0800 Subject: [llvm-commits] [llvm] r60461 - in /llvm/trunk: include/llvm/Target/Target.td include/llvm/Target/TargetInstrDesc.h lib/Target/X86/X86InstrInfo.cpp lib/Target/X86/X86InstrSSE.td test/CodeGen/X86/fold-pcmpeqd-0.ll test/CodeGen/X86/fold-pcmpeqd-1.ll utils/TableGen/CodeGenDAGPatterns.cpp In-Reply-To: <200812030521.mB35LReU024052@zion.cs.uiuc.edu> References: <200812030521.mB35LReU024052@zion.cs.uiuc.edu> Message-ID: <727785FB-2A12-4C15-B14F-EF4B9D325CB0@apple.com> Dan, this is breaking stuff. Please see 60595. Evan On Dec 2, 2008, at 9:21 PM, Dan Gohman wrote: > Author: djg > Date: Tue Dec 2 23:21:24 2008 > New Revision: 60461 > > URL: http://llvm.org/viewvc/llvm-project?rev=60461&view=rev > Log: > Mark x86's V_SET0 and V_SETALLONES with isSimpleLoad, and teach X86's > foldMemoryOperand how to "fold" them, by converting them into > constant-pool > loads. When they aren't folded, they use xorps/cmpeqd, but for > example when > register pressure is high, they may now be folded as memory > operands, which > reduces register pressure. > > Also, mark V_SET0 isAsCheapAsAMove so that two-address-elimination > will > remat it instead of copying zeros around (V_SETALLONES was already > marked). > > Added: > llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-0.ll > llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-1.ll > Modified: > llvm/trunk/include/llvm/Target/Target.td > llvm/trunk/include/llvm/Target/TargetInstrDesc.h > llvm/trunk/lib/Target/X86/X86InstrInfo.cpp > llvm/trunk/lib/Target/X86/X86InstrSSE.td > llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp > > Modified: llvm/trunk/include/llvm/Target/Target.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=60461&r1=60460&r2=60461&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/Target/Target.td (original) > +++ llvm/trunk/include/llvm/Target/Target.td Tue Dec 2 23:21:24 2008 > @@ -189,7 +189,7 @@ > bit isIndirectBranch = 0; // Is this instruction an indirect branch? > bit isBarrier = 0; // Can control flow fall through this > instruction? > bit isCall = 0; // Is this instruction a call instruction? > - bit isSimpleLoad = 0; // Is this just a load instruction? > + bit isSimpleLoad = 0; // Can this be folded as a memory > operand? > bit mayLoad = 0; // Is it possible for this inst to read > memory? > bit mayStore = 0; // Is it possible for this inst to write > memory? > bit isTwoAddress = 0; // Is this a two address instruction? > > Modified: llvm/trunk/include/llvm/Target/TargetInstrDesc.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrDesc.h?rev=60461&r1=60460&r2=60461&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/include/llvm/Target/TargetInstrDesc.h (original) > +++ llvm/trunk/include/llvm/Target/TargetInstrDesc.h Tue Dec 2 > 23:21:24 2008 > @@ -301,11 +301,14 @@ > return Flags & (1 << TID::DelaySlot); > } > > - /// isSimpleLoad - Return true for instructions that are simple > loads from > - /// memory. This should only be set on instructions that load a > value from > - /// memory and return it in their only virtual register definition. > - /// Instructions that return a value loaded from memory and then > modified in > - /// some way should not return true for this. > + /// isSimpleLoad - Return true for instructions that can be > folded as > + /// memory operands in other instructions. The most common use > for this > + /// is instructions that are simple loads from memory that don't > modify > + /// the loaded value in any way, but it can also be used for > instructions > + /// that can be expressed as constant-pool loads, such as > V_SETALLONES > + /// on x86, to allow them to be folded when it is beneficial. > + /// This should only be set on instructions that return a value > in their > + /// only virtual register definition. > bool isSimpleLoad() const { > return Flags & (1 << TID::SimpleLoad); > } > > Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=60461&r1=60460&r2=60461&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) > +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Tue Dec 2 23:21:24 > 2008 > @@ -19,6 +19,7 @@ > #include "X86Subtarget.h" > #include "X86TargetMachine.h" > #include "llvm/ADT/STLExtras.h" > +#include "llvm/CodeGen/MachineConstantPool.h" > #include "llvm/CodeGen/MachineFrameInfo.h" > #include "llvm/CodeGen/MachineInstrBuilder.h" > #include "llvm/CodeGen/MachineRegisterInfo.h" > @@ -2127,9 +2128,36 @@ > return NULL; > > SmallVector MOs; > - unsigned NumOps = LoadMI->getDesc().getNumOperands(); > - for (unsigned i = NumOps - 4; i != NumOps; ++i) > - MOs.push_back(LoadMI->getOperand(i)); > + if (LoadMI->getOpcode() == X86::V_SET0 || > + LoadMI->getOpcode() == X86::V_SETALLONES) { > + // Folding a V_SET0 or V_SETALLONES as a load, to ease register > pressure. > + // Create a constant-pool entry and operands to load from it. > + > + // x86-32 PIC requires a PIC base register for constant pools. > + unsigned PICBase = 0; > + if (TM.getRelocationModel() == Reloc::PIC_ && > + !TM.getSubtarget().is64Bit()) > + PICBase = TM.getInstrInfo()->getGlobalBaseReg(&MF); > + > + // Create a v4i32 constant-pool entry. > + MachineConstantPool &MCP = *MF.getConstantPool(); > + const VectorType *Ty = VectorType::get(Type::Int32Ty, 4); > + Constant *C = LoadMI->getOpcode() == X86::V_SET0 ? > + ConstantVector::getNullValue(Ty) : > + ConstantVector::getAllOnesValue(Ty); > + unsigned CPI = MCP.getConstantPoolIndex(C, /*AlignmentLog2=*/4); > + > + // Create operands to load from the constant pool entry. > + MOs.push_back(MachineOperand::CreateReg(PICBase, false)); > + MOs.push_back(MachineOperand::CreateImm(1)); > + MOs.push_back(MachineOperand::CreateReg(0, false)); > + MOs.push_back(MachineOperand::CreateCPI(CPI, 0)); > + } else { > + // Folding a normal load. Just copy the load's address operands. > + unsigned NumOps = LoadMI->getDesc().getNumOperands(); > + for (unsigned i = NumOps - 4; i != NumOps; ++i) > + MOs.push_back(LoadMI->getOperand(i)); > + } > return foldMemoryOperand(MF, MI, Ops[0], MOs); > } > > > Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=60461&r1=60460&r2=60461&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) > +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Tue Dec 2 23:21:24 2008 > @@ -987,7 +987,9 @@ > "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)]>; > > // Alias instructions that map zero vector to pxor / xorp* for sse. > -let isReMaterializable = 1 in > +// We set isSimpleLoad because this can be converted to a constant- > pool > +// load of an all-zeros value if folding it would be beneficial. > +let isReMaterializable = 1, isAsCheapAsAMove = 1, isSimpleLoad = 1 in > def V_SET0 : PSI<0x57, MRMInitReg, (outs VR128:$dst), (ins), > "xorps\t$dst, $dst", > [(set VR128:$dst, (v4i32 immAllZerosV))]>; > @@ -2253,7 +2255,9 @@ > (i8 1)), (MFENCE)>; > > // Alias instructions that map zero vector to pxor / xorp* for sse. > -let isReMaterializable = 1, isAsCheapAsAMove = 1 in > +// We set isSimpleLoad because this can be converted to a constant- > pool > +// load of an all-ones value if folding it would be beneficial. > +let isReMaterializable = 1, isAsCheapAsAMove = 1, isSimpleLoad = 1 in > def V_SETALLONES : PDI<0x76, MRMInitReg, (outs VR128:$dst), (ins), > "pcmpeqd\t$dst, $dst", > [(set VR128:$dst, (v4i32 immAllOnesV))]>; > > Added: llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-0.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-0.ll?rev=60461&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-0.ll (added) > +++ llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-0.ll Tue Dec 2 > 23:21:24 2008 > @@ -0,0 +1,107 @@ > +; RUN: llvm-as < %s | llc | not grep pcmpeqd > +; RUN: llvm-as < %s | llc -march=x86-64 | grep pcmpeqd | count 1 > + > +; On x86-64, this testcase shouldn't need to spill the -1 value, > +; so it should just use pcmpeqd to materialize an all-ones vector. > +; On x86-32, there aren't enough registers, so an all-ones > +; constant pool should be created so it can be folded. > + > +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32- > i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64- > f80:32:32" > +target triple = "i686-apple-cl.1.0" > + %struct.__ImageExecInfo = type <{ <4 x i32>, <4 x float>, <2 x > i64>, i8*, i8*, i8*, i32, i32, i32, i32, i32 }> > + %struct._cl_image_format_t = type <{ i32, i32, i32 }> > + %struct._image2d_t = type <{ i8*, %struct._cl_image_format_t, i32, > i32, i32, i32, i32, i32 }> > + > +define void @program_1(%struct._image2d_t* %dest, > %struct._image2d_t* %t0, <4 x float> %p0, <4 x float> %p1, <4 x > float> %p4, <4 x float> %p5, <4 x float> %p6) nounwind { > +entry: > + %tmp3.i = load i32* null ; [#uses=1] > + %cmp = icmp sgt i32 %tmp3.i, 200 ; [#uses=1] > + br i1 %cmp, label %forcond, label %ifthen > + > +ifthen: ; preds = %entry > + ret void > + > +forcond: ; preds = %entry > + %tmp3.i536 = load i32* null ; [#uses=1] > + %cmp12 = icmp slt i32 0, %tmp3.i536 ; [#uses=1] > + br i1 %cmp12, label %forbody, label %afterfor > + > +forbody: ; preds = %forcond > + %bitcast204.i313 = bitcast <4 x i32> zeroinitializer to <4 x > float> ; <<4 x float>> [#uses=1] > + %mul233 = mul <4 x float> %bitcast204.i313, zeroinitializer ; <<4 > x float>> [#uses=1] > + %mul257 = mul <4 x float> %mul233, zeroinitializer ; <<4 x > float>> [#uses=1] > + %mul275 = mul <4 x float> %mul257, zeroinitializer ; <<4 x > float>> [#uses=1] > + %tmp51 = call <4 x float> @llvm.x86.sse.max.ps(<4 x float> > %mul275, <4 x float> zeroinitializer) nounwind ; <<4 x float>> > [#uses=1] > + %bitcast198.i182 = bitcast <4 x float> zeroinitializer to <4 x > i32> ; <<4 x i32>> [#uses=0] > + %bitcast204.i185 = bitcast <4 x i32> zeroinitializer to <4 x > float> ; <<4 x float>> [#uses=1] > + %tmp69 = call <4 x i32> @llvm.x86.sse2.cvttps2dq(<4 x float> > zeroinitializer) nounwind ; <<4 x i32>> [#uses=1] > + %tmp70 = call <4 x float> @llvm.x86.sse2.cvtdq2ps(<4 x i32> > %tmp69) nounwind ; <<4 x float>> [#uses=1] > + %sub140.i78 = sub <4 x float> zeroinitializer, %tmp70 ; <<4 x > float>> [#uses=2] > + %mul166.i86 = mul <4 x float> zeroinitializer, %sub140.i78 ; <<4 > x float>> [#uses=1] > + %add167.i87 = add <4 x float> %mul166.i86, < float > 0x3FE62ACB60000000, float 0x3FE62ACB60000000, float > 0x3FE62ACB60000000, float 0x3FE62ACB60000000 > ; <<4 x float>> > [#uses=1] > + %mul171.i88 = mul <4 x float> %add167.i87, %sub140.i78 ; <<4 x > float>> [#uses=1] > + %add172.i89 = add <4 x float> %mul171.i88, < float > 0x3FF0000A40000000, float 0x3FF0000A40000000, float > 0x3FF0000A40000000, float 0x3FF0000A40000000 > ; <<4 x float>> > [#uses=1] > + %bitcast176.i90 = bitcast <4 x float> %add172.i89 to <4 x i32> ; > <<4 x i32>> [#uses=1] > + %andnps178.i92 = and <4 x i32> %bitcast176.i90, zeroinitializer ; > <<4 x i32>> [#uses=1] > + %bitcast179.i93 = bitcast <4 x i32> %andnps178.i92 to <4 x > float> ; <<4 x float>> [#uses=1] > + %mul186.i96 = mul <4 x float> %bitcast179.i93, zeroinitializer ; > <<4 x float>> [#uses=1] > + %bitcast190.i98 = bitcast <4 x float> %mul186.i96 to <4 x i32> ; > <<4 x i32>> [#uses=1] > + %andnps192.i100 = and <4 x i32> %bitcast190.i98, > zeroinitializer ; <<4 x i32>> [#uses=1] > + %xorps.i102 = xor <4 x i32> zeroinitializer, < i32 -1, i32 -1, i32 > -1, i32 -1 > ; <<4 x i32>> [#uses=1] > + %orps203.i103 = or <4 x i32> %andnps192.i100, %xorps.i102 ; <<4 x > i32>> [#uses=1] > + %bitcast204.i104 = bitcast <4 x i32> %orps203.i103 to <4 x > float> ; <<4 x float>> [#uses=1] > + %cmple.i = call <4 x float> @llvm.x86.sse.cmp.ps(<4 x float> > zeroinitializer, <4 x float> %tmp51, i8 2) nounwind ; <<4 x float>> > [#uses=1] > + %tmp80 = call <4 x float> @llvm.x86.sse2.cvtdq2ps(<4 x i32> > zeroinitializer) nounwind ; <<4 x float>> [#uses=1] > + %sub140.i = sub <4 x float> zeroinitializer, %tmp80 ; <<4 x > float>> [#uses=1] > + %bitcast148.i = bitcast <4 x float> zeroinitializer to <4 x > i32> ; <<4 x i32>> [#uses=1] > + %andnps150.i = and <4 x i32> %bitcast148.i, < i32 -2139095041, i32 > -2139095041, i32 -2139095041, i32 -2139095041 > ; <<4 x i32>> > [#uses=0] > + %mul171.i = mul <4 x float> zeroinitializer, %sub140.i ; <<4 x > float>> [#uses=1] > + %add172.i = add <4 x float> %mul171.i, < float 0x3FF0000A40000000, > float 0x3FF0000A40000000, float 0x3FF0000A40000000, float > 0x3FF0000A40000000 > ; <<4 x float>> [#uses=1] > + %bitcast176.i = bitcast <4 x float> %add172.i to <4 x i32> ; <<4 > x i32>> [#uses=1] > + %andnps178.i = and <4 x i32> %bitcast176.i, zeroinitializer ; <<4 > x i32>> [#uses=1] > + %bitcast179.i = bitcast <4 x i32> %andnps178.i to <4 x float> ; > <<4 x float>> [#uses=1] > + %mul186.i = mul <4 x float> %bitcast179.i, zeroinitializer ; <<4 > x float>> [#uses=1] > + %bitcast189.i = bitcast <4 x float> zeroinitializer to <4 x > i32> ; <<4 x i32>> [#uses=0] > + %bitcast190.i = bitcast <4 x float> %mul186.i to <4 x i32> ; <<4 > x i32>> [#uses=1] > + %andnps192.i = and <4 x i32> %bitcast190.i, zeroinitializer ; <<4 > x i32>> [#uses=1] > + %bitcast198.i = bitcast <4 x float> %cmple.i to <4 x i32> ; <<4 x > i32>> [#uses=1] > + %xorps.i = xor <4 x i32> %bitcast198.i, < i32 -1, i32 -1, i32 -1, > i32 -1 > ; <<4 x i32>> [#uses=1] > + %orps203.i = or <4 x i32> %andnps192.i, %xorps.i ; <<4 x i32>> > [#uses=1] > + %bitcast204.i = bitcast <4 x i32> %orps203.i to <4 x float> ; <<4 > x float>> [#uses=1] > + %mul307 = mul <4 x float> %bitcast204.i185, zeroinitializer ; <<4 > x float>> [#uses=1] > + %mul310 = mul <4 x float> %bitcast204.i104, zeroinitializer ; <<4 > x float>> [#uses=2] > + %mul313 = mul <4 x float> %bitcast204.i, zeroinitializer ; <<4 x > float>> [#uses=1] > + %tmp82 = call <4 x float> @llvm.x86.sse.min.ps(<4 x float> > %mul307, <4 x float> zeroinitializer) nounwind ; <<4 x float>> > [#uses=1] > + %bitcast11.i15 = bitcast <4 x float> %tmp82 to <4 x i32> ; <<4 x > i32>> [#uses=1] > + %andnps.i17 = and <4 x i32> %bitcast11.i15, zeroinitializer ; <<4 > x i32>> [#uses=1] > + %orps.i18 = or <4 x i32> %andnps.i17, zeroinitializer ; <<4 x > i32>> [#uses=1] > + %bitcast17.i19 = bitcast <4 x i32> %orps.i18 to <4 x float> ; <<4 > x float>> [#uses=1] > + %tmp83 = call <4 x float> @llvm.x86.sse.min.ps(<4 x float> > %mul310, <4 x float> zeroinitializer) nounwind ; <<4 x float>> > [#uses=1] > + %bitcast.i3 = bitcast <4 x float> %mul310 to <4 x i32> ; <<4 x > i32>> [#uses=1] > + %bitcast6.i4 = bitcast <4 x float> zeroinitializer to <4 x i32> ; > <<4 x i32>> [#uses=2] > + %andps.i5 = and <4 x i32> %bitcast.i3, %bitcast6.i4 ; <<4 x i32>> > [#uses=1] > + %bitcast11.i6 = bitcast <4 x float> %tmp83 to <4 x i32> ; <<4 x > i32>> [#uses=1] > + %not.i7 = xor <4 x i32> %bitcast6.i4, < i32 -1, i32 -1, i32 -1, > i32 -1 > ; <<4 x i32>> [#uses=1] > + %andnps.i8 = and <4 x i32> %bitcast11.i6, %not.i7 ; <<4 x i32>> > [#uses=1] > + %orps.i9 = or <4 x i32> %andnps.i8, %andps.i5 ; <<4 x i32>> > [#uses=1] > + %bitcast17.i10 = bitcast <4 x i32> %orps.i9 to <4 x float> ; <<4 > x float>> [#uses=1] > + %bitcast.i = bitcast <4 x float> %mul313 to <4 x i32> ; <<4 x > i32>> [#uses=1] > + %andps.i = and <4 x i32> %bitcast.i, zeroinitializer ; <<4 x > i32>> [#uses=1] > + %orps.i = or <4 x i32> zeroinitializer, %andps.i ; <<4 x i32>> > [#uses=1] > + %bitcast17.i = bitcast <4 x i32> %orps.i to <4 x float> ; <<4 x > float>> [#uses=1] > + call void null(<4 x float> %bitcast17.i19, <4 x float> > %bitcast17.i10, <4 x float> %bitcast17.i, <4 x float> > zeroinitializer, %struct.__ImageExecInfo* null, <4 x i32> > zeroinitializer) nounwind > + unreachable > + > +afterfor: ; preds = %forcond > + ret void > +} > + > +declare <4 x float> @llvm.x86.sse.cmp.ps(<4 x float>, <4 x float>, > i8) nounwind readnone > + > +declare <4 x float> @llvm.x86.sse2.cvtdq2ps(<4 x i32>) nounwind > readnone > + > +declare <4 x i32> @llvm.x86.sse2.cvttps2dq(<4 x float>) nounwind > readnone > + > +declare <4 x float> @llvm.x86.sse.max.ps(<4 x float>, <4 x float>) > nounwind readnone > + > +declare <4 x float> @llvm.x86.sse.min.ps(<4 x float>, <4 x float>) > nounwind readnone > > Added: llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-1.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-1.ll?rev=60461&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-1.ll (added) > +++ llvm/trunk/test/CodeGen/X86/fold-pcmpeqd-1.ll Tue Dec 2 > 23:21:24 2008 > @@ -0,0 +1,11 @@ > +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 > %t > +; RUN: grep pcmpeqd %t | count 1 > +; RUN: grep xor %t | count 1 > +; RUN: not grep LCP %t > + > +define <2 x double> @foo() nounwind { > + ret <2 x double> bitcast (<2 x i64> to <2 x > double>) > +} > +define <2 x double> @bar() nounwind { > + ret <2 x double> bitcast (<2 x i64> to <2 x double>) > +} > > Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp?rev=60461&r1=60460&r2=60461&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp (original) > +++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp Tue Dec 2 > 23:21:24 2008 > @@ -1759,15 +1759,6 @@ > MayLoad = true; > } > > - // Sanity-check the isSimpleLoad flag. > - if (Inst.isSimpleLoad) { > - if (!MayLoad) > - fprintf(stderr, > - "Warning: mayLoad flag not set or inferred for > instruction '%s'" > - " which has isSimpleLoad set.\n", > - Inst.TheDef->getName().c_str()); > - } > - > if (Inst.neverHasSideEffects) { > if (HadPattern) > fprintf(stderr, "Warning: neverHasSideEffects set on > instruction '%s' " > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From evan.cheng at apple.com Fri Dec 5 11:41:37 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 05 Dec 2008 17:41:37 -0000 Subject: [llvm-commits] [llvm] r60596 - in /llvm/trunk/lib: CodeGen/LiveIntervalAnalysis.cpp Target/X86/X86InstrInfo.cpp Message-ID: <200812051741.mB5Hfdx8004148@zion.cs.uiuc.edu> Author: evancheng Date: Fri Dec 5 11:41:31 2008 New Revision: 60596 URL: http://llvm.org/viewvc/llvm-project?rev=60596&view=rev Log: Reason #3 from 60595 doesn't hold true. If we can fold a PIC load from constpool into a use, the rewrite happens at time of spill (not in VirtRegMap). Later on, if the GlobalBaseReg is spilled, the spiller can see the use uses GlobalBaseReg and do the right thing. Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=60596&r1=60595&r2=60596&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Fri Dec 5 11:41:31 2008 @@ -2059,15 +2059,17 @@ if (isLoadSS || ReMatDefMI->getDesc().canFoldAsLoad()) Folded = tryFoldMemoryOperand(MI, vrm, ReMatDefMI, index, Ops, isLoadSS, LdSlot, VReg); - unsigned ImpUse = getReMatImplicitUse(li, ReMatDefMI); - if (ImpUse) { - // Re-matting an instruction with virtual register use. Add the - // register as an implicit use on the use MI and update the register - // interval's spill weight to HUGE_VALF to prevent it from being - // spilled. - LiveInterval &ImpLi = getInterval(ImpUse); - ImpLi.weight = HUGE_VALF; - MI->addOperand(MachineOperand::CreateReg(ImpUse, false, true)); + if (!Folded) { + unsigned ImpUse = getReMatImplicitUse(li, ReMatDefMI); + if (ImpUse) { + // Re-matting an instruction with virtual register use. Add the + // register as an implicit use on the use MI and update the register + // interval's spill weight to HUGE_VALF to prevent it from being + // spilled. + LiveInterval &ImpLi = getInterval(ImpUse); + ImpLi.weight = HUGE_VALF; + MI->addOperand(MachineOperand::CreateReg(ImpUse, false, true)); + } } } } Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=60596&r1=60595&r2=60596&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Fri Dec 5 11:41:31 2008 @@ -2141,8 +2141,6 @@ // This doesn't work for several reasons. // 1. GlobalBaseReg may have been spilled. // 2. It may not be live at MI. - // 3. If this is used during register allocation / spilling, the spiller - // must know not to spill GlobalBaseReg (which is a temporary nasty hack). return false; // Create a v4i32 constant-pool entry. From alenhar2 at cs.uiuc.edu Fri Dec 5 12:33:04 2008 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Fri, 5 Dec 2008 12:33:04 -0600 Subject: [llvm-commits] CVS: llvm-www/pubs/2009-03-ASPLOS-Recovery.html index.html Message-ID: <200812051833.mB5IX4rm017157@gravity.cs.uiuc.edu> Changes in directory llvm-www/pubs: 2009-03-ASPLOS-Recovery.html added (r1.1) index.html updated: 1.85 -> 1.86 --- Log message: add ASPLOS paper --- Diffs of the changes: (+50 -0) 2009-03-ASPLOS-Recovery.html | 46 +++++++++++++++++++++++++++++++++++++++++++ index.html | 4 +++ 2 files changed, 50 insertions(+) Index: llvm-www/pubs/2009-03-ASPLOS-Recovery.html diff -c /dev/null llvm-www/pubs/2009-03-ASPLOS-Recovery.html:1.1 *** /dev/null Fri Dec 5 12:32:12 2008 --- llvm-www/pubs/2009-03-ASPLOS-Recovery.html Fri Dec 5 12:32:02 2008 *************** *** 0 **** --- 1,46 ---- + + + + + + Recovery Domains: An Organizing Principle for Recoverable Operating Systems + + + +
+ Recovery Domains: An Organizing Principle for Recoverable Operating Systems +
+
+ Andrew Lenharth, + Samuel T. King, + Vikram Adve +
+ +

Abstract:

+
+ We describe a strategy for enabling existing commodity operating + systems to recover from unexpected run-time errors in nearly any part + of the kernel, including core kernel components. Our approach is + dynamic and request-oriented, in the sense that it isolates the + effects of a fault to requests that cause a fault rather than to + static kernel components. The approach is based on a notion of + ``recovery domains,'' an organizing principle to enable partial + rollback of affected state within a request in a multithreaded system. + We have applied this approach to the Linux kernel and it required less + than 126 lines of changed or new code: the other changes are all + performed by a simple instrumentation pass of a compiler. Our + experiments show that the approach is able to recover from otherwise + fatal faults with minimal collateral impact during a recovery event. +
+ +

To Appear ASPLOS 2009

+ + +
+ Valid CSS! + Valid HTML 4.01! + + + Index: llvm-www/pubs/index.html diff -u llvm-www/pubs/index.html:1.85 llvm-www/pubs/index.html:1.86 --- llvm-www/pubs/index.html:1.85 Fri Nov 21 00:13:13 2008 +++ llvm-www/pubs/index.html Fri Dec 5 12:32:02 2008 @@ -2,6 +2,10 @@
LLVM Related Publications
    +
  1. "Recovery Domains: An Organizing +Principle for Recoverable Operating Systems"
    +Andrew Lenharth, Samuel T. King, Vikram Adve
    +Proceedings of the Fourteenth International Conference on Architectural Support for Programming Languages and Operating Systems (ASPLOS '09)
  2. "KLEE: Unassisted and Automatic Generation of High-Coverage Tests for Complex Systems Programs"
    From sabre at nondot.org Fri Dec 5 12:46:19 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 05 Dec 2008 18:46:19 -0000 Subject: [llvm-commits] [llvm] r60600 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200812051846.mB5IkJpa006073@zion.cs.uiuc.edu> Author: lattner Date: Fri Dec 5 12:46:19 2008 New Revision: 60600 URL: http://llvm.org/viewvc/llvm-project?rev=60600&view=rev Log: Make it illegal to call getDependency* on non-memory instructions like binary operators. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60600&r1=60599&r2=60600&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Fri Dec 5 12:46:19 2008 @@ -180,7 +180,8 @@ virtual void getAnalysisUsage(AnalysisUsage &AU) const; /// getDependency - Return the instruction on which a memory operation - /// depends. See the class comment for more details. + /// depends. See the class comment for more details. It is illegal to call + /// this on non-memory instructions. MemDepResult getDependency(Instruction *QueryInst); /// getDependencyFrom - Return the instruction on which the memory operation Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60600&r1=60599&r2=60600&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Fri Dec 5 12:46:19 2008 @@ -118,10 +118,11 @@ MemPtr = F->getPointerOperand(); // FreeInsts erase the entire structure, not just a field. MemSize = ~0UL; - } else if (isa(QueryInst) || isa(QueryInst)) + } else { + assert((isa(QueryInst) || isa(QueryInst)) && + "Can only get dependency info for memory instructions!"); return getCallSiteDependency(CallSite::get(QueryInst), ScanIt, BB); - else // Non-memory instructions depend on nothing. - return MemDepResult::getNone(); + } // Walk backwards through the basic block, looking for dependencies while (ScanIt != BB->begin()) { From evan.cheng at apple.com Fri Dec 5 13:26:37 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 05 Dec 2008 19:26:37 -0000 Subject: [llvm-commits] [llvm] r60601 - /llvm/trunk/test/CodeGen/X86/2008-12-05-SpillerCrash.ll Message-ID: <200812051926.mB5JQbmW007728@zion.cs.uiuc.edu> Author: evancheng Date: Fri Dec 5 13:26:37 2008 New Revision: 60601 URL: http://llvm.org/viewvc/llvm-project?rev=60601&view=rev Log: This test also requires -mattr=+sse41. Modified: llvm/trunk/test/CodeGen/X86/2008-12-05-SpillerCrash.ll Modified: llvm/trunk/test/CodeGen/X86/2008-12-05-SpillerCrash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2008-12-05-SpillerCrash.ll?rev=60601&r1=60600&r2=60601&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2008-12-05-SpillerCrash.ll (original) +++ llvm/trunk/test/CodeGen/X86/2008-12-05-SpillerCrash.ll Fri Dec 5 13:26:37 2008 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9.5 -relocation-model=pic +; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9.5 -mattr=+sse41 -relocation-model=pic %struct.XXActiveTextureTargets = type { i64, i64, i64, i64, i64, i64 } %struct.XXAlphaTest = type { float, i16, i8, i8 } From kremenek at apple.com Fri Dec 5 13:28:59 2008 From: kremenek at apple.com (Ted Kremenek) Date: Fri, 05 Dec 2008 19:28:59 -0000 Subject: [llvm-commits] [llvm] r60602 - /llvm/tags/checker/checker-131/ Message-ID: <200812051928.mB5JSxaV007816@zion.cs.uiuc.edu> Author: kremenek Date: Fri Dec 5 13:28:59 2008 New Revision: 60602 URL: http://llvm.org/viewvc/llvm-project?rev=60602&view=rev Log: Tagging checker-131. Added: llvm/tags/checker/checker-131/ - copied from r60601, llvm/trunk/ From asl at math.spbu.ru Fri Dec 5 13:38:50 2008 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Fri, 05 Dec 2008 19:38:50 -0000 Subject: [llvm-commits] [llvm] r60604 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp Message-ID: <200812051938.mB5JcotE008143@zion.cs.uiuc.edu> Author: asl Date: Fri Dec 5 13:38:49 2008 New Revision: 60604 URL: http://llvm.org/viewvc/llvm-project?rev=60604&view=rev Log: Revert invalid r60393. It causes llvm-gcc bootstrap fails in release builds. See PR3160 for details Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=60604&r1=60603&r2=60604&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Fri Dec 5 13:38:49 2008 @@ -1484,7 +1484,6 @@ if (isCriticalEdge(PREPred->getTerminator(), succNum)) { toSplit.push_back(std::make_pair(PREPred->getTerminator(), succNum)); - Changed = true; continue; } @@ -1547,14 +1546,10 @@ } for (SmallVector, 4>::iterator - I = toSplit.begin(), E = toSplit.end(); I != E; ++I) { + I = toSplit.begin(), E = toSplit.end(); I != E; ++I) SplitCriticalEdge(I->first, I->second, this); - BasicBlock* NewBlock = I->first->getSuccessor(I->second); - localAvail[NewBlock] = - new ValueNumberScope(localAvail[I->first->getParent()]); - } - return Changed; + return Changed || toSplit.size(); } // iterateOnFunction - Executes one iteration of GVN From gohman at apple.com Fri Dec 5 14:12:48 2008 From: gohman at apple.com (Dan Gohman) Date: Fri, 05 Dec 2008 20:12:48 -0000 Subject: [llvm-commits] [llvm] r60605 - /llvm/trunk/lib/System/Unix/Signals.inc Message-ID: <200812052012.mB5KCmQh009591@zion.cs.uiuc.edu> Author: djg Date: Fri Dec 5 14:12:48 2008 New Revision: 60605 URL: http://llvm.org/viewvc/llvm-project?rev=60605&view=rev Log: Demangle and pretty-print symbols in internal backtraces. Patch by Wesley Peck, with a few fixes by me. Modified: llvm/trunk/lib/System/Unix/Signals.inc Modified: llvm/trunk/lib/System/Unix/Signals.inc URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/System/Unix/Signals.inc?rev=60605&r1=60604&r2=60605&view=diff ============================================================================== --- llvm/trunk/lib/System/Unix/Signals.inc (original) +++ llvm/trunk/lib/System/Unix/Signals.inc Fri Dec 5 14:12:48 2008 @@ -25,6 +25,10 @@ #if HAVE_SYS_STAT_H #include #endif +#if HAVE_DLFCN_H && __GNUG__ +#include +#include +#endif using namespace llvm; namespace { @@ -69,8 +73,48 @@ // Use backtrace() to output a backtrace on Linux systems with glibc. int depth = backtrace(StackTrace, static_cast(array_lengthof(StackTrace))); +#if HAVE_DLFCN_H && __GNUG__ + int width = 0; + for (int i = 0; i < depth; ++i) { + Dl_info dlinfo; + dladdr(StackTrace[i], &dlinfo); + char* name = strrchr(dlinfo.dli_fname, '/'); + + int nwidth; + if (name == NULL) nwidth = strlen(dlinfo.dli_fname); + else nwidth = strlen(name) - 1; + + if (nwidth > width) width = nwidth; + } + + for (int i = 0; i < depth; ++i) { + Dl_info dlinfo; + dladdr(StackTrace[i], &dlinfo); + + fprintf(stderr, "%-3d", i); + + char* name = strrchr(dlinfo.dli_fname, '/'); + if (name == NULL) fprintf(stderr, " %-*s", width, dlinfo.dli_fname); + else fprintf(stderr, " %-*s", width, name+1); + + fprintf(stderr, " %#0*x", (int)(sizeof(void*) * 2) + 2, StackTrace[i]); + + if (dlinfo.dli_sname != NULL) { + int res; + fputc(' ', stderr); + char* d = abi::__cxa_demangle(dlinfo.dli_sname, NULL, NULL, &res); + if (d == NULL) fputs(dlinfo.dli_sname, stderr); + else fputs(d, stderr); + free(d); + + fprintf(stderr, " + %tu",(char*)StackTrace[i]-(char*)dlinfo.dli_saddr); + } + fputc('\n', stderr); + } +#else backtrace_symbols_fd(StackTrace, depth, STDERR_FILENO); #endif +#endif } // SignalHandler - The signal handler that runs... From sabre at nondot.org Fri Dec 5 14:56:18 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 05 Dec 2008 20:56:18 -0000 Subject: [llvm-commits] [test-suite] r60606 - in /test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk: csr_matvec.c relax.c Message-ID: <200812052056.mB5KuIf7010929@zion.cs.uiuc.edu> Author: lattner Date: Fri Dec 5 14:56:17 2008 New Revision: 60606 URL: http://llvm.org/viewvc/llvm-project?rev=60606&view=rev Log: remove two unnecessary headers. Modified: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/csr_matvec.c test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/relax.c Modified: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/csr_matvec.c URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/csr_matvec.c?rev=60606&r1=60605&r2=60606&view=diff ============================================================================== --- test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/csr_matvec.c (original) +++ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/csr_matvec.c Fri Dec 5 14:56:17 2008 @@ -34,7 +34,7 @@ #include "headers.h" #include -#include "omp.h" +//#include "omp.h" /*-------------------------------------------------------------------------- * hypre_CSRMatrixMatvec Modified: test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/relax.c URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/relax.c?rev=60606&r1=60605&r2=60606&view=diff ============================================================================== --- test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/relax.c (original) +++ test-suite/trunk/MultiSource/Benchmarks/ASC_Sequoia/AMGmk/relax.c Fri Dec 5 14:56:17 2008 @@ -34,7 +34,7 @@ *****************************************************************************/ #include "headers.h" -#include "omp.h" +//#include "omp.h" /*-------------------------------------------------------------------------- * hypre_BoomerAMGSeqRelax From sabre at nondot.org Fri Dec 5 15:04:20 2008 From: sabre at nondot.org (Chris Lattner) Date: Fri, 05 Dec 2008 21:04:20 -0000 Subject: [llvm-commits] [llvm] r60607 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp lib/Transforms/Scalar/DeadStoreElimination.cpp lib/Transforms/Scalar/GVN.cpp lib/Transforms/Scalar/MemCpyOptimizer.cpp Message-ID: <200812052104.mB5L4KRc011158@zion.cs.uiuc.edu> Author: lattner Date: Fri Dec 5 15:04:20 2008 New Revision: 60607 URL: http://llvm.org/viewvc/llvm-project?rev=60607&view=rev Log: Make a few major changes to memdep and its clients: 1. Merge the 'None' result into 'Normal', making loads and stores return their dependencies on allocations as Normal. 2. Split the 'Normal' result into 'Clobber' and 'Def' to distinguish between the cases when memdep knows the value is produced from when we just know if may be changed. 3. Move some of the logic for determining whether readonly calls are CSEs into memdep instead of it being in GVN. This still leaves verification that the arguments are hte same to GVN to let it know about value equivalences in different contexts. 4. Change memdep's call/call dependency analysis to use getModRefInfo(CallSite,CallSite) instead of doing something very weak. This only really matters for things like DSA, but someday maybe we'll have some other decent context sensitive analyses :) 5. This reimplements the guts of memdep to handle the new results. 6. This simplifies GVN significantly: a) readonly call CSE is slightly simpler b) I eliminated the "getDependencyFrom" chaining for load elimination and load CSE doesn't have to worry about volatile (they are always clobbers) anymore. c) GVN no longer does any 'lastLoad' caching, leaving it to memdep. 7. The logic in DSE is simplified a bit and sped up. A potentially unsafe case was eliminated. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp llvm/trunk/lib/Transforms/Scalar/GVN.cpp llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60607&r1=60606&r2=60607&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Fri Dec 5 15:04:20 2008 @@ -36,20 +36,36 @@ /// Invalid - Clients of MemDep never see this. Invalid = 0, - /// Normal - This is a normal instruction dependence. The pointer member - /// of the MemDepResult pair holds the instruction. - Normal, - + /// Clobber - This is a dependence on the specified instruction which + /// clobbers the desired value. The pointer member of the MemDepResult + /// pair holds the instruction that clobbers the memory. For example, + /// this occurs when we see a may-aliased store to the memory location we + /// care about. + Clobber, + + /// Def - This is a dependence on the specified instruction which + /// defines/produces the desired memory location. The pointer member of + /// the MemDepResult pair holds the instruction that defines the memory. + /// Cases of interest: + /// 1. This could be a load or store for dependence queries on + /// load/store. The value loaded or stored is the produced value. + /// Note that the pointer operand may be different than that of the + /// queried pointer due to must aliases and phi translation. Note + /// that the def may not be the same type as the query, the pointers + /// may just be must aliases. + /// 2. For loads and stores, this could be an allocation instruction. In + /// this case, the load is loading an undef value or a store is the + /// first store to (that part of) the allocation. + /// 3. Dependence queries on calls return Def only when they are + /// readonly calls with identical callees and no intervening + /// clobbers. No validation is done that the operands to the calls + /// are the same. + Def, + /// NonLocal - This marker indicates that the query has no dependency in /// the specified block. To find out more, the client should query other /// predecessor blocks. - NonLocal, - - /// None - This dependence type indicates that the query does not depend - /// on any instructions, either because it is not a memory instruction or - /// because it scanned to the definition of the memory (alloca/malloc) - /// being accessed. - None + NonLocal }; typedef PointerIntPair PairTy; PairTy Value; @@ -59,29 +75,29 @@ /// get methods: These are static ctor methods for creating various /// MemDepResult kinds. - static MemDepResult get(Instruction *Inst) { - return MemDepResult(PairTy(Inst, Normal)); + static MemDepResult getDef(Instruction *Inst) { + return MemDepResult(PairTy(Inst, Def)); + } + static MemDepResult getClobber(Instruction *Inst) { + return MemDepResult(PairTy(Inst, Clobber)); } static MemDepResult getNonLocal() { return MemDepResult(PairTy(0, NonLocal)); } - static MemDepResult getNone() { - return MemDepResult(PairTy(0, None)); - } - /// isNormal - Return true if this MemDepResult represents a query that is - /// a normal instruction dependency. - bool isNormal() const { return Value.getInt() == Normal; } + /// isClobber - Return true if this MemDepResult represents a query that is + /// a instruction clobber dependency. + bool isClobber() const { return Value.getInt() == Clobber; } + + /// isDef - Return true if this MemDepResult represents a query that is + /// a instruction definition dependency. + bool isDef() const { return Value.getInt() == Def; } /// isNonLocal - Return true if this MemDepResult represents an query that /// is transparent to the start of the block, but where a non-local hasn't /// been done. bool isNonLocal() const { return Value.getInt() == NonLocal; } - /// isNone - Return true if this MemDepResult represents a query that - /// doesn't depend on any instruction. - bool isNone() const { return Value.getInt() == None; } - /// getInst() - If this is a normal dependency, return the instruction that /// is depended on. Otherwise, return null. Instruction *getInst() const { return Value.getPointer(); } Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60607&r1=60606&r2=60607&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Fri Dec 5 15:04:20 2008 @@ -55,8 +55,7 @@ /// getCallSiteDependency - Private helper for finding the local dependencies /// of a call site. MemDepResult MemoryDependenceAnalysis:: -getCallSiteDependency(CallSite C, BasicBlock::iterator ScanIt, BasicBlock *BB) { - +getCallSiteDependency(CallSite CS, BasicBlock::iterator ScanIt, BasicBlock *BB) { // Walk backwards through the block, looking for dependencies while (ScanIt != BB->begin()) { Instruction *Inst = --ScanIt; @@ -76,17 +75,29 @@ // FreeInsts erase the entire structure PointerSize = ~0UL; } else if (isa(Inst) || isa(Inst)) { - if (AA->getModRefBehavior(CallSite::get(Inst)) == - AliasAnalysis::DoesNotAccessMemory) + CallSite InstCS = CallSite::get(Inst); + // If these two calls do not interfere, look past it. + if (AA->getModRefInfo(CS, InstCS) == AliasAnalysis::NoModRef) continue; - return MemDepResult::get(Inst); + + // FIXME: If this is a ref/ref result, we should ignore it! + // X = strlen(P); + // Y = strlen(Q); + // Z = strlen(P); // Z = X + + // If they interfere, we generally return clobber. However, if they are + // calls to the same read-only functions we return Def. + if (!AA->onlyReadsMemory(CS) || CS.getCalledFunction() == 0 || + CS.getCalledFunction() != InstCS.getCalledFunction()) + return MemDepResult::getClobber(Inst); + return MemDepResult::getDef(Inst); } else { // Non-memory instruction. continue; } - if (AA->getModRefInfo(C, Pointer, PointerSize) != AliasAnalysis::NoModRef) - return MemDepResult::get(Inst); + if (AA->getModRefInfo(CS, Pointer, PointerSize) != AliasAnalysis::NoModRef) + return MemDepResult::getClobber(Inst); } // No dependence found. @@ -107,10 +118,10 @@ MemPtr = S->getPointerOperand(); MemSize = TD->getTypeStoreSize(S->getOperand(0)->getType()); MemVolatile = S->isVolatile(); - } else if (LoadInst* L = dyn_cast(QueryInst)) { - MemPtr = L->getPointerOperand(); - MemSize = TD->getTypeStoreSize(L->getType()); - MemVolatile = L->isVolatile(); + } else if (LoadInst* LI = dyn_cast(QueryInst)) { + MemPtr = LI->getPointerOperand(); + MemSize = TD->getTypeStoreSize(LI->getType()); + MemVolatile = LI->isVolatile(); } else if (VAArgInst* V = dyn_cast(QueryInst)) { MemPtr = V->getOperand(0); MemSize = TD->getTypeStoreSize(V->getType()); @@ -128,34 +139,49 @@ while (ScanIt != BB->begin()) { Instruction *Inst = --ScanIt; - // If the access is volatile and this is a volatile load/store, return a - // dependence. - if (MemVolatile && - ((isa(Inst) && cast(Inst)->isVolatile()) || - (isa(Inst) && cast(Inst)->isVolatile()))) - return MemDepResult::get(Inst); - // Values depend on loads if the pointers are must aliased. This means that // a load depends on another must aliased load from the same value. - if (LoadInst *L = dyn_cast(Inst)) { - Value *Pointer = L->getPointerOperand(); - uint64_t PointerSize = TD->getTypeStoreSize(L->getType()); + if (LoadInst *LI = dyn_cast(Inst)) { + // If the access is volatile and this is volatile, return a dependence. + if (MemVolatile && LI->isVolatile()) + return MemDepResult::getClobber(LI); + + Value *Pointer = LI->getPointerOperand(); + uint64_t PointerSize = TD->getTypeStoreSize(LI->getType()); - // If we found a pointer, check if it could be the same as our pointer + // If we found a pointer, check if it could be the same as our pointer. AliasAnalysis::AliasResult R = AA->alias(Pointer, PointerSize, MemPtr, MemSize); - if (R == AliasAnalysis::NoAlias) continue; // May-alias loads don't depend on each other without a dependence. if (isa(QueryInst) && R == AliasAnalysis::MayAlias) continue; - return MemDepResult::get(Inst); + return MemDepResult::getDef(Inst); + } + + if (StoreInst *SI = dyn_cast(Inst)) { + // If the access is volatile and this is volatile, return a dependence. + if (MemVolatile && SI->isVolatile()) + return MemDepResult::getClobber(SI); + + Value *Pointer = SI->getPointerOperand(); + uint64_t PointerSize = TD->getTypeStoreSize(SI->getOperand(0)->getType()); + + // If we found a pointer, check if it could be the same as our pointer. + AliasAnalysis::AliasResult R = + AA->alias(Pointer, PointerSize, MemPtr, MemSize); + + if (R == AliasAnalysis::NoAlias) + continue; + if (R == AliasAnalysis::MayAlias) + return MemDepResult::getClobber(Inst); + return MemDepResult::getDef(Inst); } // If this is an allocation, and if we know that the accessed pointer is to - // the allocation, return None. This means that there is no dependence and + // the allocation, return Def. This means that there is no dependence and // the access can be optimized based on that. For example, a load could // turn into undef. if (AllocationInst *AI = dyn_cast(Inst)) { @@ -163,22 +189,16 @@ if (AccessPtr == AI || AA->alias(AI, 1, AccessPtr, 1) == AliasAnalysis::MustAlias) - return MemDepResult::getNone(); + return MemDepResult::getDef(AI); continue; } - // See if this instruction mod/ref's the pointer. - AliasAnalysis::ModRefResult MRR = AA->getModRefInfo(Inst, MemPtr, MemSize); - - if (MRR == AliasAnalysis::NoModRef) - continue; - - // Loads don't depend on read-only instructions. - if (isa(QueryInst) && MRR == AliasAnalysis::Ref) + // See if this instruction (e.g. a call or vaarg) mod/ref's the pointer. + if (AA->getModRefInfo(Inst, MemPtr, MemSize) == AliasAnalysis::NoModRef) continue; // Otherwise, there is a dependence. - return MemDepResult::get(Inst); + return MemDepResult::getClobber(Inst); } // If we found nothing, return the non-local flag. Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=60607&r1=60606&r2=60607&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Fri Dec 5 15:04:20 2008 @@ -148,25 +148,27 @@ // If we're storing the same value back to a pointer that we just // loaded from, then the store can be removed; if (LoadInst* L = dyn_cast(S->getOperand(0))) { - // FIXME: Don't do dep query if Parents don't match and other stuff! - MemDepResult dep = MD.getDependency(S); - DominatorTree& DT = getAnalysis(); - if (!S->isVolatile() && S->getParent() == L->getParent() && - S->getPointerOperand() == L->getPointerOperand() && - (!dep.isNormal() || DT.dominates(dep.getInst(), L))) { - - DeleteDeadInstruction(S); - if (BBI != BB.begin()) - --BBI; - NumFastStores++; - MadeChange = true; - } else + S->getPointerOperand() == L->getPointerOperand()) { + MemDepResult dep = MD.getDependency(S); + if (dep.isDef() && dep.getInst() == L) { + DeleteDeadInstruction(S); + if (BBI != BB.begin()) + --BBI; + NumFastStores++; + MadeChange = true; + } else { + // Update our most-recent-store map. + last = S; + } + } else { // Update our most-recent-store map. last = S; - } else + } + } else { // Update our most-recent-store map. last = S; + } } } Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=60607&r1=60606&r2=60607&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Fri Dec 5 15:04:20 2008 @@ -461,30 +461,19 @@ MemDepResult local_dep = MD->getDependency(C); - if (local_dep.isNone()) { + if (!local_dep.isDef() && !local_dep.isNonLocal()) { valueNumbering.insert(std::make_pair(V, nextValueNumber)); return nextValueNumber++; } - - if (Instruction *LocalDepInst = local_dep.getInst()) { - if (!isa(LocalDepInst)) { - valueNumbering.insert(std::make_pair(V, nextValueNumber)); - return nextValueNumber++; - } - - CallInst* local_cdep = cast(LocalDepInst); - - if (local_cdep->getCalledFunction() != C->getCalledFunction() || - local_cdep->getNumOperands() != C->getNumOperands()) { - valueNumbering.insert(std::make_pair(V, nextValueNumber)); - return nextValueNumber++; - } + + if (local_dep.isDef()) { + CallInst* local_cdep = cast(local_dep.getInst()); - if (!C->getCalledFunction()) { + if (local_cdep->getNumOperands() != C->getNumOperands()) { valueNumbering.insert(std::make_pair(V, nextValueNumber)); return nextValueNumber++; } - + for (unsigned i = 1; i < C->getNumOperands(); ++i) { uint32_t c_vn = lookup_or_add(C->getOperand(i)); uint32_t cd_vn = lookup_or_add(local_cdep->getOperand(i)); @@ -498,10 +487,12 @@ valueNumbering.insert(std::make_pair(V, v)); return v; } - + // Non-local case. const MemoryDependenceAnalysis::NonLocalDepInfo &deps = MD->getNonLocalDependency(C); + // FIXME: call/call dependencies for readonly calls should return def, not + // clobber! Move the checking logic to MemDep! CallInst* cdep = 0; // Check to see if we have a single dominating call instruction that is @@ -514,7 +505,7 @@ // We don't handle non-depedencies. If we already have a call, reject // instruction dependencies. - if (I->second.isNone() || cdep != 0) { + if (I->second.isClobber() || cdep != 0) { cdep = 0; break; } @@ -535,12 +526,7 @@ return nextValueNumber++; } - if (cdep->getCalledFunction() != C->getCalledFunction() || - cdep->getNumOperands() != C->getNumOperands()) { - valueNumbering.insert(std::make_pair(V, nextValueNumber)); - return nextValueNumber++; - } - if (!C->getCalledFunction()) { + if (cdep->getNumOperands() != C->getNumOperands()) { valueNumbering.insert(std::make_pair(V, nextValueNumber)); return nextValueNumber++; } @@ -736,10 +722,8 @@ // Helper fuctions // FIXME: eliminate or document these better bool processLoad(LoadInst* L, - DenseMap &lastLoad, SmallVectorImpl &toErase); bool processInstruction(Instruction* I, - DenseMap& lastSeenLoad, SmallVectorImpl &toErase); bool processNonLocalLoad(LoadInst* L, SmallVectorImpl &toErase); @@ -979,7 +963,15 @@ continue; } - if (DepInfo.isNone()) { + if (DepInfo.isClobber()) { + UnavailableBlocks.push_back(DepBB); + continue; + } + + Instruction *DepInst = DepInfo.getInst(); + + // Loading the allocation -> undef. + if (isa(DepInst)) { ValuesPerBlock.push_back(std::make_pair(DepBB, UndefValue::get(LI->getType()))); continue; @@ -996,13 +988,6 @@ continue; } - if (S->getPointerOperand() != LI->getPointerOperand() && - VN.getAliasAnalysis()->alias(S->getPointerOperand(), 1, - LI->getPointerOperand(), 1) - != AliasAnalysis::MustAlias) { - UnavailableBlocks.push_back(DepBB); - continue; - } ValuesPerBlock.push_back(std::make_pair(DepBB, S->getOperand(0))); } else if (LoadInst* LD = dyn_cast(DepInfo.getInst())) { @@ -1010,14 +995,6 @@ UnavailableBlocks.push_back(DepBB); continue; } - - if (LD->getPointerOperand() != LI->getPointerOperand() && - VN.getAliasAnalysis()->alias(LD->getPointerOperand(), 1, - LI->getPointerOperand(), 1) - != AliasAnalysis::MustAlias) { - UnavailableBlocks.push_back(DepBB); - continue; - } ValuesPerBlock.push_back(std::make_pair(DepBB, LD)); } else { UnavailableBlocks.push_back(DepBB); @@ -1156,84 +1133,64 @@ /// processLoad - Attempt to eliminate a load, first by eliminating it /// locally, and then attempting non-local elimination if that fails. -bool GVN::processLoad(LoadInst *L, DenseMap &lastLoad, - SmallVectorImpl &toErase) { - if (L->isVolatile()) { - lastLoad[L->getPointerOperand()] = L; +bool GVN::processLoad(LoadInst *L, SmallVectorImpl &toErase) { + if (L->isVolatile()) return false; - } Value* pointer = L->getPointerOperand(); - LoadInst*& last = lastLoad[pointer]; - + // ... to a pointer that has been loaded from before... - bool removedNonLocal = false; MemDepResult dep = MD->getDependency(L); - if (dep.isNonLocal() && - L->getParent() != &L->getParent()->getParent()->getEntryBlock()) { - removedNonLocal = processNonLocalLoad(L, toErase); + + // If the value isn't available, don't do anything! + if (dep.isClobber()) + return false; + + // If it is defined in another block, try harder. + if (dep.isNonLocal()) { + if (L->getParent() == &L->getParent()->getParent()->getEntryBlock()) + return false; + return processNonLocalLoad(L, toErase); + } + + Instruction *DepInst = dep.getInst(); + if (StoreInst *DepSI = dyn_cast(DepInst)) { + // Only forward substitute stores to loads of the same type. + // FIXME: Could do better! + if (DepSI->getPointerOperand()->getType() != pointer->getType()) + return false; - if (!removedNonLocal) - last = L; + // Remove it! + L->replaceAllUsesWith(DepSI->getOperand(0)); + toErase.push_back(L); + NumGVNLoad++; + return true; + } + + if (LoadInst *DepLI = dyn_cast(DepInst)) { + // Only forward substitute stores to loads of the same type. + // FIXME: Could do better! load i32 -> load i8 -> truncate on little endian. + if (DepLI->getType() != L->getType()) + return false; - return removedNonLocal; + // Remove it! + L->replaceAllUsesWith(DepLI); + toErase.push_back(L); + NumGVNLoad++; + return true; } - - bool deletedLoad = false; - - // Walk up the dependency chain until we either find - // a dependency we can use, or we can't walk any further - while (Instruction *DepInst = dep.getInst()) { - // ... that depends on a store ... - if (StoreInst* S = dyn_cast(DepInst)) { - if (S->getPointerOperand() == pointer) { - // Remove it! - L->replaceAllUsesWith(S->getOperand(0)); - toErase.push_back(L); - deletedLoad = true; - NumGVNLoad++; - } - - // Whether we removed it or not, we can't - // go any further - break; - } else if (!isa(DepInst)) { - // Only want to handle loads below. - break; - } else if (!last) { - // If we don't depend on a store, and we haven't - // been loaded before, bail. - break; - } else if (DepInst == last) { - // Remove it! - L->replaceAllUsesWith(last); - toErase.push_back(L); - deletedLoad = true; - NumGVNLoad++; - break; - } else { - dep = MD->getDependencyFrom(L, DepInst, DepInst->getParent()); - } - } - // If this load really doesn't depend on anything, then we must be loading an // undef value. This can happen when loading for a fresh allocation with no // intervening stores, for example. - if (dep.isNone()) { - // If this load depends directly on an allocation, there isn't - // anything stored there; therefore, we can optimize this load - // to undef. + if (isa(DepInst)) { L->replaceAllUsesWith(UndefValue::get(L->getType())); toErase.push_back(L); - deletedLoad = true; NumGVNLoad++; + return true; } - if (!deletedLoad) - last = L; - - return deletedLoad; + return false; } Value* GVN::lookupNumber(BasicBlock* BB, uint32_t num) { @@ -1257,10 +1214,9 @@ /// processInstruction - When calculating availability, handle an instruction /// by inserting it into the appropriate sets bool GVN::processInstruction(Instruction *I, - DenseMap &lastSeenLoad, SmallVectorImpl &toErase) { if (LoadInst* L = dyn_cast(I)) { - bool changed = processLoad(L, lastSeenLoad, toErase); + bool changed = processLoad(L, toErase); if (!changed) { unsigned num = VN.lookup_or_add(L); @@ -1362,7 +1318,6 @@ bool GVN::processBlock(DomTreeNode* DTN) { BasicBlock* BB = DTN->getBlock(); SmallVector toErase; - DenseMap lastSeenLoad; bool changed_function = false; if (DTN->getIDom()) @@ -1373,7 +1328,7 @@ for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) { - changed_function |= processInstruction(BI, lastSeenLoad, toErase); + changed_function |= processInstruction(BI, toErase); if (toErase.empty()) { ++BI; continue; Modified: llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp?rev=60607&r1=60606&r2=60607&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp Fri Dec 5 15:04:20 2008 @@ -630,13 +630,12 @@ // a) memcpy-memcpy xform which exposes redundance for DSE // b) call-memcpy xform for return slot optimization MemDepResult dep = MD.getDependency(M); - if (!dep.isNormal()) + if (!dep.isClobber()) return false; - else if (!isa(dep.getInst())) { + if (!isa(dep.getInst())) { if (CallInst* C = dyn_cast(dep.getInst())) return performCallSlotOptzn(M, C); - else - return false; + return false; } MemCpyInst* MDep = cast(dep.getInst()); From clattner at apple.com Fri Dec 5 15:22:55 2008 From: clattner at apple.com (Chris Lattner) Date: Fri, 5 Dec 2008 13:22:55 -0800 Subject: [llvm-commits] [llvm] r60607 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp lib/Transforms/Scalar/DeadStoreElimination.cpp lib/Transforms/Scalar/GVN.cpp lib/Transforms/Scalar/MemCpyOptimizer.cpp In-Reply-To: <200812052104.mB5L4KRc011158@zion.cs.uiuc.edu> References: <200812052104.mB5L4KRc011158@zion.cs.uiuc.edu> Message-ID: <8A2FBD51-D6F3-4E53-AFA9-05190D60BA8B@apple.com> On Dec 5, 2008, at 1:04 PM, Chris Lattner wrote: > Author: lattner > Date: Fri Dec 5 15:04:20 2008 > New Revision: 60607 > > URL: http://llvm.org/viewvc/llvm-project?rev=60607&view=rev > Log: > Make a few major changes to memdep and its clients: Oh yeah, this speeds up GVN by 10% on 403.gcc. -Chris From dalej at apple.com Fri Dec 5 15:47:28 2008 From: dalej at apple.com (Dale Johannesen) Date: Fri, 05 Dec 2008 21:47:28 -0000 Subject: [llvm-commits] [llvm] r60608 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86Subtarget.cpp lib/Transforms/Scalar/LoopStrengthReduce.cpp test/CodeGen/X86/loop-strength-reduce-2.ll test/CodeGen/X86/loop-strength-reduce-3.ll test/CodeGen/X86/loop-strength-reduce.ll Message-ID: <200812052147.mB5LlSeH012488@zion.cs.uiuc.edu> Author: johannes Date: Fri Dec 5 15:47:27 2008 New Revision: 60608 URL: http://llvm.org/viewvc/llvm-project?rev=60608&view=rev Log: Make LoopStrengthReduce smarter about hoisting things out of loops when they can be subsumed into addressing modes. Change X86 addressing mode check to realize that some PIC references need an extra register. (I believe this is correct for Linux, if not, I'm sure someone will tell me.) Added: llvm/trunk/test/CodeGen/X86/loop-strength-reduce-2.ll llvm/trunk/test/CodeGen/X86/loop-strength-reduce-3.ll Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86Subtarget.cpp llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp llvm/trunk/test/CodeGen/X86/loop-strength-reduce.ll Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=60608&r1=60607&r2=60608&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Dec 5 15:47:27 2008 @@ -6463,6 +6463,10 @@ // We can only fold this if we don't need an extra load. if (Subtarget->GVRequiresExtraLoad(AM.BaseGV, getTargetMachine(), false)) return false; + // If BaseGV requires a register, we cannot also have a BaseReg. + if (Subtarget->GVRequiresRegister(AM.BaseGV, getTargetMachine(), false) && + AM.HasBaseReg) + return false; // X86-64 only supports addr of globals in small code model. if (Subtarget->is64Bit()) { Modified: llvm/trunk/lib/Target/X86/X86Subtarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.cpp?rev=60608&r1=60607&r2=60608&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Subtarget.cpp (original) +++ llvm/trunk/lib/Target/X86/X86Subtarget.cpp Fri Dec 5 15:47:27 2008 @@ -59,7 +59,23 @@ return (GV->hasDLLImportLinkage()); } } - + return false; +} + +/// True if accessing the GV requires a register. This is a superset of the +/// cases where GVRequiresExtraLoad is true. Some variations of PIC require +/// a register, but not an extra load. +bool X86Subtarget::GVRequiresRegister(const GlobalValue *GV, + const TargetMachine& TM, + bool isDirectCall) const +{ + if (GVRequiresExtraLoad(GV, TM, isDirectCall)) + return true; + // Code below here need only consider cases where GVRequiresExtraLoad + // returns false. + if (TM.getRelocationModel() == Reloc::PIC_) + return !isDirectCall && + (GV->hasInternalLinkage() || GV->hasExternalLinkage()); return false; } Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=60608&r1=60607&r2=60608&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Fri Dec 5 15:47:27 2008 @@ -444,7 +444,33 @@ return true; } - +/// isAddress - Returns true if the specified instruction is using the +/// specified value as an address. +static bool isAddressUse(Instruction *Inst, Value *OperandVal) { + bool isAddress = isa(Inst); + if (StoreInst *SI = dyn_cast(Inst)) { + if (SI->getOperand(1) == OperandVal) + isAddress = true; + } else if (IntrinsicInst *II = dyn_cast(Inst)) { + // Addressing modes can also be folded into prefetches and a variety + // of intrinsics. + switch (II->getIntrinsicID()) { + default: break; + case Intrinsic::prefetch: + case Intrinsic::x86_sse2_loadu_dq: + case Intrinsic::x86_sse2_loadu_pd: + case Intrinsic::x86_sse_loadu_ps: + case Intrinsic::x86_sse_storeu_ps: + case Intrinsic::x86_sse2_storeu_pd: + case Intrinsic::x86_sse2_storeu_dq: + case Intrinsic::x86_sse2_storel_dq: + if (II->getOperand(1) == OperandVal) + isAddress = true; + break; + } + } + return isAddress; +} /// AddUsersIfInteresting - Inspect the specified instruction. If it is a /// reducible SCEV, recursively add its users to the IVUsesByStride set and @@ -731,15 +757,16 @@ } -/// isTargetConstant - Return true if the following can be referenced by the -/// immediate field of a target instruction. -static bool isTargetConstant(const SCEVHandle &V, const Type *UseTy, - const TargetLowering *TLI) { +/// fitsInAddressMode - Return true if V can be subsumed within an addressing +/// mode, and does not need to be put in a register first. +static bool fitsInAddressMode(const SCEVHandle &V, const Type *UseTy, + const TargetLowering *TLI, bool HasBaseReg) { if (SCEVConstant *SC = dyn_cast(V)) { int64_t VC = SC->getValue()->getSExtValue(); if (TLI) { TargetLowering::AddrMode AM; AM.BaseOffs = VC; + AM.HasBaseReg = HasBaseReg; return TLI->isLegalAddressingMode(AM, UseTy); } else { // Defaults to PPC. PPC allows a sign-extended 16-bit immediate field. @@ -754,6 +781,7 @@ if (GlobalValue *GV = dyn_cast(Op0)) { TargetLowering::AddrMode AM; AM.BaseGV = GV; + AM.HasBaseReg = HasBaseReg; return TLI->isLegalAddressingMode(AM, UseTy); } } @@ -846,7 +874,7 @@ return; } else if (SCEVMulExpr *SME = dyn_cast(Val)) { // Transform "8 * (4 + v)" -> "32 + 8*V" if "32" fits in the immed field. - if (isAddress && isTargetConstant(SME->getOperand(0), UseTy, TLI) && + if (isAddress && fitsInAddressMode(SME->getOperand(0), UseTy, TLI, false) && SME->getNumOperands() == 2 && SME->isLoopInvariant(L)) { SCEVHandle SubImm = SE->getIntegerSCEV(0, Val->getType()); @@ -859,7 +887,7 @@ // Scale SubImm up by "8". If the result is a target constant, we are // good. SubImm = SE->getMulExpr(SubImm, SME->getOperand(0)); - if (isTargetConstant(SubImm, UseTy, TLI)) { + if (fitsInAddressMode(SubImm, UseTy, TLI, false)) { // Accumulate the immediate. Imm = SE->getAddExpr(Imm, SubImm); @@ -873,7 +901,7 @@ // Loop-variant expressions must stay in the immediate field of the // expression. - if ((isAddress && isTargetConstant(Val, UseTy, TLI)) || + if ((isAddress && fitsInAddressMode(Val, UseTy, TLI, false)) || !Val->isLoopInvariant(L)) { Imm = SE->getAddExpr(Imm, Val); Val = SE->getIntegerSCEV(0, Val->getType()); @@ -912,21 +940,28 @@ } } - -/// RemoveCommonExpressionsFromUseBases - Look through all of the uses in Bases, -/// removing any common subexpressions from it. Anything truly common is -/// removed, accumulated, and returned. This looks for things like (a+b+c) and +// This is logically local to the following function, but C++ says we have +// to make it file scope. +struct SubExprUseData { unsigned Count; bool notAllUsesAreFree; }; + +/// RemoveCommonExpressionsFromUseBases - Look through all of the Bases of all +/// the Uses, removing any common subexpressions, except that if all such +/// subexpressions can be folded into an addressing mode for all uses inside +/// the loop (this case is referred to as "free" in comments herein) we do +/// not remove anything. This looks for things like (a+b+c) and /// (a+c+d) and computes the common (a+c) subexpression. The common expression /// is *removed* from the Bases and returned. static SCEVHandle RemoveCommonExpressionsFromUseBases(std::vector &Uses, - ScalarEvolution *SE, Loop *L) { + ScalarEvolution *SE, Loop *L, + const TargetLowering *TLI) { unsigned NumUses = Uses.size(); // Only one use? This is a very common case, so we handle it specially and // cheaply. SCEVHandle Zero = SE->getIntegerSCEV(0, Uses[0].Base->getType()); SCEVHandle Result = Zero; + SCEVHandle FreeResult = Zero; if (NumUses == 1) { // If the use is inside the loop, use its base, regardless of what it is: // it is clearly shared across all the IV's. If the use is outside the loop @@ -939,7 +974,10 @@ // To find common subexpressions, count how many of Uses use each expression. // If any subexpressions are used Uses.size() times, they are common. - std::map SubExpressionUseCounts; + // Also track whether all uses of each expression can be moved into an + // an addressing mode "for free"; such expressions are left within the loop. + // struct SubExprUseData { unsigned Count; bool notAllUsesAreFree; }; + std::map SubExpressionUseData; // UniqueSubExprs - Keep track of all of the subexpressions we see in the // order we see them. @@ -962,31 +1000,89 @@ // CSEs we can find. if (Uses[i].Base == Zero) return Zero; + // If this use is as an address we may be able to put CSEs in the addressing + // mode rather than hoisting them. + bool isAddrUse = isAddressUse(Uses[i].Inst, Uses[i].OperandValToReplace); + // We may need the UseTy below, but only when isAddrUse, so compute it + // only in that case. + const Type *UseTy = 0; + if (isAddrUse) { + UseTy = Uses[i].Inst->getType(); + if (StoreInst *SI = dyn_cast(Uses[i].Inst)) + UseTy = SI->getOperand(0)->getType(); + } + // Split the expression into subexprs. SeparateSubExprs(SubExprs, Uses[i].Base, SE); - // Add one to SubExpressionUseCounts for each subexpr present. - for (unsigned j = 0, e = SubExprs.size(); j != e; ++j) - if (++SubExpressionUseCounts[SubExprs[j]] == 1) + // Add one to SubExpressionUseData.Count for each subexpr present, and + // if the subexpr is not a valid immediate within an addressing mode use, + // set SubExpressionUseData.notAllUsesAreFree. We definitely want to + // hoist these out of the loop (if they are common to all uses). + for (unsigned j = 0, e = SubExprs.size(); j != e; ++j) { + if (++SubExpressionUseData[SubExprs[j]].Count == 1) UniqueSubExprs.push_back(SubExprs[j]); + if (!isAddrUse || !fitsInAddressMode(SubExprs[j], UseTy, TLI, false)) + SubExpressionUseData[SubExprs[j]].notAllUsesAreFree = true; + } SubExprs.clear(); } // Now that we know how many times each is used, build Result. Iterate over // UniqueSubexprs so that we have a stable ordering. for (unsigned i = 0, e = UniqueSubExprs.size(); i != e; ++i) { - std::map::iterator I = - SubExpressionUseCounts.find(UniqueSubExprs[i]); - assert(I != SubExpressionUseCounts.end() && "Entry not found?"); - if (I->second == NumUsesInsideLoop) // Found CSE! - Result = SE->getAddExpr(Result, I->first); - else - // Remove non-cse's from SubExpressionUseCounts. - SubExpressionUseCounts.erase(I); + std::map::iterator I = + SubExpressionUseData.find(UniqueSubExprs[i]); + assert(I != SubExpressionUseData.end() && "Entry not found?"); + if (I->second.Count == NumUsesInsideLoop) { // Found CSE! + if (I->second.notAllUsesAreFree) + Result = SE->getAddExpr(Result, I->first); + else + FreeResult = SE->getAddExpr(FreeResult, I->first); + } else + // Remove non-cse's from SubExpressionUseData. + SubExpressionUseData.erase(I); + } + + if (FreeResult != Zero) { + // We have some subexpressions that can be subsumed into addressing + // modes in every use inside the loop. However, it's possible that + // there are so many of them that the combined FreeResult cannot + // be subsumed, or that the target cannot handle both a FreeResult + // and a Result in the same instruction (for example because it would + // require too many registers). Check this. + for (unsigned i=0; icontains(Uses[i].Inst->getParent())) + continue; + // We know this is an addressing mode use; if there are any uses that + // are not, FreeResult would be Zero. + const Type *UseTy = Uses[i].Inst->getType(); + if (StoreInst *SI = dyn_cast(Uses[i].Inst)) + UseTy = SI->getOperand(0)->getType(); + if (!fitsInAddressMode(FreeResult, UseTy, TLI, Result!=Zero)) { + // FIXME: could split up FreeResult into pieces here, some hoisted + // and some not. Doesn't seem worth it for now. + Result = SE->getAddExpr(Result, FreeResult); + FreeResult = Zero; + break; + } + } } - + // If we found no CSE's, return now. if (Result == Zero) return Result; + // If we still have a FreeResult, remove its subexpressions from + // SubExpressionUseData. This means they will remain in the use Bases. + if (FreeResult != Zero) { + SeparateSubExprs(SubExprs, FreeResult, SE); + for (unsigned j = 0, e = SubExprs.size(); j != e; ++j) { + std::map::iterator I = + SubExpressionUseData.find(SubExprs[j]); + SubExpressionUseData.erase(I); + } + SubExprs.clear(); + } + // Otherwise, remove all of the CSE's we found from each of the base values. for (unsigned i = 0; i != NumUses; ++i) { // Uses outside the loop don't necessarily include the common base, but @@ -1003,7 +1099,7 @@ // Remove any common subexpressions. for (unsigned j = 0, e = SubExprs.size(); j != e; ++j) - if (SubExpressionUseCounts.count(SubExprs[j])) { + if (SubExpressionUseData.count(SubExprs[j])) { SubExprs.erase(SubExprs.begin()+j); --j; --e; } @@ -1131,34 +1227,6 @@ return SC->getValue()->getValue().isNegative(); } -/// isAddress - Returns true if the specified instruction is using the -/// specified value as an address. -static bool isAddressUse(Instruction *Inst, Value *OperandVal) { - bool isAddress = isa(Inst); - if (StoreInst *SI = dyn_cast(Inst)) { - if (SI->getOperand(1) == OperandVal) - isAddress = true; - } else if (IntrinsicInst *II = dyn_cast(Inst)) { - // Addressing modes can also be folded into prefetches and a variety - // of intrinsics. - switch (II->getIntrinsicID()) { - default: break; - case Intrinsic::prefetch: - case Intrinsic::x86_sse2_loadu_dq: - case Intrinsic::x86_sse2_loadu_pd: - case Intrinsic::x86_sse_loadu_ps: - case Intrinsic::x86_sse_storeu_ps: - case Intrinsic::x86_sse2_storeu_pd: - case Intrinsic::x86_sse2_storeu_dq: - case Intrinsic::x86_sse2_storel_dq: - if (II->getOperand(1) == OperandVal) - isAddress = true; - break; - } - } - return isAddress; -} - // CollectIVUsers - Transform our list of users and offsets to a bit more // complex table. In this new vector, each 'BasedUser' contains 'Base', the base // of the strided accesses, as well as the old information from Uses. We @@ -1190,7 +1258,7 @@ // "A+B"), emit it to the preheader, then remove the expression from the // UsersToProcess base values. SCEVHandle CommonExprs = - RemoveCommonExpressionsFromUseBases(UsersToProcess, SE, L); + RemoveCommonExpressionsFromUseBases(UsersToProcess, SE, L, TLI); // Next, figure out what we can represent in the immediate fields of // instructions. If we can represent anything there, move it to the imm @@ -1347,7 +1415,8 @@ Constant *C = dyn_cast(CommonBaseV); if (!C || (!C->isNullValue() && - !isTargetConstant(SE->getUnknown(CommonBaseV), ReplacedTy, TLI))) + !fitsInAddressMode(SE->getUnknown(CommonBaseV), ReplacedTy, + TLI, false))) // We want the common base emitted into the preheader! This is just // using cast as a copy so BitCast (no-op cast) is appropriate CommonBaseV = new BitCastInst(CommonBaseV, CommonBaseV->getType(), @@ -1403,7 +1472,8 @@ // this by forcing a BitCast (noop cast) to be inserted into the preheader // in this case. if (Constant *C = dyn_cast(BaseV)) { - if (!C->isNullValue() && !isTargetConstant(Base, ReplacedTy, TLI)) { + if (!C->isNullValue() && !fitsInAddressMode(Base, ReplacedTy, + TLI, false)) { // We want this constant emitted into the preheader! This is just // using cast as a copy so BitCast (no-op cast) is appropriate BaseV = new BitCastInst(BaseV, BaseV->getType(), "preheaderinsert", Added: llvm/trunk/test/CodeGen/X86/loop-strength-reduce-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/loop-strength-reduce-2.ll?rev=60608&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/loop-strength-reduce-2.ll (added) +++ llvm/trunk/test/CodeGen/X86/loop-strength-reduce-2.ll Fri Dec 5 15:47:27 2008 @@ -0,0 +1,30 @@ +; RUN: llvm-as < %s | llc -march=x86 -relocation-model=pic | \ +; RUN: grep {A-} | count 1 +; +; Make sure the common loop invariant A is hoisted up to preheader, +; since too many registers are needed to subsume it into the addressing modes. + + at A = global [16 x [16 x i32]] zeroinitializer, align 32 ; <[16 x [16 x i32]]*> [#uses=2] + +define void @test(i32 %row, i32 %N.in) nounwind { +entry: + %N = bitcast i32 %N.in to i32 ; [#uses=1] + %tmp5 = icmp sgt i32 %N.in, 0 ; [#uses=1] + br i1 %tmp5, label %cond_true, label %return + +cond_true: ; preds = %cond_true, %entry + %indvar = phi i32 [ 0, %entry ], [ %indvar.next, %cond_true ] ; [#uses=2] + %i.0.0 = bitcast i32 %indvar to i32 ; [#uses=2] + %tmp2 = add i32 %i.0.0, 1 ; [#uses=1] + %tmp = getelementptr [16 x [16 x i32]]* @A, i32 0, i32 %row, i32 %tmp2 ; [#uses=1] + store i32 4, i32* %tmp + %tmp5.upgrd.1 = add i32 %i.0.0, 2 ; [#uses=1] + %tmp7 = getelementptr [16 x [16 x i32]]* @A, i32 0, i32 %row, i32 %tmp5.upgrd.1 ; [#uses=1] + store i32 5, i32* %tmp7 + %indvar.next = add i32 %indvar, 1 ; [#uses=2] + %exitcond = icmp eq i32 %indvar.next, %N ; [#uses=1] + br i1 %exitcond, label %return, label %cond_true + +return: ; preds = %cond_true, %entry + ret void +} Added: llvm/trunk/test/CodeGen/X86/loop-strength-reduce-3.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/loop-strength-reduce-3.ll?rev=60608&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/loop-strength-reduce-3.ll (added) +++ llvm/trunk/test/CodeGen/X86/loop-strength-reduce-3.ll Fri Dec 5 15:47:27 2008 @@ -0,0 +1,30 @@ +; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin -relocation-model=dynamic-no-pic | \ +; RUN: grep {A+} | count 2 +; +; Make sure the common loop invariant A is not hoisted up to preheader, +; since it can be subsumed it into the addressing modes. + + at A = global [16 x [16 x i32]] zeroinitializer, align 32 ; <[16 x [16 x i32]]*> [#uses=2] + +define void @test(i32 %row, i32 %N.in) nounwind { +entry: + %N = bitcast i32 %N.in to i32 ; [#uses=1] + %tmp5 = icmp sgt i32 %N.in, 0 ; [#uses=1] + br i1 %tmp5, label %cond_true, label %return + +cond_true: ; preds = %cond_true, %entry + %indvar = phi i32 [ 0, %entry ], [ %indvar.next, %cond_true ] ; [#uses=2] + %i.0.0 = bitcast i32 %indvar to i32 ; [#uses=2] + %tmp2 = add i32 %i.0.0, 1 ; [#uses=1] + %tmp = getelementptr [16 x [16 x i32]]* @A, i32 0, i32 %row, i32 %tmp2 ; [#uses=1] + store i32 4, i32* %tmp + %tmp5.upgrd.1 = add i32 %i.0.0, 2 ; [#uses=1] + %tmp7 = getelementptr [16 x [16 x i32]]* @A, i32 0, i32 %row, i32 %tmp5.upgrd.1 ; [#uses=1] + store i32 5, i32* %tmp7 + %indvar.next = add i32 %indvar, 1 ; [#uses=2] + %exitcond = icmp eq i32 %indvar.next, %N ; [#uses=1] + br i1 %exitcond, label %return, label %cond_true + +return: ; preds = %cond_true, %entry + ret void +} Modified: llvm/trunk/test/CodeGen/X86/loop-strength-reduce.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/loop-strength-reduce.ll?rev=60608&r1=60607&r2=60608&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/loop-strength-reduce.ll (original) +++ llvm/trunk/test/CodeGen/X86/loop-strength-reduce.ll Fri Dec 5 15:47:27 2008 @@ -1,7 +1,8 @@ -; RUN: llvm-as < %s | llc -march=x86 | \ -; RUN: grep {A(} | count 1 +; RUN: llvm-as < %s | llc -march=x86 -relocation-model=static | \ +; RUN: grep {A+} | count 2 ; -; Make sure the common loop invariant _A(reg) is hoisted up to preheader. +; Make sure the common loop invariant A is not hoisted up to preheader, +; since it can be subsumed into the addressing mode in all uses. @A = internal global [16 x [16 x i32]] zeroinitializer, align 32 ; <[16 x [16 x i32]]*> [#uses=2] From tonic at nondot.org Fri Dec 5 15:49:51 2008 From: tonic at nondot.org (Tanya Lattner) Date: Fri, 5 Dec 2008 15:49:51 -0600 Subject: [llvm-commits] CVS: llvm-www/www-index.html Message-ID: <200812052149.mB5Lnp6p012566@zion.cs.uiuc.edu> Changes in directory llvm-www: www-index.html updated: 1.169 -> 1.170 --- Log message: Add 2.5 release schedule. --- Diffs of the changes: (+10 -1) www-index.html | 11 ++++++++++- 1 files changed, 10 insertions(+), 1 deletion(-) Index: llvm-www/www-index.html diff -u llvm-www/www-index.html:1.169 llvm-www/www-index.html:1.170 --- llvm-www/www-index.html:1.169 Mon Nov 10 00:52:19 2008 +++ llvm-www/www-index.html Fri Dec 5 15:49:13 2008 @@ -106,7 +106,16 @@

    LLVM 2.5 release schedule:

    -

    Roughly February or March, stay tuned for details.

    +

    +

      +
    • Jan 21 - Code Freeze/Branch Creation (9PM PST).
    • +
    • Jan 25 - Pre-release 1 testing begins.
    • +
    • Feb 1 - Pre-release 1 testing ends.
    • +
    • Feb 2 - Pre-release 2 testing begins.
    • +
    • Feb 9 - Pre-release 2 testing ends.
    • +
    • Feb 11 - Release.
    • +
    +


    From evan.cheng at apple.com Fri Dec 5 15:52:11 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 5 Dec 2008 13:52:11 -0800 Subject: [llvm-commits] [llvm] r60608 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86Subtarget.cpp lib/Transforms/Scalar/LoopStrengthReduce.cpp test/CodeGen/X86/loop-strength-reduce-2.ll test/CodeGen/X86/loop-strength-reduce-3.ll test/CodeGen/X86/loop-strength-reduce.ll In-Reply-To: <200812052147.mB5LlSeH012488@zion.cs.uiuc.edu> References: <200812052147.mB5LlSeH012488@zion.cs.uiuc.edu> Message-ID: <36D2ED53-4677-4946-8CC3-967D896BC0AE@apple.com> You forgot changes to X86Subtarget.h? Evan On Dec 5, 2008, at 1:47 PM, Dale Johannesen wrote: > Author: johannes > Date: Fri Dec 5 15:47:27 2008 > New Revision: 60608 > > URL: http://llvm.org/viewvc/llvm-project?rev=60608&view=rev > Log: > Make LoopStrengthReduce smarter about hoisting things out of > loops when they can be subsumed into addressing modes. > > Change X86 addressing mode check to realize that > some PIC references need an extra register. > (I believe this is correct for Linux, if not, I'm sure > someone will tell me.) > > > Added: > llvm/trunk/test/CodeGen/X86/loop-strength-reduce-2.ll > llvm/trunk/test/CodeGen/X86/loop-strength-reduce-3.ll > Modified: > llvm/trunk/lib/Target/X86/X86ISelLowering.cpp > llvm/trunk/lib/Target/X86/X86Subtarget.cpp > llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp > llvm/trunk/test/CodeGen/X86/loop-strength-reduce.ll > > Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=60608&r1=60607&r2=60608&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) > +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Dec 5 > 15:47:27 2008 > @@ -6463,6 +6463,10 @@ > // We can only fold this if we don't need an extra load. > if (Subtarget->GVRequiresExtraLoad(AM.BaseGV, > getTargetMachine(), false)) > return false; > + // If BaseGV requires a register, we cannot also have a BaseReg. > + if (Subtarget->GVRequiresRegister(AM.BaseGV, > getTargetMachine(), false) && > + AM.HasBaseReg) > + return false; > > // X86-64 only supports addr of globals in small code model. > if (Subtarget->is64Bit()) { > > Modified: llvm/trunk/lib/Target/X86/X86Subtarget.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.cpp?rev=60608&r1=60607&r2=60608&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/X86/X86Subtarget.cpp (original) > +++ llvm/trunk/lib/Target/X86/X86Subtarget.cpp Fri Dec 5 15:47:27 > 2008 > @@ -59,7 +59,23 @@ > return (GV->hasDLLImportLinkage()); > } > } > - > + return false; > +} > + > +/// True if accessing the GV requires a register. This is a > superset of the > +/// cases where GVRequiresExtraLoad is true. Some variations of > PIC require > +/// a register, but not an extra load. > +bool X86Subtarget::GVRequiresRegister(const GlobalValue *GV, > + const TargetMachine& TM, > + bool isDirectCall) const > +{ > + if (GVRequiresExtraLoad(GV, TM, isDirectCall)) > + return true; > + // Code below here need only consider cases where > GVRequiresExtraLoad > + // returns false. > + if (TM.getRelocationModel() == Reloc::PIC_) > + return !isDirectCall && > + (GV->hasInternalLinkage() || GV->hasExternalLinkage()); > return false; > } > > > Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=60608&r1=60607&r2=60608&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) > +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Fri Dec > 5 15:47:27 2008 > @@ -444,7 +444,33 @@ > return true; > } > > - > +/// isAddress - Returns true if the specified instruction is using > the > +/// specified value as an address. > +static bool isAddressUse(Instruction *Inst, Value *OperandVal) { > + bool isAddress = isa(Inst); > + if (StoreInst *SI = dyn_cast(Inst)) { > + if (SI->getOperand(1) == OperandVal) > + isAddress = true; > + } else if (IntrinsicInst *II = dyn_cast(Inst)) { > + // Addressing modes can also be folded into prefetches and a > variety > + // of intrinsics. > + switch (II->getIntrinsicID()) { > + default: break; > + case Intrinsic::prefetch: > + case Intrinsic::x86_sse2_loadu_dq: > + case Intrinsic::x86_sse2_loadu_pd: > + case Intrinsic::x86_sse_loadu_ps: > + case Intrinsic::x86_sse_storeu_ps: > + case Intrinsic::x86_sse2_storeu_pd: > + case Intrinsic::x86_sse2_storeu_dq: > + case Intrinsic::x86_sse2_storel_dq: > + if (II->getOperand(1) == OperandVal) > + isAddress = true; > + break; > + } > + } > + return isAddress; > +} > > /// AddUsersIfInteresting - Inspect the specified instruction. If > it is a > /// reducible SCEV, recursively add its users to the IVUsesByStride > set and > @@ -731,15 +757,16 @@ > } > > > -/// isTargetConstant - Return true if the following can be > referenced by the > -/// immediate field of a target instruction. > -static bool isTargetConstant(const SCEVHandle &V, const Type *UseTy, > - const TargetLowering *TLI) { > +/// fitsInAddressMode - Return true if V can be subsumed within an > addressing > +/// mode, and does not need to be put in a register first. > +static bool fitsInAddressMode(const SCEVHandle &V, const Type *UseTy, > + const TargetLowering *TLI, bool > HasBaseReg) { > if (SCEVConstant *SC = dyn_cast(V)) { > int64_t VC = SC->getValue()->getSExtValue(); > if (TLI) { > TargetLowering::AddrMode AM; > AM.BaseOffs = VC; > + AM.HasBaseReg = HasBaseReg; > return TLI->isLegalAddressingMode(AM, UseTy); > } else { > // Defaults to PPC. PPC allows a sign-extended 16-bit > immediate field. > @@ -754,6 +781,7 @@ > if (GlobalValue *GV = dyn_cast(Op0)) { > TargetLowering::AddrMode AM; > AM.BaseGV = GV; > + AM.HasBaseReg = HasBaseReg; > return TLI->isLegalAddressingMode(AM, UseTy); > } > } > @@ -846,7 +874,7 @@ > return; > } else if (SCEVMulExpr *SME = dyn_cast(Val)) { > // Transform "8 * (4 + v)" -> "32 + 8*V" if "32" fits in the > immed field. > - if (isAddress && isTargetConstant(SME->getOperand(0), UseTy, > TLI) && > + if (isAddress && fitsInAddressMode(SME->getOperand(0), UseTy, > TLI, false) && > SME->getNumOperands() == 2 && SME->isLoopInvariant(L)) { > > SCEVHandle SubImm = SE->getIntegerSCEV(0, Val->getType()); > @@ -859,7 +887,7 @@ > // Scale SubImm up by "8". If the result is a target > constant, we are > // good. > SubImm = SE->getMulExpr(SubImm, SME->getOperand(0)); > - if (isTargetConstant(SubImm, UseTy, TLI)) { > + if (fitsInAddressMode(SubImm, UseTy, TLI, false)) { > // Accumulate the immediate. > Imm = SE->getAddExpr(Imm, SubImm); > > @@ -873,7 +901,7 @@ > > // Loop-variant expressions must stay in the immediate field of the > // expression. > - if ((isAddress && isTargetConstant(Val, UseTy, TLI)) || > + if ((isAddress && fitsInAddressMode(Val, UseTy, TLI, false)) || > !Val->isLoopInvariant(L)) { > Imm = SE->getAddExpr(Imm, Val); > Val = SE->getIntegerSCEV(0, Val->getType()); > @@ -912,21 +940,28 @@ > } > } > > - > -/// RemoveCommonExpressionsFromUseBases - Look through all of the > uses in Bases, > -/// removing any common subexpressions from it. Anything truly > common is > -/// removed, accumulated, and returned. This looks for things like > (a+b+c) and > +// This is logically local to the following function, but C++ says > we have > +// to make it file scope. > +struct SubExprUseData { unsigned Count; bool notAllUsesAreFree; }; > + > +/// RemoveCommonExpressionsFromUseBases - Look through all of the > Bases of all > +/// the Uses, removing any common subexpressions, except that if > all such > +/// subexpressions can be folded into an addressing mode for all > uses inside > +/// the loop (this case is referred to as "free" in comments > herein) we do > +/// not remove anything. This looks for things like (a+b+c) and > /// (a+c+d) and computes the common (a+c) subexpression. The common > expression > /// is *removed* from the Bases and returned. > static SCEVHandle > RemoveCommonExpressionsFromUseBases(std::vector &Uses, > - ScalarEvolution *SE, Loop *L) { > + ScalarEvolution *SE, Loop *L, > + const TargetLowering *TLI) { > unsigned NumUses = Uses.size(); > > // Only one use? This is a very common case, so we handle it > specially and > // cheaply. > SCEVHandle Zero = SE->getIntegerSCEV(0, Uses[0].Base->getType()); > SCEVHandle Result = Zero; > + SCEVHandle FreeResult = Zero; > if (NumUses == 1) { > // If the use is inside the loop, use its base, regardless of > what it is: > // it is clearly shared across all the IV's. If the use is > outside the loop > @@ -939,7 +974,10 @@ > > // To find common subexpressions, count how many of Uses use each > expression. > // If any subexpressions are used Uses.size() times, they are > common. > - std::map SubExpressionUseCounts; > + // Also track whether all uses of each expression can be moved > into an > + // an addressing mode "for free"; such expressions are left > within the loop. > + // struct SubExprUseData { unsigned Count; bool > notAllUsesAreFree; }; > + std::map SubExpressionUseData; > > // UniqueSubExprs - Keep track of all of the subexpressions we see > in the > // order we see them. > @@ -962,31 +1000,89 @@ > // CSEs we can find. > if (Uses[i].Base == Zero) return Zero; > > + // If this use is as an address we may be able to put CSEs in > the addressing > + // mode rather than hoisting them. > + bool isAddrUse = isAddressUse(Uses[i].Inst, > Uses[i].OperandValToReplace); > + // We may need the UseTy below, but only when isAddrUse, so > compute it > + // only in that case. > + const Type *UseTy = 0; > + if (isAddrUse) { > + UseTy = Uses[i].Inst->getType(); > + if (StoreInst *SI = dyn_cast(Uses[i].Inst)) > + UseTy = SI->getOperand(0)->getType(); > + } > + > // Split the expression into subexprs. > SeparateSubExprs(SubExprs, Uses[i].Base, SE); > - // Add one to SubExpressionUseCounts for each subexpr present. > - for (unsigned j = 0, e = SubExprs.size(); j != e; ++j) > - if (++SubExpressionUseCounts[SubExprs[j]] == 1) > + // Add one to SubExpressionUseData.Count for each subexpr > present, and > + // if the subexpr is not a valid immediate within an addressing > mode use, > + // set SubExpressionUseData.notAllUsesAreFree. We definitely > want to > + // hoist these out of the loop (if they are common to all uses). > + for (unsigned j = 0, e = SubExprs.size(); j != e; ++j) { > + if (++SubExpressionUseData[SubExprs[j]].Count == 1) > UniqueSubExprs.push_back(SubExprs[j]); > + if (!isAddrUse || !fitsInAddressMode(SubExprs[j], UseTy, TLI, > false)) > + SubExpressionUseData[SubExprs[j]].notAllUsesAreFree = true; > + } > SubExprs.clear(); > } > > // Now that we know how many times each is used, build Result. > Iterate over > // UniqueSubexprs so that we have a stable ordering. > for (unsigned i = 0, e = UniqueSubExprs.size(); i != e; ++i) { > - std::map::iterator I = > - SubExpressionUseCounts.find(UniqueSubExprs[i]); > - assert(I != SubExpressionUseCounts.end() && "Entry not found?"); > - if (I->second == NumUsesInsideLoop) // Found CSE! > - Result = SE->getAddExpr(Result, I->first); > - else > - // Remove non-cse's from SubExpressionUseCounts. > - SubExpressionUseCounts.erase(I); > + std::map::iterator I = > + SubExpressionUseData.find(UniqueSubExprs[i]); > + assert(I != SubExpressionUseData.end() && "Entry not found?"); > + if (I->second.Count == NumUsesInsideLoop) { // Found CSE! > + if (I->second.notAllUsesAreFree) > + Result = SE->getAddExpr(Result, I->first); > + else > + FreeResult = SE->getAddExpr(FreeResult, I->first); > + } else > + // Remove non-cse's from SubExpressionUseData. > + SubExpressionUseData.erase(I); > + } > + > + if (FreeResult != Zero) { > + // We have some subexpressions that can be subsumed into > addressing > + // modes in every use inside the loop. However, it's possible > that > + // there are so many of them that the combined FreeResult cannot > + // be subsumed, or that the target cannot handle both a > FreeResult > + // and a Result in the same instruction (for example because it > would > + // require too many registers). Check this. > + for (unsigned i=0; i + if (!L->contains(Uses[i].Inst->getParent())) > + continue; > + // We know this is an addressing mode use; if there are any > uses that > + // are not, FreeResult would be Zero. > + const Type *UseTy = Uses[i].Inst->getType(); > + if (StoreInst *SI = dyn_cast(Uses[i].Inst)) > + UseTy = SI->getOperand(0)->getType(); > + if (!fitsInAddressMode(FreeResult, UseTy, TLI, Result!=Zero)) { > + // FIXME: could split up FreeResult into pieces here, some > hoisted > + // and some not. Doesn't seem worth it for now. > + Result = SE->getAddExpr(Result, FreeResult); > + FreeResult = Zero; > + break; > + } > + } > } > - > + > // If we found no CSE's, return now. > if (Result == Zero) return Result; > > + // If we still have a FreeResult, remove its subexpressions from > + // SubExpressionUseData. This means they will remain in the use > Bases. > + if (FreeResult != Zero) { > + SeparateSubExprs(SubExprs, FreeResult, SE); > + for (unsigned j = 0, e = SubExprs.size(); j != e; ++j) { > + std::map::iterator I = > + SubExpressionUseData.find(SubExprs[j]); > + SubExpressionUseData.erase(I); > + } > + SubExprs.clear(); > + } > + > // Otherwise, remove all of the CSE's we found from each of the > base values. > for (unsigned i = 0; i != NumUses; ++i) { > // Uses outside the loop don't necessarily include the common > base, but > @@ -1003,7 +1099,7 @@ > > // Remove any common subexpressions. > for (unsigned j = 0, e = SubExprs.size(); j != e; ++j) > - if (SubExpressionUseCounts.count(SubExprs[j])) { > + if (SubExpressionUseData.count(SubExprs[j])) { > SubExprs.erase(SubExprs.begin()+j); > --j; --e; > } > @@ -1131,34 +1227,6 @@ > return SC->getValue()->getValue().isNegative(); > } > > -/// isAddress - Returns true if the specified instruction is using > the > -/// specified value as an address. > -static bool isAddressUse(Instruction *Inst, Value *OperandVal) { > - bool isAddress = isa(Inst); > - if (StoreInst *SI = dyn_cast(Inst)) { > - if (SI->getOperand(1) == OperandVal) > - isAddress = true; > - } else if (IntrinsicInst *II = dyn_cast(Inst)) { > - // Addressing modes can also be folded into prefetches and a > variety > - // of intrinsics. > - switch (II->getIntrinsicID()) { > - default: break; > - case Intrinsic::prefetch: > - case Intrinsic::x86_sse2_loadu_dq: > - case Intrinsic::x86_sse2_loadu_pd: > - case Intrinsic::x86_sse_loadu_ps: > - case Intrinsic::x86_sse_storeu_ps: > - case Intrinsic::x86_sse2_storeu_pd: > - case Intrinsic::x86_sse2_storeu_dq: > - case Intrinsic::x86_sse2_storel_dq: > - if (II->getOperand(1) == OperandVal) > - isAddress = true; > - break; > - } > - } > - return isAddress; > -} > - > // CollectIVUsers - Transform our list of users and offsets to a bit > more > // complex table. In this new vector, each 'BasedUser' contains > 'Base', the base > // of the strided accesses, as well as the old information from > Uses. We > @@ -1190,7 +1258,7 @@ > // "A+B"), emit it to the preheader, then remove the expression > from the > // UsersToProcess base values. > SCEVHandle CommonExprs = > - RemoveCommonExpressionsFromUseBases(UsersToProcess, SE, L); > + RemoveCommonExpressionsFromUseBases(UsersToProcess, SE, L, TLI); > > // Next, figure out what we can represent in the immediate fields of > // instructions. If we can represent anything there, move it to > the imm > @@ -1347,7 +1415,8 @@ > Constant *C = dyn_cast(CommonBaseV); > if (!C || > (!C->isNullValue() && > - !isTargetConstant(SE->getUnknown(CommonBaseV), ReplacedTy, > TLI))) > + !fitsInAddressMode(SE->getUnknown(CommonBaseV), ReplacedTy, > + TLI, false))) > // We want the common base emitted into the preheader! This is > just > // using cast as a copy so BitCast (no-op cast) is appropriate > CommonBaseV = new BitCastInst(CommonBaseV, CommonBaseV- > >getType(), > @@ -1403,7 +1472,8 @@ > // this by forcing a BitCast (noop cast) to be inserted into the > preheader > // in this case. > if (Constant *C = dyn_cast(BaseV)) { > - if (!C->isNullValue() && !isTargetConstant(Base, ReplacedTy, > TLI)) { > + if (!C->isNullValue() && !fitsInAddressMode(Base, ReplacedTy, > + TLI, false)) { > // We want this constant emitted into the preheader! This is > just > // using cast as a copy so BitCast (no-op cast) is appropriate > BaseV = new BitCastInst(BaseV, BaseV->getType(), > "preheaderinsert", > > Added: llvm/trunk/test/CodeGen/X86/loop-strength-reduce-2.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/loop-strength-reduce-2.ll?rev=60608&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/X86/loop-strength-reduce-2.ll (added) > +++ llvm/trunk/test/CodeGen/X86/loop-strength-reduce-2.ll Fri Dec 5 > 15:47:27 2008 > @@ -0,0 +1,30 @@ > +; RUN: llvm-as < %s | llc -march=x86 -relocation-model=pic | \ > +; RUN: grep {A-} | count 1 > +; > +; Make sure the common loop invariant A is hoisted up to preheader, > +; since too many registers are needed to subsume it into the > addressing modes. > + > + at A = global [16 x [16 x i32]] zeroinitializer, align 32 ; <[16 x > [16 x i32]]*> [#uses=2] > + > +define void @test(i32 %row, i32 %N.in) nounwind { > +entry: > + %N = bitcast i32 %N.in to i32 ; [#uses=1] > + %tmp5 = icmp sgt i32 %N.in, 0 ; [#uses=1] > + br i1 %tmp5, label %cond_true, label %return > + > +cond_true: ; preds = %cond_true, %entry > + %indvar = phi i32 [ 0, %entry ], [ %indvar.next, %cond_true ] ; > [#uses=2] > + %i.0.0 = bitcast i32 %indvar to i32 ; [#uses=2] > + %tmp2 = add i32 %i.0.0, 1 ; [#uses=1] > + %tmp = getelementptr [16 x [16 x i32]]* @A, i32 0, i32 %row, i32 > %tmp2 ; [#uses=1] > + store i32 4, i32* %tmp > + %tmp5.upgrd.1 = add i32 %i.0.0, 2 ; [#uses=1] > + %tmp7 = getelementptr [16 x [16 x i32]]* @A, i32 0, i32 %row, i32 > %tmp5.upgrd.1 ; [#uses=1] > + store i32 5, i32* %tmp7 > + %indvar.next = add i32 %indvar, 1 ; [#uses=2] > + %exitcond = icmp eq i32 %indvar.next, %N ; [#uses=1] > + br i1 %exitcond, label %return, label %cond_true > + > +return: ; preds = %cond_true, %entry > + ret void > +} > > Added: llvm/trunk/test/CodeGen/X86/loop-strength-reduce-3.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/loop-strength-reduce-3.ll?rev=60608&view=auto > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/X86/loop-strength-reduce-3.ll (added) > +++ llvm/trunk/test/CodeGen/X86/loop-strength-reduce-3.ll Fri Dec 5 > 15:47:27 2008 > @@ -0,0 +1,30 @@ > +; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin -relocation- > model=dynamic-no-pic | \ > +; RUN: grep {A+} | count 2 > +; > +; Make sure the common loop invariant A is not hoisted up to > preheader, > +; since it can be subsumed it into the addressing modes. > + > + at A = global [16 x [16 x i32]] zeroinitializer, align 32 ; <[16 x > [16 x i32]]*> [#uses=2] > + > +define void @test(i32 %row, i32 %N.in) nounwind { > +entry: > + %N = bitcast i32 %N.in to i32 ; [#uses=1] > + %tmp5 = icmp sgt i32 %N.in, 0 ; [#uses=1] > + br i1 %tmp5, label %cond_true, label %return > + > +cond_true: ; preds = %cond_true, %entry > + %indvar = phi i32 [ 0, %entry ], [ %indvar.next, %cond_true ] ; > [#uses=2] > + %i.0.0 = bitcast i32 %indvar to i32 ; [#uses=2] > + %tmp2 = add i32 %i.0.0, 1 ; [#uses=1] > + %tmp = getelementptr [16 x [16 x i32]]* @A, i32 0, i32 %row, i32 > %tmp2 ; [#uses=1] > + store i32 4, i32* %tmp > + %tmp5.upgrd.1 = add i32 %i.0.0, 2 ; [#uses=1] > + %tmp7 = getelementptr [16 x [16 x i32]]* @A, i32 0, i32 %row, i32 > %tmp5.upgrd.1 ; [#uses=1] > + store i32 5, i32* %tmp7 > + %indvar.next = add i32 %indvar, 1 ; [#uses=2] > + %exitcond = icmp eq i32 %indvar.next, %N ; [#uses=1] > + br i1 %exitcond, label %return, label %cond_true > + > +return: ; preds = %cond_true, %entry > + ret void > +} > > Modified: llvm/trunk/test/CodeGen/X86/loop-strength-reduce.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/loop-strength-reduce.ll?rev=60608&r1=60607&r2=60608&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/test/CodeGen/X86/loop-strength-reduce.ll (original) > +++ llvm/trunk/test/CodeGen/X86/loop-strength-reduce.ll Fri Dec 5 > 15:47:27 2008 > @@ -1,7 +1,8 @@ > -; RUN: llvm-as < %s | llc -march=x86 | \ > -; RUN: grep {A(} | count 1 > +; RUN: llvm-as < %s | llc -march=x86 -relocation-model=static | \ > +; RUN: grep {A+} | count 2 > ; > -; Make sure the common loop invariant _A(reg) is hoisted up to > preheader. > +; Make sure the common loop invariant A is not hoisted up to > preheader, > +; since it can be subsumed into the addressing mode in all uses. > > @A = internal global [16 x [16 x i32]] zeroinitializer, align 32 ; > <[16 x [16 x i32]]*> [#uses=2] > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From dalej at apple.com Fri Dec 5 15:55:36 2008 From: dalej at apple.com (Dale Johannesen) Date: Fri, 05 Dec 2008 21:55:36 -0000 Subject: [llvm-commits] [llvm] r60609 - /llvm/trunk/lib/Target/X86/X86Subtarget.h Message-ID: <200812052155.mB5LtaHw012739@zion.cs.uiuc.edu> Author: johannes Date: Fri Dec 5 15:55:35 2008 New Revision: 60609 URL: http://llvm.org/viewvc/llvm-project?rev=60609&view=rev Log: Forgot a file. Modified: llvm/trunk/lib/Target/X86/X86Subtarget.h Modified: llvm/trunk/lib/Target/X86/X86Subtarget.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.h?rev=60609&r1=60608&r2=60609&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Subtarget.h (original) +++ llvm/trunk/lib/Target/X86/X86Subtarget.h Fri Dec 5 15:55:35 2008 @@ -179,6 +179,12 @@ bool GVRequiresExtraLoad(const GlobalValue* GV, const TargetMachine& TM, bool isDirectCall) const; + /// True if accessing the GV requires a register. This is a superset of the + /// cases where GVRequiresExtraLoad is true. Some variations of PIC require + /// a register, but not an extra load. + bool GVRequiresRegister(const GlobalValue* GV, const TargetMachine& TM, + bool isDirectCall) const; + /// This function returns the name of a function which has an interface /// like the non-standard bzero function, if such a function exists on /// the current subtarget and it is considered prefereable over From dalej at apple.com Fri Dec 5 15:56:23 2008 From: dalej at apple.com (Dale Johannesen) Date: Fri, 5 Dec 2008 13:56:23 -0800 Subject: [llvm-commits] [llvm] r60608 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86Subtarget.cpp lib/Transforms/Scalar/LoopStrengthReduce.cpp test/CodeGen/X86/loop-strength-reduce-2.ll test/CodeGen/X86/loop-strength-reduce-3.ll test/CodeGen/X86/loop-strength-reduce.ll In-Reply-To: <36D2ED53-4677-4946-8CC3-967D896BC0AE@apple.com> References: <200812052147.mB5LlSeH012488@zion.cs.uiuc.edu> <36D2ED53-4677-4946-8CC3-967D896BC0AE@apple.com> Message-ID: <3A04EE30-41EB-4F8C-BE19-8D717F7C1CCB@apple.com> On Dec 5, 2008, at 1:52 PMPST, Evan Cheng wrote: > You forgot changes to X86Subtarget.h? Sorry, fixed. From anton at korobeynikov.info Fri Dec 5 16:01:20 2008 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Sat, 6 Dec 2008 01:01:20 +0300 Subject: [llvm-commits] [llvm] r60608 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86Subtarget.cpp lib/Transforms/Scalar/LoopStrengthReduce.cpp test/CodeGen/X86/loop-strength-reduce-2.ll test/CodeGen/X86/loop-strength-reduce-3.ll test/CodeGen/X86/loop-strength-reduce.ll In-Reply-To: <200812052147.mB5LlSeH012488@zion.cs.uiuc.edu> References: <200812052147.mB5LlSeH012488@zion.cs.uiuc.edu> Message-ID: Hi, Dale > > +/// True if accessing the GV requires a register. This is a > superset of the > +/// cases where GVRequiresExtraLoad is true. Some variations of > PIC require > +/// a register, but not an extra load. > +bool X86Subtarget::GVRequiresRegister(const GlobalValue *GV, > + const TargetMachine& TM, > + bool isDirectCall) const > +{ > + if (GVRequiresExtraLoad(GV, TM, isDirectCall)) > + return true; > + // Code below here need only consider cases where > GVRequiresExtraLoad > + // returns false. > + if (TM.getRelocationModel() == Reloc::PIC_) > + return !isDirectCall && > + (GV->hasInternalLinkage() || GV->hasExternalLinkage()); I don't understand this. Why only internal and external linkage? Actually for PIC on Linux (32 bit only) access to every symbols, except ones with internal linkage or hidden visibility requires a GOT register access. There was even special hook inside X86ISelLowering.cpp (incomplete in general, but usable - CallRequiresGOTPtrInReg() and another one around) for this sort of thing. Please consider using it. We've just ended with 3 hooks used for more or less similar stuff. It will be nice to have all this in one place and in consistent state... --- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University From anton at korobeynikov.info Fri Dec 5 16:15:08 2008 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Sat, 6 Dec 2008 01:15:08 +0300 Subject: [llvm-commits] [llvm] r60608 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86Subtarget.cpp lib/Transforms/Scalar/LoopStrengthReduce.cpp test/CodeGen/X86/loop-strength-reduce-2.ll test/CodeGen/X86/loop-strength-reduce-3.ll test/CodeGen/X86/loop-strength-reduce.ll In-Reply-To: <200812052147.mB5LlSeH012488@zion.cs.uiuc.edu> References: <200812052147.mB5LlSeH012488@zion.cs.uiuc.edu> Message-ID: Hi, Dale > llvm/trunk/test/CodeGen/X86/loop-strength-reduce-2.ll According to buildbot this test failed on x86-64/linux. This can be indication of bugs noted in my previous e-mail, or just indication, that you will need to provide target triple there explicitly. PIC mode is quite different on darwin vs x86-32/linux vs x86-64/linux --- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University From anton at korobeynikov.info Fri Dec 5 16:18:56 2008 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Sat, 6 Dec 2008 01:18:56 +0300 Subject: [llvm-commits] [llvm] r60605 - /llvm/trunk/lib/System/Unix/Signals.inc In-Reply-To: <200812052012.mB5KCmQh009591@zion.cs.uiuc.edu> References: <200812052012.mB5KCmQh009591@zion.cs.uiuc.edu> Message-ID: <217C03D2-9CEC-4414-A675-EE8A6406BB5B@korobeynikov.info> Hi, Dan > Modified: > llvm/trunk/lib/System/Unix/Signals.inc According to buildbot, this leads to warning: Unix/Signals.inc:100: warning: format ?%#0*x? expects type ?unsigned int?, but argument 4 has type ?void*? --- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University From dalej at apple.com Fri Dec 5 16:23:30 2008 From: dalej at apple.com (Dale Johannesen) Date: Fri, 5 Dec 2008 14:23:30 -0800 Subject: [llvm-commits] [llvm] r60608 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86Subtarget.cpp lib/Transforms/Scalar/LoopStrengthReduce.cpp test/CodeGen/X86/loop-strength-reduce-2.ll test/CodeGen/X86/loop-strength-reduce-3.ll test/CodeGen/X86/loop-strength-reduce.ll In-Reply-To: References: <200812052147.mB5LlSeH012488@zion.cs.uiuc.edu> Message-ID: On Dec 5, 2008, at 2:01 PMPST, Anton Korobeynikov wrote: > Hi, Dale > >> >> +/// True if accessing the GV requires a register. This is a >> superset of the >> +/// cases where GVRequiresExtraLoad is true. Some variations of >> PIC require >> +/// a register, but not an extra load. >> +bool X86Subtarget::GVRequiresRegister(const GlobalValue *GV, >> + const TargetMachine& TM, >> + bool isDirectCall) const >> +{ >> + if (GVRequiresExtraLoad(GV, TM, isDirectCall)) >> + return true; >> + // Code below here need only consider cases where >> GVRequiresExtraLoad >> + // returns false. >> + if (TM.getRelocationModel() == Reloc::PIC_) >> + return !isDirectCall && >> + (GV->hasInternalLinkage() || GV->hasExternalLinkage()); > I don't understand this. Why only internal and external linkage? All the others are already handled by GVRequiresExtraLoad. (At least for Darwin.) > Actually for PIC on Linux (32 bit only) access to every symbols, > except ones with internal linkage or hidden visibility requires a GOT > register access. There was even special hook inside > X86ISelLowering.cpp (incomplete in general, but usable - > CallRequiresGOTPtrInReg() and another one around) for this sort of > thing. Please consider using it. This applies to data objects, not calls. The rules are fairly different for calls and data, and I'm not sure commonality is useful. The hook I'm interested in fixing is isLegalAddressingMode, which isn't calling into the Linux function you mention. > We've just ended with 3 hooks used > for more or less similar stuff. > > It will be nice to have all this in one place and in consistent > state... > > --- > With best regards, Anton Korobeynikov > Faculty of Mathematics and Mechanics, Saint Petersburg State > University > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From dalej at apple.com Fri Dec 5 16:27:33 2008 From: dalej at apple.com (Dale Johannesen) Date: Fri, 5 Dec 2008 14:27:33 -0800 Subject: [llvm-commits] [llvm] r60608 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86Subtarget.cpp lib/Transforms/Scalar/LoopStrengthReduce.cpp test/CodeGen/X86/loop-strength-reduce-2.ll test/CodeGen/X86/loop-strength-reduce-3.ll test/CodeGen/X86/loop-strength-reduce.ll In-Reply-To: References: <200812052147.mB5LlSeH012488@zion.cs.uiuc.edu> Message-ID: On Dec 5, 2008, at 2:15 PMPST, Anton Korobeynikov wrote: > Hi, Dale > >> llvm/trunk/test/CodeGen/X86/loop-strength-reduce-2.ll > According to buildbot this test failed on x86-64/linux. This can be > indication of bugs noted in my previous e-mail, or just indication, > that you will need to provide target triple there explicitly. PIC mode > is quite different on darwin vs x86-32/linux vs x86-64/linux Not sure. Is movl $4, A at GOT+4(%edx,%eax,4) (or A+4 at GOT) valid on Linux? From dalej at apple.com Fri Dec 5 16:33:55 2008 From: dalej at apple.com (Dale Johannesen) Date: Fri, 5 Dec 2008 14:33:55 -0800 Subject: [llvm-commits] [llvm] r60608 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86Subtarget.cpp lib/Transforms/Scalar/LoopStrengthReduce.cpp test/CodeGen/X86/loop-strength-reduce-2.ll test/CodeGen/X86/loop-strength-reduce-3.ll test/CodeGen/X86/loop-strength-reduce.ll In-Reply-To: References: <200812052147.mB5LlSeH012488@zion.cs.uiuc.edu> Message-ID: <56DDD3A6-EB4C-4973-BCE7-2A2A05190C2D@apple.com> On Dec 5, 2008, at 2:27 PMPST, Dale Johannesen wrote: > > On Dec 5, 2008, at 2:15 PMPST, Anton Korobeynikov wrote: > >> Hi, Dale >> >>> llvm/trunk/test/CodeGen/X86/loop-strength-reduce-2.ll >> According to buildbot this test failed on x86-64/linux. This can be >> indication of bugs noted in my previous e-mail, or just indication, >> that you will need to provide target triple there explicitly. PIC >> mode >> is quite different on darwin vs x86-32/linux vs x86-64/linux > > Not sure. Is > > movl $4, A at GOT+4(%edx,%eax,4) > > (or A+4 at GOT) valid on Linux? Never mind, it's doing the right thing, I need to change the success test. From kremenek at apple.com Fri Dec 5 16:36:30 2008 From: kremenek at apple.com (Ted Kremenek) Date: Fri, 05 Dec 2008 22:36:30 -0000 Subject: [llvm-commits] [llvm] r60612 - /llvm/tags/checker/checker-131/ Message-ID: <200812052236.mB5MaVAV014114@zion.cs.uiuc.edu> Author: kremenek Date: Fri Dec 5 16:36:30 2008 New Revision: 60612 URL: http://llvm.org/viewvc/llvm-project?rev=60612&view=rev Log: Removing checker-131. Removed: llvm/tags/checker/checker-131/ From anton at korobeynikov.info Fri Dec 5 16:38:10 2008 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Sat, 6 Dec 2008 01:38:10 +0300 Subject: [llvm-commits] [llvm] r60608 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86Subtarget.cpp lib/Transforms/Scalar/LoopStrengthReduce.cpp test/CodeGen/X86/loop-strength-reduce-2.ll test/CodeGen/X86/loop-strength-reduce-3.ll test/CodeGen/X86/loop-strength-reduce.ll In-Reply-To: References: <200812052147.mB5LlSeH012488@zion.cs.uiuc.edu> Message-ID: <4428D3C2-3705-446F-B72B-FE263E647FBF@korobeynikov.info> Hi, Dale > > movl $4, A at GOT+4(%edx,%eax,4) Assembler ate this without any problems... But I don't see usage of GOT register here and don't think this is valid, since you're patching address inside GOT. If A is array, you need to do load first to obtain it's address, e.g. this code: int A[10]; int foo() { return A[5]; } compiles into (here ecx is GOT register): movl A at GOT(%ecx), %eax movl 20(%eax), %eax > (or A+4 at GOT) valid on Linux? This should be invalid. --- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081206/a81e12d9/attachment.html From dalej at apple.com Fri Dec 5 16:38:21 2008 From: dalej at apple.com (Dale Johannesen) Date: Fri, 05 Dec 2008 22:38:21 -0000 Subject: [llvm-commits] [llvm] r60614 - /llvm/trunk/test/CodeGen/X86/loop-strength-reduce-2.ll Message-ID: <200812052238.mB5McLfp014235@zion.cs.uiuc.edu> Author: johannes Date: Fri Dec 5 16:38:21 2008 New Revision: 60614 URL: http://llvm.org/viewvc/llvm-project?rev=60614&view=rev Log: Fix test to pass on Linux. Modified: llvm/trunk/test/CodeGen/X86/loop-strength-reduce-2.ll Modified: llvm/trunk/test/CodeGen/X86/loop-strength-reduce-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/loop-strength-reduce-2.ll?rev=60614&r1=60613&r2=60614&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/loop-strength-reduce-2.ll (original) +++ llvm/trunk/test/CodeGen/X86/loop-strength-reduce-2.ll Fri Dec 5 16:38:21 2008 @@ -1,5 +1,5 @@ ; RUN: llvm-as < %s | llc -march=x86 -relocation-model=pic | \ -; RUN: grep {A-} | count 1 +; RUN: grep {, 4} | count 1 ; ; Make sure the common loop invariant A is hoisted up to preheader, ; since too many registers are needed to subsume it into the addressing modes. From gohman at apple.com Fri Dec 5 17:39:24 2008 From: gohman at apple.com (Dan Gohman) Date: Fri, 05 Dec 2008 23:39:24 -0000 Subject: [llvm-commits] [llvm] r60616 - /llvm/trunk/lib/System/Unix/Signals.inc Message-ID: <200812052339.mB5NdO3l016301@zion.cs.uiuc.edu> Author: djg Date: Fri Dec 5 17:39:24 2008 New Revision: 60616 URL: http://llvm.org/viewvc/llvm-project?rev=60616&view=rev Log: Don't use plain %x to print pointer values. I had changed it from %p since %p isn't formatted consistently, but obviously plain %x is wrong. PRIxPTR with a cast to uintptr_t would work here, but that requires inconvenient build-system changes. %lu works on all current and foreseable future hosts. Modified: llvm/trunk/lib/System/Unix/Signals.inc Modified: llvm/trunk/lib/System/Unix/Signals.inc URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/System/Unix/Signals.inc?rev=60616&r1=60615&r2=60616&view=diff ============================================================================== --- llvm/trunk/lib/System/Unix/Signals.inc (original) +++ llvm/trunk/lib/System/Unix/Signals.inc Fri Dec 5 17:39:24 2008 @@ -97,7 +97,8 @@ if (name == NULL) fprintf(stderr, " %-*s", width, dlinfo.dli_fname); else fprintf(stderr, " %-*s", width, name+1); - fprintf(stderr, " %#0*x", (int)(sizeof(void*) * 2) + 2, StackTrace[i]); + fprintf(stderr, " %#0*lx", + (int)(sizeof(void*) * 2) + 2, (unsigned long)StackTrace[i]); if (dlinfo.dli_sname != NULL) { int res; From evan.cheng at apple.com Fri Dec 5 17:52:13 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 5 Dec 2008 15:52:13 -0800 Subject: [llvm-commits] [llvm] r60608 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86Subtarget.cpp lib/Transforms/Scalar/LoopStrengthReduce.cpp test/CodeGen/X86/loop-strength-reduce-2.ll test/CodeGen/X86/loop-strength-reduce-3.ll test/CodeGen/X86/loop-strength-reduce.ll In-Reply-To: References: <200812052147.mB5LlSeH012488@zion.cs.uiuc.edu> Message-ID: <38759B43-0069-42C6-9885-678822D956CE@apple.com> On Dec 5, 2008, at 2:23 PM, Dale Johannesen wrote: > > On Dec 5, 2008, at 2:01 PMPST, Anton Korobeynikov wrote: > >> Hi, Dale >> >>> >>> +/// True if accessing the GV requires a register. This is a >>> superset of the >>> +/// cases where GVRequiresExtraLoad is true. Some variations of >>> PIC require >>> +/// a register, but not an extra load. >>> +bool X86Subtarget::GVRequiresRegister(const GlobalValue *GV, >>> + const TargetMachine& TM, >>> + bool isDirectCall) const >>> +{ >>> + if (GVRequiresExtraLoad(GV, TM, isDirectCall)) >>> + return true; >>> + // Code below here need only consider cases where >>> GVRequiresExtraLoad >>> + // returns false. >>> + if (TM.getRelocationModel() == Reloc::PIC_) >>> + return !isDirectCall && >>> + (GV->hasInternalLinkage() || GV->hasExternalLinkage()); >> I don't understand this. Why only internal and external linkage? > > All the others are already handled by GVRequiresExtraLoad. (At least > for Darwin.) That doesn't sound right. For Darwin x86 32-bit PIC, all data load requires the pic base register. This has nothing to do with whether a stub is needed. Evan > > >> Actually for PIC on Linux (32 bit only) access to every symbols, >> except ones with internal linkage or hidden visibility requires a GOT >> register access. There was even special hook inside >> X86ISelLowering.cpp (incomplete in general, but usable - >> CallRequiresGOTPtrInReg() and another one around) for this sort of >> thing. Please consider using it. > > This applies to data objects, not calls. The rules are fairly > different for calls and data, and I'm not sure commonality is useful. > The hook I'm interested in fixing is isLegalAddressingMode, which > isn't calling into the Linux function you mention. > >> We've just ended with 3 hooks used >> for more or less similar stuff. >> >> It will be nice to have all this in one place and in consistent >> state... >> >> --- >> With best regards, Anton Korobeynikov >> Faculty of Mathematics and Mechanics, Saint Petersburg State >> University >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From gohman at apple.com Fri Dec 5 17:55:40 2008 From: gohman at apple.com (Dan Gohman) Date: Fri, 5 Dec 2008 15:55:40 -0800 Subject: [llvm-commits] [llvm] r60605 - /llvm/trunk/lib/System/Unix/Signals.inc In-Reply-To: <217C03D2-9CEC-4414-A675-EE8A6406BB5B@korobeynikov.info> References: <200812052012.mB5KCmQh009591@zion.cs.uiuc.edu> <217C03D2-9CEC-4414-A675-EE8A6406BB5B@korobeynikov.info> Message-ID: On Dec 5, 2008, at 2:18 PM, Anton Korobeynikov wrote: > Hi, Dan > >> Modified: >> llvm/trunk/lib/System/Unix/Signals.inc > According to buildbot, this leads to warning: > Unix/Signals.inc:100: warning: format ?%#0*x? expects type ?unsigned > int?, but argument 4 has type ?void*? Fixed. Thanks! Dan From dalej at apple.com Fri Dec 5 17:58:34 2008 From: dalej at apple.com (Dale Johannesen) Date: Fri, 5 Dec 2008 15:58:34 -0800 Subject: [llvm-commits] [llvm] r60608 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86Subtarget.cpp lib/Transforms/Scalar/LoopStrengthReduce.cpp test/CodeGen/X86/loop-strength-reduce-2.ll test/CodeGen/X86/loop-strength-reduce-3.ll test/CodeGen/X86/loop-strength-reduce.ll In-Reply-To: <38759B43-0069-42C6-9885-678822D956CE@apple.com> References: <200812052147.mB5LlSeH012488@zion.cs.uiuc.edu> <38759B43-0069-42C6-9885-678822D956CE@apple.com> Message-ID: On Dec 5, 2008, at 3:52 PMPST, Evan Cheng wrote: >> On Dec 5, 2008, at 2:01 PMPST, Anton Korobeynikov wrote: >> >>> Hi, Dale >>> >>>> >>>> +/// True if accessing the GV requires a register. This is a >>>> superset of the >>>> +/// cases where GVRequiresExtraLoad is true. Some variations of >>>> PIC require >>>> +/// a register, but not an extra load. >>>> +bool X86Subtarget::GVRequiresRegister(const GlobalValue *GV, >>>> + const TargetMachine& TM, >>>> + bool isDirectCall) const >>>> +{ >>>> + if (GVRequiresExtraLoad(GV, TM, isDirectCall)) >>>> + return true; >>>> + // Code below here need only consider cases where >>>> GVRequiresExtraLoad >>>> + // returns false. >>>> + if (TM.getRelocationModel() == Reloc::PIC_) >>>> + return !isDirectCall && >>>> + (GV->hasInternalLinkage() || GV->hasExternalLinkage()); >>> I don't understand this. Why only internal and external linkage? >> >> All the others are already handled by GVRequiresExtraLoad. (At least >> for Darwin.) > > That doesn't sound right. For Darwin x86 32-bit PIC, all data load > requires the pic base register. This has nothing to do with whether a > stub is needed. What is it that doesn't sound right? You're quite right this has nothing to do with stubs, why do you think it does? There is a difference between requiring the pic register and requiring an extra load; the former was not being modelled. Externals are referenced via leal L_x5$non_lazy_ptr-"L00000000001$pb"(%ebx), %eax movl (%eax), %eax << loading address movl (%eax), %eax << loading value This case returns true from GVRequiresExtraLoad. Statics and globals are referenced via leal _x0-"L00000000001$pb"(%ebx), %eax movl (%eax), %eax << loading value This case returns false from GVRequiresExtraLoad but true from GVRequiresRegister. From evan.cheng at apple.com Fri Dec 5 18:12:33 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 5 Dec 2008 16:12:33 -0800 Subject: [llvm-commits] [llvm] r60608 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86Subtarget.cpp lib/Transforms/Scalar/LoopStrengthReduce.cpp test/CodeGen/X86/loop-strength-reduce-2.ll test/CodeGen/X86/loop-strength-reduce-3.ll test/CodeGen/X86/loop-strength-reduce.ll In-Reply-To: References: <200812052147.mB5LlSeH012488@zion.cs.uiuc.edu> <38759B43-0069-42C6-9885-678822D956CE@apple.com> Message-ID: On Dec 5, 2008, at 3:58 PM, Dale Johannesen wrote: > > On Dec 5, 2008, at 3:52 PMPST, Evan Cheng wrote: >>> On Dec 5, 2008, at 2:01 PMPST, Anton Korobeynikov wrote: >>> >>>> Hi, Dale >>>> >>>>> >>>>> +/// True if accessing the GV requires a register. This is a >>>>> superset of the >>>>> +/// cases where GVRequiresExtraLoad is true. Some variations of >>>>> PIC require >>>>> +/// a register, but not an extra load. >>>>> +bool X86Subtarget::GVRequiresRegister(const GlobalValue *GV, >>>>> + const TargetMachine& TM, >>>>> + bool isDirectCall) const >>>>> +{ >>>>> + if (GVRequiresExtraLoad(GV, TM, isDirectCall)) >>>>> + return true; >>>>> + // Code below here need only consider cases where >>>>> GVRequiresExtraLoad >>>>> + // returns false. >>>>> + if (TM.getRelocationModel() == Reloc::PIC_) >>>>> + return !isDirectCall && >>>>> + (GV->hasInternalLinkage() || GV->hasExternalLinkage()); >>>> I don't understand this. Why only internal and external linkage? >>> >>> All the others are already handled by GVRequiresExtraLoad. (At >>> least >>> for Darwin.) >> >> That doesn't sound right. For Darwin x86 32-bit PIC, all data load >> requires the pic base register. This has nothing to do with whether a >> stub is needed. > > What is it that doesn't sound right? You're quite right this has > nothing to do with stubs, why do you think it does? > > There is a difference between requiring the pic register and requiring > an extra > load; the former was not being modelled. Externals are referenced via > leal L_x5$non_lazy_ptr-"L00000000001$pb"(%ebx), %eax > movl (%eax), %eax << loading address > movl (%eax), %eax << loading value > This case returns true from GVRequiresExtraLoad. > > Statics and globals are referenced via > leal _x0-"L00000000001$pb"(%ebx), %eax > movl (%eax), %eax << loading value > This case returns false from GVRequiresExtraLoad but true from > GVRequiresRegister. I don't think GVRequiresRegister needs to call GVRequiresExtraLoad though. Even if it returns false, GVRequiresRegister should always return true for PIC && !DirectCall. It needs PIC base even if linkage is weak, common, etc. Plus, you should check relocation model first which is cheaper than GVRequiresExtraLoad. Evan > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From dalej at apple.com Fri Dec 5 18:18:11 2008 From: dalej at apple.com (Dale Johannesen) Date: Fri, 5 Dec 2008 16:18:11 -0800 Subject: [llvm-commits] [llvm] r60608 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86Subtarget.cpp lib/Transforms/Scalar/LoopStrengthReduce.cpp test/CodeGen/X86/loop-strength-reduce-2.ll test/CodeGen/X86/loop-strength-reduce-3.ll test/CodeGen/X86/loop-strength-reduce.ll In-Reply-To: References: <200812052147.mB5LlSeH012488@zion.cs.uiuc.edu> <38759B43-0069-42C6-9885-678822D956CE@apple.com> Message-ID: <10961E0E-392B-400C-AE7E-093ED6A24BFF@apple.com> On Dec 5, 2008, at 4:12 PMPST, Evan Cheng wrote: >>> >>> That doesn't sound right. For Darwin x86 32-bit PIC, all data load >>> requires the pic base register. This has nothing to do with >>> whether a >>> stub is needed. >> >> What is it that doesn't sound right? You're quite right this has >> nothing to do with stubs, why do you think it does? >> >> There is a difference between requiring the pic register and >> requiring >> an extra >> load; the former was not being modelled. Externals are referenced >> via >> leal L_x5$non_lazy_ptr-"L00000000001$pb"(%ebx), %eax >> movl (%eax), %eax << loading address >> movl (%eax), %eax << loading value >> This case returns true from GVRequiresExtraLoad. >> >> Statics and globals are referenced via >> leal _x0-"L00000000001$pb"(%ebx), %eax >> movl (%eax), %eax << loading value >> This case returns false from GVRequiresExtraLoad but true from >> GVRequiresRegister. > > I don't think GVRequiresRegister needs to call GVRequiresExtraLoad > though. Even if it returns false, GVRequiresRegister should always > return true for PIC && !DirectCall. It needs PIC base even if linkage > is weak, common, etc. > > Plus, you should check relocation model first which is cheaper than > GVRequiresExtraLoad. Hmm, maybe. I find it much easier to understand this if I think of RequiresRegister as "RequiresExtraLoad plus some extra cases" and have the implementation follow that. Think of it as factoring. From gohman at apple.com Fri Dec 5 18:20:35 2008 From: gohman at apple.com (Dan Gohman) Date: Sat, 06 Dec 2008 00:20:35 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r60617 - /llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Message-ID: <200812060020.mB60KaRY017488@zion.cs.uiuc.edu> Author: djg Date: Fri Dec 5 18:20:35 2008 New Revision: 60617 URL: http://llvm.org/viewvc/llvm-project?rev=60617&view=rev Log: SchedulerRegistry.h is now sufficient for most front-ends, so it's not necessary to include ScheduleDAGSDNodes.h here. Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=60617&r1=60616&r2=60617&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Fri Dec 5 18:20:35 2008 @@ -36,7 +36,6 @@ #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/CodeGen/RegAllocRegistry.h" #include "llvm/CodeGen/SchedulerRegistry.h" -#include "llvm/CodeGen/ScheduleDAGSDNodes.h" #include "llvm/Target/SubtargetFeature.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetLowering.h" From sabre at nondot.org Fri Dec 5 18:53:23 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 06 Dec 2008 00:53:23 -0000 Subject: [llvm-commits] [llvm] r60619 - in /llvm/trunk: lib/Transforms/Scalar/DeadStoreElimination.cpp test/Transforms/DeadStoreElimination/free.ll Message-ID: <200812060053.mB60rNB5018521@zion.cs.uiuc.edu> Author: lattner Date: Fri Dec 5 18:53:22 2008 New Revision: 60619 URL: http://llvm.org/viewvc/llvm-project?rev=60619&view=rev Log: Reimplement the inner loop of DSE. It now uniformly uses getDependence(), doesn't do its own local caching, and is slightly more aggressive about free/store dse (see testcase). This eliminates the last external client of MemDep::getDependenceFrom(). Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp llvm/trunk/test/Transforms/DeadStoreElimination/free.ll Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=60619&r1=60618&r2=60619&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Fri Dec 5 18:53:22 2008 @@ -50,7 +50,7 @@ bool runOnBasicBlock(BasicBlock &BB); bool handleFreeWithNonTrivialDependency(FreeInst *F, MemDepResult Dep); bool handleEndBlock(BasicBlock &BB); - bool RemoveUndeadPointers(Value* pointer, uint64_t killPointerSize, + bool RemoveUndeadPointers(Value* Ptr, uint64_t killPointerSize, BasicBlock::iterator& BBI, SmallPtrSet& deadPointers); void DeleteDeadInstruction(Instruction *I, @@ -81,93 +81,60 @@ MemoryDependenceAnalysis& MD = getAnalysis(); TargetData &TD = getAnalysis(); - // Record the last-seen store to this pointer - DenseMap lastStore; - bool MadeChange = false; // Do a top-down walk on the BB for (BasicBlock::iterator BBI = BB.begin(), BBE = BB.end(); BBI != BBE; ) { Instruction *Inst = BBI++; - // If we find a store or a free... + // If we find a store or a free, get it's memory dependence. if (!isa(Inst) && !isa(Inst)) continue; - Value* pointer = 0; - if (StoreInst* S = dyn_cast(Inst)) { - if (S->isVolatile()) - continue; - pointer = S->getPointerOperand(); - } else { - pointer = cast(Inst)->getPointerOperand(); + MemDepResult InstDep = MD.getDependency(Inst); + + // Ignore non-local stores. + // FIXME: cross-block DSE would be fun. :) + if (InstDep.isNonLocal()) continue; + + // Handle frees whose dependencies are non-trivial. + if (FreeInst *FI = dyn_cast(Inst)) { + MadeChange |= handleFreeWithNonTrivialDependency(FI, InstDep); + continue; } - - pointer = pointer->stripPointerCasts(); - StoreInst *&last = lastStore[pointer]; - - // ... to a pointer that has been stored to before... - if (last) { - MemDepResult dep = MD.getDependency(Inst); - bool deletedStore = false; - - // ... and no other memory dependencies are between them.... - while (StoreInst *DepStore = dyn_cast_or_null(dep.getInst())) { - if (DepStore != last || - TD.getTypeStoreSize(last->getOperand(0)->getType()) > - TD.getTypeStoreSize(Inst->getOperand(0)->getType())) { - dep = MD.getDependencyFrom(Inst, DepStore, DepStore->getParent()); - continue; - } - + + StoreInst *SI = cast(Inst); + + // If not a definite must-alias dependency, ignore it. + if (!InstDep.isDef()) + continue; + + // If this is a store-store dependence, then the previous store is dead so + // long as this store is at least as big as it. + if (StoreInst *DepStore = dyn_cast(InstDep.getInst())) + if (TD.getTypeStoreSize(DepStore->getOperand(0)->getType()) <= + TD.getTypeStoreSize(SI->getOperand(0)->getType())) { // Delete the store and now-dead instructions that feed it. - DeleteDeadInstruction(last); + DeleteDeadInstruction(DepStore); NumFastStores++; - deletedStore = true; MadeChange = true; - break; - } - - // If we deleted a store, reinvestigate this instruction. - if (deletedStore) { + if (BBI != BB.begin()) --BBI; continue; } - } - // Handle frees whose dependencies are non-trivial. - if (FreeInst* F = dyn_cast(Inst)) { - MadeChange |= handleFreeWithNonTrivialDependency(F, MD.getDependency(F)); - - // No known stores after the free. - last = 0; - } else { - StoreInst* S = cast(Inst); - - // If we're storing the same value back to a pointer that we just - // loaded from, then the store can be removed; - if (LoadInst* L = dyn_cast(S->getOperand(0))) { - if (!S->isVolatile() && S->getParent() == L->getParent() && - S->getPointerOperand() == L->getPointerOperand()) { - MemDepResult dep = MD.getDependency(S); - if (dep.isDef() && dep.getInst() == L) { - DeleteDeadInstruction(S); - if (BBI != BB.begin()) - --BBI; - NumFastStores++; - MadeChange = true; - } else { - // Update our most-recent-store map. - last = S; - } - } else { - // Update our most-recent-store map. - last = S; - } - } else { - // Update our most-recent-store map. - last = S; + // If we're storing the same value back to a pointer that we just + // loaded from, then the store can be removed. + if (LoadInst *DepLoad = dyn_cast(InstDep.getInst())) { + if (SI->getPointerOperand() == DepLoad->getPointerOperand() && + SI->getOperand(0) == DepLoad) { + DeleteDeadInstruction(SI); + if (BBI != BB.begin()) + --BBI; + NumFastStores++; + MadeChange = true; + continue; } } } @@ -182,29 +149,22 @@ /// handleFreeWithNonTrivialDependency - Handle frees of entire structures whose /// dependency is a store to a field of that structure. -bool DSE::handleFreeWithNonTrivialDependency(FreeInst* F, MemDepResult dep) { - TargetData &TD = getAnalysis(); +bool DSE::handleFreeWithNonTrivialDependency(FreeInst *F, MemDepResult Dep) { AliasAnalysis &AA = getAnalysis(); - StoreInst* dependency = dyn_cast_or_null(dep.getInst()); - if (!dependency) - return false; - else if (dependency->isVolatile()) + StoreInst *Dependency = dyn_cast_or_null(Dep.getInst()); + if (!Dependency || Dependency->isVolatile()) return false; - Value* depPointer = dependency->getPointerOperand(); - const Type* depType = dependency->getOperand(0)->getType(); - unsigned depPointerSize = TD.getTypeStoreSize(depType); - - // Check for aliasing - AliasAnalysis::AliasResult A = AA.alias(F->getPointerOperand(), ~0U, - depPointer, depPointerSize); + Value *DepPointer = Dependency->getPointerOperand()->getUnderlyingObject(); - if (A != AliasAnalysis::MustAlias) + // Check for aliasing. + if (AA.alias(F->getPointerOperand(), 1, DepPointer, 1) != + AliasAnalysis::MustAlias) return false; // DCE instructions only used to calculate that store - DeleteDeadInstruction(dependency); + DeleteDeadInstruction(Dependency); NumFastStores++; return true; } Modified: llvm/trunk/test/Transforms/DeadStoreElimination/free.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DeadStoreElimination/free.ll?rev=60619&r1=60618&r2=60619&view=diff ============================================================================== --- llvm/trunk/test/Transforms/DeadStoreElimination/free.ll (original) +++ llvm/trunk/test/Transforms/DeadStoreElimination/free.ll Fri Dec 5 18:53:22 2008 @@ -6,3 +6,10 @@ free i32* %P ret void } + +define void @test2({i32, i32}* %P) { + %Q = getelementptr {i32, i32} *%P, i32 0, i32 1 + store i32 4, i32* %Q + free {i32,i32}* %P + ret void +} From evan.cheng at apple.com Fri Dec 5 20:00:56 2008 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 06 Dec 2008 02:00:56 -0000 Subject: [llvm-commits] [llvm] r60621 - in /llvm/trunk: lib/Target/ARM/ARMTargetAsmInfo.cpp lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp test/CodeGen/ARM/2008-08-07-AsmPrintBug.ll test/CodeGen/ARM/hidden-vis-2.ll test/CodeGen/ARM/hidden-vis-3.ll test/CodeGen/ARM/hidden-vis.ll Message-ID: <200812060200.mB620v5W020436@zion.cs.uiuc.edu> Author: evancheng Date: Fri Dec 5 20:00:55 2008 New Revision: 60621 URL: http://llvm.org/viewvc/llvm-project?rev=60621&view=rev Log: Clean up some ARM GV asm printing out; minor fixes to match what gcc does. Added: llvm/trunk/test/CodeGen/ARM/hidden-vis-2.ll llvm/trunk/test/CodeGen/ARM/hidden-vis-3.ll llvm/trunk/test/CodeGen/ARM/hidden-vis.ll Modified: llvm/trunk/lib/Target/ARM/ARMTargetAsmInfo.cpp llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp llvm/trunk/test/CodeGen/ARM/2008-08-07-AsmPrintBug.ll Modified: llvm/trunk/lib/Target/ARM/ARMTargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMTargetAsmInfo.cpp?rev=60621&r1=60620&r2=60621&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMTargetAsmInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMTargetAsmInfo.cpp Fri Dec 5 20:00:55 2008 @@ -56,6 +56,7 @@ ZeroFillDirective = "\t.zerofill\t"; // Uses .zerofill SetDirective = "\t.set\t"; WeakRefDirective = "\t.weak_reference\t"; + WeakDefDirective = "\t.weak_definition "; HiddenDirective = "\t.private_extern\t"; ProtectedDirective = NULL; JumpTableDataSection = ".const"; Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp?rev=60621&r1=60620&r2=60621&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Fri Dec 5 20:00:55 2008 @@ -29,7 +29,6 @@ #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSet.h" @@ -84,10 +83,6 @@ /// asm printer should generate stubs for. StringSet<> FnStubs; - /// PCRelGVs - Keeps the set of GlobalValues used in pc relative - /// constantpool. - SmallPtrSet PCRelGVs; - /// True if asm printer is printing a series of CONSTPOOL_ENTRY. bool InCPMode; @@ -677,12 +672,6 @@ if (MCPE.isMachineConstantPoolEntry()) { EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal); - ARMConstantPoolValue *ACPV = - static_cast(MCPE.Val.MachineCPVal); - if (ACPV->getPCAdjustment() != 0) { - const GlobalValue *GV = ACPV->getGV(); - PCRelGVs.insert(GV); - } } else { EmitGlobalConstant(MCPE.Val.ConstVal); // remember to emit the weak reference @@ -841,18 +830,18 @@ const Type *Type = C->getType(); unsigned Size = TD->getABITypeSize(Type); unsigned Align = TD->getPreferredAlignmentLog(GVar); + bool isDarwin = Subtarget->isTargetDarwin(); printVisibility(name, GVar->getVisibility()); if (Subtarget->isTargetELF()) O << "\t.type " << name << ",%object\n"; - SwitchToSection(TAI->SectionForGlobal(GVar)); - if (C->isNullValue() && !GVar->hasSection() && !GVar->isThreadLocal()) { // FIXME: This seems to be pretty darwin-specific if (GVar->hasExternalLinkage()) { + SwitchToSection(TAI->SectionForGlobal(GVar)); if (const char *Directive = TAI->getZeroFillDirective()) { O << "\t.globl\t" << name << "\n"; O << Directive << "__DATA, __common, " << name << ", " @@ -864,14 +853,34 @@ if (GVar->hasInternalLinkage() || GVar->mayBeOverridden()) { if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. - if (TAI->getLCOMMDirective() != NULL) { - if (PCRelGVs.count(GVar) || GVar->hasInternalLinkage()) { + if (isDarwin) { + if (GVar->hasInternalLinkage()) { + O << TAI->getLCOMMDirective() << name << "," << Size + << ',' << Align; + } else if (GVar->hasCommonLinkage()) { + O << TAI->getCOMMDirective() << name << "," << Size + << ',' << Align; + } else { + SwitchToSection(TAI->SectionForGlobal(GVar)); + O << "\t.globl " << name << '\n' + << TAI->getWeakDefDirective() << name << '\n'; + EmitAlignment(Align, GVar); + O << name << ":\t\t\t\t" << TAI->getCommentString() << ' '; + PrintUnmangledNameSafely(GVar, O); + O << '\n'; + EmitGlobalConstant(C); + return; + } + } else if (TAI->getLCOMMDirective() != NULL) { + if (GVar->hasInternalLinkage()) { O << TAI->getLCOMMDirective() << name << "," << Size; - if (Subtarget->isTargetDarwin()) - O << "," << Align; - } else + } else { O << TAI->getCOMMDirective() << name << "," << Size; + if (TAI->getCOMMDirectiveTakesAlignment()) + O << ',' << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align); + } } else { + SwitchToSection(TAI->SectionForGlobal(GVar)); if (GVar->hasInternalLinkage()) O << "\t.local\t" << name << "\n"; O << TAI->getCOMMDirective() << name << "," << Size; @@ -885,10 +894,12 @@ } } + SwitchToSection(TAI->SectionForGlobal(GVar)); switch (GVar->getLinkage()) { + case GlobalValue::CommonLinkage: case GlobalValue::LinkOnceLinkage: case GlobalValue::WeakLinkage: - if (Subtarget->isTargetDarwin()) { + if (isDarwin) { O << "\t.globl " << name << "\n" << "\t.weak_definition " << name << "\n"; } else { @@ -980,7 +991,7 @@ // Output non-lazy-pointers for external and common global variables. if (!GVNonLazyPtrs.empty()) { - SwitchToDataSection(".non_lazy_symbol_pointer", 0); + SwitchToDataSection("\t.non_lazy_symbol_pointer", 0); for (StringSet<>::iterator i = GVNonLazyPtrs.begin(), e = GVNonLazyPtrs.end(); i != e; ++i) { const char *p = i->getKeyData(); Modified: llvm/trunk/test/CodeGen/ARM/2008-08-07-AsmPrintBug.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2008-08-07-AsmPrintBug.ll?rev=60621&r1=60620&r2=60621&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/2008-08-07-AsmPrintBug.ll (original) +++ llvm/trunk/test/CodeGen/ARM/2008-08-07-AsmPrintBug.ll Fri Dec 5 20:00:55 2008 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin -mattr=+v6 -relocation-model=pic | grep lcomm +; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin -mattr=+v6 -relocation-model=pic | grep comm %struct.FILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, %struct.__sFILEX*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 } %struct.__gcov_var = type { %struct.FILE*, i32, i32, i32, i32, i32, i32, [1025 x i32] } Added: llvm/trunk/test/CodeGen/ARM/hidden-vis-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/hidden-vis-2.ll?rev=60621&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/hidden-vis-2.ll (added) +++ llvm/trunk/test/CodeGen/ARM/hidden-vis-2.ll Fri Dec 5 20:00:55 2008 @@ -0,0 +1,9 @@ +; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin | grep ldr | count 2 + + at x = weak hidden global i32 0 ; [#uses=1] + +define i32 @t() nounwind readonly { +entry: + %0 = load i32* @x, align 4 ; [#uses=1] + ret i32 %0 +} Added: llvm/trunk/test/CodeGen/ARM/hidden-vis-3.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/hidden-vis-3.ll?rev=60621&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/hidden-vis-3.ll (added) +++ llvm/trunk/test/CodeGen/ARM/hidden-vis-3.ll Fri Dec 5 20:00:55 2008 @@ -0,0 +1,14 @@ +; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin | grep ldr | count 6 +; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin | grep non_lazy_ptr +; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin | grep long | count 4 + + at x = external hidden global i32 ; [#uses=1] + at y = extern_weak hidden global i32 ; [#uses=1] + +define i32 @t() nounwind readonly { +entry: + %0 = load i32* @x, align 4 ; [#uses=1] + %1 = load i32* @y, align 4 ; [#uses=1] + %2 = add i32 %1, %0 ; [#uses=1] + ret i32 %2 +} Added: llvm/trunk/test/CodeGen/ARM/hidden-vis.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/hidden-vis.ll?rev=60621&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/hidden-vis.ll (added) +++ llvm/trunk/test/CodeGen/ARM/hidden-vis.ll Fri Dec 5 20:00:55 2008 @@ -0,0 +1,18 @@ +; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin | \ +; RUN: grep .private_extern | count 2 + +%struct.Person = type { i32 } + at a = hidden global i32 0 + at b = external global i32 + + +define weak hidden void @_ZN6Person13privateMethodEv(%struct.Person* %this) { + ret void +} + +declare void @function(i32) + +define weak void @_ZN6PersonC1Ei(%struct.Person* %this, i32 %_c) { + ret void +} + From wangmp at apple.com Fri Dec 5 23:09:36 2008 From: wangmp at apple.com (Mon Ping Wang) Date: Fri, 5 Dec 2008 21:09:36 -0800 Subject: [llvm-commits] Patch: small fix to bit convert and shifts In-Reply-To: <9677A259-CA70-47BC-A7B9-8F969B887B02@rapidmind.com> References: <2E498C01-B301-4F46-B16B-D030D169FE88@apple.com> <9677A259-CA70-47BC-A7B9-8F969B887B02@rapidmind.com> Message-ID: Hi, I'm resubmitting the patch with an additional change that fixes another bug when splitting vector shifts. When unrolling a vector shift, we fix up the shift amount to be the correct type. I left the fix up of the shift amount in LegalizeOp alone though I don't think it is ever needed since I don't think one can create a shift of a scalar with an incorrect shift amount type. I also updated the LangRef with an examples of using vector for the shift operands. -- Mon Ping -------------- next part -------------- A non-text attachment was scrubbed... Name: vshift.patch Type: application/octet-stream Size: 5425 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081205/d17e7337/attachment.obj -------------- next part -------------- From nicholas at mxc.ca Sat Dec 6 11:57:06 2008 From: nicholas at mxc.ca (Nick Lewycky) Date: Sat, 06 Dec 2008 17:57:06 -0000 Subject: [llvm-commits] [llvm] r60623 - /llvm/trunk/lib/Analysis/ScalarEvolution.cpp Message-ID: <200812061757.mB6Hv6qf025933@zion.cs.uiuc.edu> Author: nicholas Date: Sat Dec 6 11:57:05 2008 New Revision: 60623 URL: http://llvm.org/viewvc/llvm-project?rev=60623&view=rev Log: Minor cleanup. Use dyn_cast, not isa/cast pairs. No functionality change. Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=60623&r1=60622&r2=60623&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Sat Dec 6 11:57:05 2008 @@ -2911,18 +2911,18 @@ bool isSigned, bool trueWhenEqual) { // Return true when the distance from RHS to maxint > Stride. - if (!isa(Stride)) + SCEVConstant *SC = dyn_cast(Stride); + if (!SC) return true; - SCEVConstant *SC = cast(Stride); if (SC->getValue()->isZero()) return true; if (!trueWhenEqual && SC->getValue()->isOne()) return false; - if (!isa(RHS)) + SCEVConstant *R = dyn_cast(RHS); + if (!R) return true; - SCEVConstant *R = cast(RHS); if (isSigned) return true; // XXX: because we don't have an sdiv scev. @@ -2983,7 +2983,7 @@ // loop by one iteration. // // The loop won't actually run (m-n)/s times because the loop iterations - // won't divide evenly. For example, if you have {2,+,5} u< 10 the + // might not divide cleanly. For example, if you have {2,+,5} u< 10 the // division would equal one, but the loop runs twice putting the // induction variable at 12. From sabre at nondot.org Sat Dec 6 13:28:22 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 06 Dec 2008 19:28:22 -0000 Subject: [llvm-commits] [llvm] r60624 - /llvm/trunk/lib/Target/README.txt Message-ID: <200812061928.mB6JSNfM028488@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 6 13:28:22 2008 New Revision: 60624 URL: http://llvm.org/viewvc/llvm-project?rev=60624&view=rev Log: some random notes. Modified: llvm/trunk/lib/Target/README.txt Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=60624&r1=60623&r2=60624&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Sat Dec 6 13:28:22 2008 @@ -1272,4 +1272,101 @@ later. +//===---------------------------------------------------------------------===// + +Store sinking: This code: + +void f (int n, int *cond, int *res) { + int i; + *res = 0; + for (i = 0; i < n; i++) + if (*cond) + *res ^= 234; /* (*) */ +} + +On this function GVN hoists the fully redundant value of *res, but nothing +moves the store out. This gives us this code: + +bb: ; preds = %bb2, %entry + %.rle = phi i32 [ 0, %entry ], [ %.rle6, %bb2 ] + %i.05 = phi i32 [ 0, %entry ], [ %indvar.next, %bb2 ] + %1 = load i32* %cond, align 4 + %2 = icmp eq i32 %1, 0 + br i1 %2, label %bb2, label %bb1 + +bb1: ; preds = %bb + %3 = xor i32 %.rle, 234 + store i32 %3, i32* %res, align 4 + br label %bb2 + +bb2: ; preds = %bb, %bb1 + %.rle6 = phi i32 [ %3, %bb1 ], [ %.rle, %bb ] + %indvar.next = add i32 %i.05, 1 + %exitcond = icmp eq i32 %indvar.next, %n + br i1 %exitcond, label %return, label %bb + +DSE should sink partially dead stores to get the store out of the loop. + +//===---------------------------------------------------------------------===// + +Scalar PRE hoists the mul in the common block up to the else: + +int test (int a, int b, int c, int g) { + int d, e; + if (a) + d = b * c; + else + d = b - c; + e = b * c + g; + return d + e; +} + +It would be better to do the mul once to reduce codesize above the if. +This is GCC PR38204. + +//===---------------------------------------------------------------------===// + +GCC PR37810 is an interesting case where we should sink load/store reload +into the if block and outside the loop, so we don't reload/store it on the +non-call path. + +for () { + *P += 1; + if () + call(); + else + ... +-> +tmp = *P +for () { + tmp += 1; + if () { + *P = tmp; + call(); + tmp = *P; + } else ... +} +*P = tmp; + +//===---------------------------------------------------------------------===// + +GCC PR37166: Sinking of loads prevents SROA'ing the "g" struct on the stack +leading to excess stack traffic. This could be handled by GVN with some crazy +symbolic phi translation. The code we get looks like (g is on the stack): + +bb2: ; preds = %bb1 +.. + %9 = getelementptr %struct.f* %g, i32 0, i32 0 + store i32 %8, i32* %9, align bel %bb3 + +bb3: ; preds = %bb1, %bb2, %bb + %c_addr.0 = phi %struct.f* [ %g, %bb2 ], [ %c, %bb ], [ %c, %bb1 ] + %b_addr.0 = phi %struct.f* [ %b, %bb2 ], [ %g, %bb ], [ %b, %bb1 ] + %10 = getelementptr %struct.f* %c_addr.0, i32 0, i32 0 + %11 = load i32* %10, align 4 + +%11 is fully redundant, an in BB2 it should have the value %8. + +//===---------------------------------------------------------------------===// + From sabre at nondot.org Sat Dec 6 16:49:05 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 06 Dec 2008 22:49:05 -0000 Subject: [llvm-commits] [llvm] r60632 - /llvm/trunk/lib/Target/X86/README.txt Message-ID: <200812062249.mB6Mn6CM001816@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 6 16:49:05 2008 New Revision: 60632 URL: http://llvm.org/viewvc/llvm-project?rev=60632&view=rev Log: add a note Modified: llvm/trunk/lib/Target/X86/README.txt Modified: llvm/trunk/lib/Target/X86/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/README.txt?rev=60632&r1=60631&r2=60632&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README.txt (original) +++ llvm/trunk/lib/Target/X86/README.txt Sat Dec 6 16:49:05 2008 @@ -1816,3 +1816,18 @@ A similar code sequence works for division. //===---------------------------------------------------------------------===// + +These should compile to the same code, but the later codegen's to useless +instructions on X86. This may be a trivial dag combine (GCC PR7061): + +struct s1 { unsigned char a, b; }; +unsigned long f1(struct s1 x) { + return x.a + x.b; +} +struct s2 { unsigned a: 8, b: 8; }; +unsigned long f2(struct s2 x) { + return x.a + x.b; +} + +//===---------------------------------------------------------------------===// + From sabre at nondot.org Sat Dec 6 16:52:13 2008 From: sabre at nondot.org (Chris Lattner) Date: Sat, 06 Dec 2008 22:52:13 -0000 Subject: [llvm-commits] [llvm] r60633 - /llvm/trunk/lib/Target/README.txt Message-ID: <200812062252.mB6MqDvZ001903@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 6 16:52:12 2008 New Revision: 60633 URL: http://llvm.org/viewvc/llvm-project?rev=60633&view=rev Log: some more PRE/GVN/DSE related notes. Modified: llvm/trunk/lib/Target/README.txt Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=60633&r1=60632&r2=60633&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Sat Dec 6 16:52:12 2008 @@ -1307,6 +1307,9 @@ DSE should sink partially dead stores to get the store out of the loop. +Here's another partial dead case: +http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12395 + //===---------------------------------------------------------------------===// Scalar PRE hoists the mul in the common block up to the else: @@ -1367,6 +1370,54 @@ %11 is fully redundant, an in BB2 it should have the value %8. +GCC PR33344 is a similar case. + +//===---------------------------------------------------------------------===// + +There are many load PRE testcases in testsuite/gcc.dg/tree-ssa/loadpre* in the +GCC testsuite. There are many pre testcases as ssa-pre-*.c + +Other simple load PRE cases: +http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35287 +http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34677 (licm does this) +http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29789 (SPEC2K6) +http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23455 +http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14705 + +//===---------------------------------------------------------------------===// + +When GVN/PRE finds a store of float* to a must aliases pointer when expecting +an int*, it should turn it into a bitcast. This is a nice generalization of +the SROA hack that would apply to other cases. + +One example (that requires crazy phi translation) is: +http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16799 + //===---------------------------------------------------------------------===// +A/B get pinned to the stack because we turn an if/then into a select instead +of PRE'ing the load/store. This may be fixable in instcombine: +http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37892 + +Interesting missed case because of control flow flattening (should be 2 loads): +http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26629 + + +//===---------------------------------------------------------------------===// + +http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19633 +We could eliminate the branch condition here, loading from null is undefined: + +struct S { int w, x, y, z; }; +struct T { int r; struct S s; }; +void bar (struct S, int); +void foo (int a, struct T b) +{ + struct S *c = 0; + if (a) + c = &b.s; + bar (*c, a); +} + +//===---------------------------------------------------------------------===// From sabre at nondot.org Sat Dec 6 18:15:12 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 07 Dec 2008 00:15:12 -0000 Subject: [llvm-commits] [llvm] r60636 - /llvm/trunk/lib/Target/README.txt Message-ID: <200812070015.mB70FChW004383@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 6 18:15:10 2008 New Revision: 60636 URL: http://llvm.org/viewvc/llvm-project?rev=60636&view=rev Log: improve a note. Modified: llvm/trunk/lib/Target/README.txt Modified: llvm/trunk/lib/Target/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=60636&r1=60635&r2=60636&view=diff ============================================================================== --- llvm/trunk/lib/Target/README.txt (original) +++ llvm/trunk/lib/Target/README.txt Sat Dec 6 18:15:10 2008 @@ -1388,7 +1388,18 @@ When GVN/PRE finds a store of float* to a must aliases pointer when expecting an int*, it should turn it into a bitcast. This is a nice generalization of -the SROA hack that would apply to other cases. +the SROA hack that would apply to other cases, e.g.: + +int foo(int C, int *P, float X) { + if (C) { + bar(); + *P = 42; + } else + *(float*)P = X; + + return *P; +} + One example (that requires crazy phi translation) is: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16799 From sabre at nondot.org Sat Dec 6 18:16:50 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 07 Dec 2008 00:16:50 -0000 Subject: [llvm-commits] [llvm] r60637 - /llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Message-ID: <200812070016.mB70GooF004448@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 6 18:16:50 2008 New Revision: 60637 URL: http://llvm.org/viewvc/llvm-project?rev=60637&view=rev Log: make getDependencyFrom private. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60637&r1=60636&r2=60637&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Sat Dec 6 18:16:50 2008 @@ -200,16 +200,6 @@ /// this on non-memory instructions. MemDepResult getDependency(Instruction *QueryInst); - /// getDependencyFrom - Return the instruction on which the memory operation - /// 'QueryInst' depends. This starts scanning from the instruction before - /// the position indicated by ScanIt. - /// - /// Note that this method does no caching at all. You should use - /// getDependency where possible. - MemDepResult getDependencyFrom(Instruction *QueryInst, - BasicBlock::iterator ScanIt, BasicBlock *BB); - - /// getNonLocalDependency - Perform a full dependency query for the /// specified instruction, returning the set of blocks that the value is /// potentially live across. The returned set of results will include a @@ -229,6 +219,16 @@ void removeInstruction(Instruction *InstToRemove); private: + + /// getDependencyFrom - Return the instruction on which the memory operation + /// 'QueryInst' depends. This starts scanning from the instruction before + /// the position indicated by ScanIt. + /// + /// Note that this method does no caching at all. You should use + /// getDependency where possible. + MemDepResult getDependencyFrom(Instruction *QueryInst, + BasicBlock::iterator ScanIt, BasicBlock *BB); + /// verifyRemoved - Verify that the specified instruction does not occur /// in our internal data structures. void verifyRemoved(Instruction *Inst) const; From sabre at nondot.org Sat Dec 6 18:21:18 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 07 Dec 2008 00:21:18 -0000 Subject: [llvm-commits] [llvm] r60639 - /llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200812070021.mB70LIFQ004621@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 6 18:21:18 2008 New Revision: 60639 URL: http://llvm.org/viewvc/llvm-project?rev=60639&view=rev Log: remove the ability to get memdep info for vaarg. I don't think the original impl was correct and noone actually makes the query anyway. Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60639&r1=60638&r2=60639&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Dec 6 18:21:18 2008 @@ -109,6 +109,10 @@ MemDepResult MemoryDependenceAnalysis:: getDependencyFrom(Instruction *QueryInst, BasicBlock::iterator ScanIt, BasicBlock *BB) { + // The first instruction in a block is always non-local. + if (ScanIt == BB->begin()) + return MemDepResult::getNonLocal(); + // Get the pointer value for which dependence will be determined Value *MemPtr = 0; uint64_t MemSize = 0; @@ -122,17 +126,16 @@ MemPtr = LI->getPointerOperand(); MemSize = TD->getTypeStoreSize(LI->getType()); MemVolatile = LI->isVolatile(); - } else if (VAArgInst* V = dyn_cast(QueryInst)) { - MemPtr = V->getOperand(0); - MemSize = TD->getTypeStoreSize(V->getType()); } else if (FreeInst* F = dyn_cast(QueryInst)) { MemPtr = F->getPointerOperand(); // FreeInsts erase the entire structure, not just a field. MemSize = ~0UL; - } else { - assert((isa(QueryInst) || isa(QueryInst)) && - "Can only get dependency info for memory instructions!"); + } else if (isa(QueryInst) || isa(QueryInst)) { return getCallSiteDependency(CallSite::get(QueryInst), ScanIt, BB); + } else { + // Otherwise, this is a vaarg or non-memory instruction, just return a + // clobber dependency on the previous inst. + return MemDepResult::getClobber(--ScanIt); } // Walk backwards through the basic block, looking for dependencies From sabre at nondot.org Sat Dec 6 18:25:15 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 07 Dec 2008 00:25:15 -0000 Subject: [llvm-commits] [llvm] r60640 - /llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Message-ID: <200812070025.mB70PFkR004788@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 6 18:25:15 2008 New Revision: 60640 URL: http://llvm.org/viewvc/llvm-project?rev=60640&view=rev Log: don't bother touching volatile stores, they will just return clobber on everything interesting anyway. Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=60640&r1=60639&r2=60640&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Sat Dec 6 18:25:15 2008 @@ -90,6 +90,11 @@ // If we find a store or a free, get it's memory dependence. if (!isa(Inst) && !isa(Inst)) continue; + + // Don't molest volatile stores or do queries that will return "clobber". + if (StoreInst *SI = dyn_cast(Inst)) + if (SI->isVolatile()) + continue; MemDepResult InstDep = MD.getDependency(Inst); From sabre at nondot.org Sat Dec 6 18:28:02 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 07 Dec 2008 00:28:02 -0000 Subject: [llvm-commits] [llvm] r60641 - /llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200812070028.mB70S291004874@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 6 18:28:02 2008 New Revision: 60641 URL: http://llvm.org/viewvc/llvm-project?rev=60641&view=rev Log: a memdep query on a volatile load/store will always return clobber with the current implementation. Instead of returning a "precise clobber" just return a fuzzy one. This doesn't matter to any clients anyway and should speed up analysis time very very slightly. Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60641&r1=60640&r2=60641&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Dec 6 18:28:02 2008 @@ -116,16 +116,23 @@ // Get the pointer value for which dependence will be determined Value *MemPtr = 0; uint64_t MemSize = 0; - bool MemVolatile = false; if (StoreInst* S = dyn_cast(QueryInst)) { + // If this is a volatile store, don't mess around with it. Just return the + // previous instruction as a clobber. + if (S->isVolatile()) + return MemDepResult::getClobber(--ScanIt); + MemPtr = S->getPointerOperand(); MemSize = TD->getTypeStoreSize(S->getOperand(0)->getType()); - MemVolatile = S->isVolatile(); } else if (LoadInst* LI = dyn_cast(QueryInst)) { + // If this is a volatile load, don't mess around with it. Just return the + // previous instruction as a clobber. + if (S->isVolatile()) + return MemDepResult::getClobber(--ScanIt); + MemPtr = LI->getPointerOperand(); MemSize = TD->getTypeStoreSize(LI->getType()); - MemVolatile = LI->isVolatile(); } else if (FreeInst* F = dyn_cast(QueryInst)) { MemPtr = F->getPointerOperand(); // FreeInsts erase the entire structure, not just a field. @@ -145,10 +152,6 @@ // Values depend on loads if the pointers are must aliased. This means that // a load depends on another must aliased load from the same value. if (LoadInst *LI = dyn_cast(Inst)) { - // If the access is volatile and this is volatile, return a dependence. - if (MemVolatile && LI->isVolatile()) - return MemDepResult::getClobber(LI); - Value *Pointer = LI->getPointerOperand(); uint64_t PointerSize = TD->getTypeStoreSize(LI->getType()); @@ -165,10 +168,6 @@ } if (StoreInst *SI = dyn_cast(Inst)) { - // If the access is volatile and this is volatile, return a dependence. - if (MemVolatile && SI->isVolatile()) - return MemDepResult::getClobber(SI); - Value *Pointer = SI->getPointerOperand(); uint64_t PointerSize = TD->getTypeStoreSize(SI->getOperand(0)->getType()); From sabre at nondot.org Sat Dec 6 18:35:52 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 07 Dec 2008 00:35:52 -0000 Subject: [llvm-commits] [llvm] r60642 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200812070035.mB70Zq0w005088@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 6 18:35:51 2008 New Revision: 60642 URL: http://llvm.org/viewvc/llvm-project?rev=60642&view=rev Log: Rename getCallSiteDependency -> getCallSiteDependencyFrom to emphasize the scanning and make it more similar to getDependencyFrom Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60642&r1=60641&r2=60642&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Sat Dec 6 18:35:51 2008 @@ -223,18 +223,16 @@ /// getDependencyFrom - Return the instruction on which the memory operation /// 'QueryInst' depends. This starts scanning from the instruction before /// the position indicated by ScanIt. - /// - /// Note that this method does no caching at all. You should use - /// getDependency where possible. MemDepResult getDependencyFrom(Instruction *QueryInst, BasicBlock::iterator ScanIt, BasicBlock *BB); + MemDepResult getCallSiteDependencyFrom(CallSite C, + BasicBlock::iterator ScanIt, + BasicBlock *BB); /// verifyRemoved - Verify that the specified instruction does not occur /// in our internal data structures. void verifyRemoved(Instruction *Inst) const; - MemDepResult getCallSiteDependency(CallSite C, BasicBlock::iterator ScanIt, - BasicBlock *BB); }; } // End llvm namespace Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60642&r1=60641&r2=60642&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Dec 6 18:35:51 2008 @@ -52,10 +52,11 @@ } -/// getCallSiteDependency - Private helper for finding the local dependencies -/// of a call site. +/// getCallSiteDependencyFrom - Private helper for finding the local +/// dependencies of a call site. MemDepResult MemoryDependenceAnalysis:: -getCallSiteDependency(CallSite CS, BasicBlock::iterator ScanIt, BasicBlock *BB) { +getCallSiteDependencyFrom(CallSite CS, BasicBlock::iterator ScanIt, + BasicBlock *BB) { // Walk backwards through the block, looking for dependencies while (ScanIt != BB->begin()) { Instruction *Inst = --ScanIt; @@ -138,7 +139,7 @@ // FreeInsts erase the entire structure, not just a field. MemSize = ~0UL; } else if (isa(QueryInst) || isa(QueryInst)) { - return getCallSiteDependency(CallSite::get(QueryInst), ScanIt, BB); + return getCallSiteDependencyFrom(CallSite::get(QueryInst), ScanIt, BB); } else { // Otherwise, this is a vaarg or non-memory instruction, just return a // clobber dependency on the previous inst. From sabre at nondot.org Sat Dec 6 18:38:27 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 07 Dec 2008 00:38:27 -0000 Subject: [llvm-commits] [llvm] r60643 - /llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200812070038.mB70cRB1005164@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 6 18:38:27 2008 New Revision: 60643 URL: http://llvm.org/viewvc/llvm-project?rev=60643&view=rev Log: I love how using out of scope variables is not an error with GCC, no really I do. Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60643&r1=60642&r2=60643&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Dec 6 18:38:27 2008 @@ -118,7 +118,7 @@ Value *MemPtr = 0; uint64_t MemSize = 0; - if (StoreInst* S = dyn_cast(QueryInst)) { + if (StoreInst *S = dyn_cast(QueryInst)) { // If this is a volatile store, don't mess around with it. Just return the // previous instruction as a clobber. if (S->isVolatile()) @@ -126,10 +126,10 @@ MemPtr = S->getPointerOperand(); MemSize = TD->getTypeStoreSize(S->getOperand(0)->getType()); - } else if (LoadInst* LI = dyn_cast(QueryInst)) { + } else if (LoadInst *LI = dyn_cast(QueryInst)) { // If this is a volatile load, don't mess around with it. Just return the // previous instruction as a clobber. - if (S->isVolatile()) + if (LI->isVolatile()) return MemDepResult::getClobber(--ScanIt); MemPtr = LI->getPointerOperand(); From sabre at nondot.org Sat Dec 6 18:39:19 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 07 Dec 2008 00:39:19 -0000 Subject: [llvm-commits] [llvm] r60644 - /llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200812070039.mB70dJq9005195@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 6 18:39:19 2008 New Revision: 60644 URL: http://llvm.org/viewvc/llvm-project?rev=60644&view=rev Log: rename some variables for consistency Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60644&r1=60643&r2=60644&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Dec 6 18:39:19 2008 @@ -118,14 +118,14 @@ Value *MemPtr = 0; uint64_t MemSize = 0; - if (StoreInst *S = dyn_cast(QueryInst)) { + if (StoreInst *SI = dyn_cast(QueryInst)) { // If this is a volatile store, don't mess around with it. Just return the // previous instruction as a clobber. - if (S->isVolatile()) + if (SI->isVolatile()) return MemDepResult::getClobber(--ScanIt); - MemPtr = S->getPointerOperand(); - MemSize = TD->getTypeStoreSize(S->getOperand(0)->getType()); + MemPtr = SI->getPointerOperand(); + MemSize = TD->getTypeStoreSize(SI->getOperand(0)->getType()); } else if (LoadInst *LI = dyn_cast(QueryInst)) { // If this is a volatile load, don't mess around with it. Just return the // previous instruction as a clobber. @@ -134,8 +134,8 @@ MemPtr = LI->getPointerOperand(); MemSize = TD->getTypeStoreSize(LI->getType()); - } else if (FreeInst* F = dyn_cast(QueryInst)) { - MemPtr = F->getPointerOperand(); + } else if (FreeInst *FI = dyn_cast(QueryInst)) { + MemPtr = FI->getPointerOperand(); // FreeInsts erase the entire structure, not just a field. MemSize = ~0UL; } else if (isa(QueryInst) || isa(QueryInst)) { From sabre at nondot.org Sat Dec 6 19:21:14 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 07 Dec 2008 01:21:14 -0000 Subject: [llvm-commits] [llvm] r60647 - /llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200812070121.mB71LEXv006415@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 6 19:21:14 2008 New Revision: 60647 URL: http://llvm.org/viewvc/llvm-project?rev=60647&view=rev Log: make clients have to know how to call getCallSiteDependencyFrom instead of making getDependencyFrom do it. Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60647&r1=60646&r2=60647&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Dec 6 19:21:14 2008 @@ -139,6 +139,7 @@ // FreeInsts erase the entire structure, not just a field. MemSize = ~0UL; } else if (isa(QueryInst) || isa(QueryInst)) { + assert(0 && "Should use getCallSiteDependencyFrom!"); return getCallSiteDependencyFrom(CallSite::get(QueryInst), ScanIt, BB); } else { // Otherwise, this is a vaarg or non-memory instruction, just return a @@ -233,7 +234,11 @@ } // Do the scan. - LocalCache = getDependencyFrom(QueryInst, ScanPos, QueryInst->getParent()); + if (!isa(QueryInst) && !isa(QueryInst)) + LocalCache = getDependencyFrom(QueryInst, ScanPos, QueryInst->getParent()); + else + LocalCache = getCallSiteDependencyFrom(CallSite::get(QueryInst), ScanPos, + QueryInst->getParent()); // Remember the result! if (Instruction *I = LocalCache.getInst()) @@ -341,7 +346,12 @@ } // Find out if this block has a local dependency for QueryInst. - MemDepResult Dep = getDependencyFrom(QueryInst, ScanPos, DirtyBB); + MemDepResult Dep; + if (!isa(QueryInst) && !isa(QueryInst)) + Dep = getDependencyFrom(QueryInst, ScanPos, DirtyBB); + else + Dep = getCallSiteDependencyFrom(CallSite::get(QueryInst), ScanPos, + DirtyBB); // If we had a dirty entry for the block, update it. Otherwise, just add // a new entry. @@ -368,6 +378,7 @@ return Cache; } + /// removeInstruction - Remove an instruction from the dependence analysis, /// updating the dependence of instructions that previously depended on it. /// This method attempts to keep the cache coherent using the reverse map. From sabre at nondot.org Sat Dec 6 19:50:17 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 07 Dec 2008 01:50:17 -0000 Subject: [llvm-commits] [llvm] r60648 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200812070150.mB71oH8b007175@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 6 19:50:16 2008 New Revision: 60648 URL: http://llvm.org/viewvc/llvm-project?rev=60648&view=rev Log: push the "pointer case" up the analysis stack a bit. This causes duplication of logic (in 2 places) to determine what pointer a load/store touches. This will be addressed in a future commit. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60648&r1=60647&r2=60648&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Sat Dec 6 19:50:16 2008 @@ -220,11 +220,13 @@ private: - /// getDependencyFrom - Return the instruction on which the memory operation - /// 'QueryInst' depends. This starts scanning from the instruction before + /// getDependencyFrom - Return the instruction on which the memory location + /// '*Pointer' depends. This starts scanning from the instruction before /// the position indicated by ScanIt. - MemDepResult getDependencyFrom(Instruction *QueryInst, - BasicBlock::iterator ScanIt, BasicBlock *BB); + MemDepResult getPointerDependencyFrom(Value *Pointer, uint64_t MemSize, + bool isLoad, + BasicBlock::iterator ScanIt, + BasicBlock *BB); MemDepResult getCallSiteDependencyFrom(CallSite C, BasicBlock::iterator ScanIt, BasicBlock *BB); Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60648&r1=60647&r2=60648&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Dec 6 19:50:16 2008 @@ -105,48 +105,16 @@ return MemDepResult::getNonLocal(); } -/// getDependencyFrom - Return the instruction on which a memory operation -/// depends. +/// getPointerDependencyFrom - Return the instruction on which a memory +/// location depends. If isLoad is true, this routine ignore may-aliases with +/// read-only operations. MemDepResult MemoryDependenceAnalysis:: -getDependencyFrom(Instruction *QueryInst, BasicBlock::iterator ScanIt, - BasicBlock *BB) { +getPointerDependencyFrom(Value *MemPtr, uint64_t MemSize, bool isLoad, + BasicBlock::iterator ScanIt, BasicBlock *BB) { // The first instruction in a block is always non-local. if (ScanIt == BB->begin()) return MemDepResult::getNonLocal(); - // Get the pointer value for which dependence will be determined - Value *MemPtr = 0; - uint64_t MemSize = 0; - - if (StoreInst *SI = dyn_cast(QueryInst)) { - // If this is a volatile store, don't mess around with it. Just return the - // previous instruction as a clobber. - if (SI->isVolatile()) - return MemDepResult::getClobber(--ScanIt); - - MemPtr = SI->getPointerOperand(); - MemSize = TD->getTypeStoreSize(SI->getOperand(0)->getType()); - } else if (LoadInst *LI = dyn_cast(QueryInst)) { - // If this is a volatile load, don't mess around with it. Just return the - // previous instruction as a clobber. - if (LI->isVolatile()) - return MemDepResult::getClobber(--ScanIt); - - MemPtr = LI->getPointerOperand(); - MemSize = TD->getTypeStoreSize(LI->getType()); - } else if (FreeInst *FI = dyn_cast(QueryInst)) { - MemPtr = FI->getPointerOperand(); - // FreeInsts erase the entire structure, not just a field. - MemSize = ~0UL; - } else if (isa(QueryInst) || isa(QueryInst)) { - assert(0 && "Should use getCallSiteDependencyFrom!"); - return getCallSiteDependencyFrom(CallSite::get(QueryInst), ScanIt, BB); - } else { - // Otherwise, this is a vaarg or non-memory instruction, just return a - // clobber dependency on the previous inst. - return MemDepResult::getClobber(--ScanIt); - } - // Walk backwards through the basic block, looking for dependencies while (ScanIt != BB->begin()) { Instruction *Inst = --ScanIt; @@ -164,7 +132,7 @@ continue; // May-alias loads don't depend on each other without a dependence. - if (isa(QueryInst) && R == AliasAnalysis::MayAlias) + if (isLoad && R == AliasAnalysis::MayAlias) continue; return MemDepResult::getDef(Inst); } @@ -198,6 +166,7 @@ } // See if this instruction (e.g. a call or vaarg) mod/ref's the pointer. + // FIXME: If this is a load, we should ignore readonly calls! if (AA->getModRefInfo(Inst, MemPtr, MemSize) == AliasAnalysis::NoModRef) continue; @@ -233,12 +202,50 @@ ReverseLocalDeps.erase(Inst); } + BasicBlock *QueryParent = QueryInst->getParent(); + + Value *MemPtr = 0; + uint64_t MemSize = 0; + // Do the scan. - if (!isa(QueryInst) && !isa(QueryInst)) - LocalCache = getDependencyFrom(QueryInst, ScanPos, QueryInst->getParent()); - else + if (BasicBlock::iterator(QueryInst) == QueryParent->begin()) { + // First instruction in the block -> non local. + LocalCache = MemDepResult::getNonLocal(); + } else if (StoreInst *SI = dyn_cast(QueryInst)) { + // If this is a volatile store, don't mess around with it. Just return the + // previous instruction as a clobber. + if (SI->isVolatile()) + LocalCache = MemDepResult::getClobber(--BasicBlock::iterator(ScanPos)); + else { + MemPtr = SI->getPointerOperand(); + MemSize = TD->getTypeStoreSize(SI->getOperand(0)->getType()); + } + } else if (LoadInst *LI = dyn_cast(QueryInst)) { + // If this is a volatile load, don't mess around with it. Just return the + // previous instruction as a clobber. + if (LI->isVolatile()) + LocalCache = MemDepResult::getClobber(--BasicBlock::iterator(ScanPos)); + else { + MemPtr = LI->getPointerOperand(); + MemSize = TD->getTypeStoreSize(LI->getType()); + } + } else if (isa(QueryInst) || isa(QueryInst)) { LocalCache = getCallSiteDependencyFrom(CallSite::get(QueryInst), ScanPos, - QueryInst->getParent()); + QueryParent); + } else if (FreeInst *FI = dyn_cast(QueryInst)) { + MemPtr = FI->getPointerOperand(); + // FreeInsts erase the entire structure, not just a field. + MemSize = ~0UL; + } else { + // Non-memory instruction. + LocalCache = MemDepResult::getClobber(--BasicBlock::iterator(ScanPos)); + } + + // If we need to do a pointer scan, make it happen. + if (MemPtr) + LocalCache = getPointerDependencyFrom(MemPtr, MemSize, + isa(QueryInst), + ScanPos, QueryParent); // Remember the result! if (Instruction *I = LocalCache.getInst()) @@ -257,10 +264,11 @@ /// const MemoryDependenceAnalysis::NonLocalDepInfo & MemoryDependenceAnalysis::getNonLocalDependency(Instruction *QueryInst) { + assert(isa(QueryInst) || isa(QueryInst) || + isa(QueryInst) || isa(QueryInst)); assert(getDependency(QueryInst).isNonLocal() && "getNonLocalDependency should only be used on insts with non-local deps!"); PerInstNLInfo &CacheP = NonLocalDeps[QueryInst]; - NonLocalDepInfo &Cache = CacheP.first; /// DirtyBlocks - This is the set of blocks that need to be recomputed. In @@ -347,11 +355,40 @@ // Find out if this block has a local dependency for QueryInst. MemDepResult Dep; - if (!isa(QueryInst) && !isa(QueryInst)) - Dep = getDependencyFrom(QueryInst, ScanPos, DirtyBB); - else + + Value *MemPtr = 0; + uint64_t MemSize = 0; + + if (BasicBlock::iterator(QueryInst) == DirtyBB->begin()) { + // First instruction in the block -> non local. + Dep = MemDepResult::getNonLocal(); + } else if (StoreInst *SI = dyn_cast(QueryInst)) { + // If this is a volatile store, don't mess around with it. Just return the + // previous instruction as a clobber. + if (SI->isVolatile()) + Dep = MemDepResult::getClobber(--BasicBlock::iterator(ScanPos)); + else { + MemPtr = SI->getPointerOperand(); + MemSize = TD->getTypeStoreSize(SI->getOperand(0)->getType()); + } + } else if (LoadInst *LI = dyn_cast(QueryInst)) { + // If this is a volatile load, don't mess around with it. Just return the + // previous instruction as a clobber. + if (LI->isVolatile()) + Dep = MemDepResult::getClobber(--BasicBlock::iterator(ScanPos)); + else { + MemPtr = LI->getPointerOperand(); + MemSize = TD->getTypeStoreSize(LI->getType()); + } + } else { + assert(isa(QueryInst) || isa(QueryInst)); Dep = getCallSiteDependencyFrom(CallSite::get(QueryInst), ScanPos, DirtyBB); + } + + if (MemPtr) + Dep = getPointerDependencyFrom(MemPtr, MemSize, isa(QueryInst), + ScanPos, DirtyBB); // If we had a dirty entry for the block, update it. Otherwise, just add // a new entry. @@ -378,7 +415,6 @@ return Cache; } - /// removeInstruction - Remove an instruction from the dependence analysis, /// updating the dependence of instructions that previously depended on it. /// This method attempts to keep the cache coherent using the reverse map. From sabre at nondot.org Sat Dec 6 20:15:48 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 07 Dec 2008 02:15:48 -0000 Subject: [llvm-commits] [llvm] r60649 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200812070215.mB72Fmch007932@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 6 20:15:47 2008 New Revision: 60649 URL: http://llvm.org/viewvc/llvm-project?rev=60649&view=rev Log: Introduce a new MemDep::getNonLocalPointerDependency method. This will eventually take over load/store dep queries from getNonLocalDependency. For now it works fine, but is incredibly slow because it does no caching. Lets not switch GVN to use it until that is fixed :) Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60649&r1=60648&r2=60649&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Sat Dec 6 20:15:47 2008 @@ -214,6 +214,18 @@ /// that. const NonLocalDepInfo &getNonLocalDependency(Instruction *QueryInst); + + /// getNonLocalPointerDependency - Perform a full dependency query for an + /// access to the specified (non-volatile) memory location, returning the + /// set of instructions that either define or clobber the value. + /// + /// This method assumes the pointer has a "NonLocal" dependency within BB + /// and assumes that Result is empty when you call it. + /// + void getNonLocalPointerDependency(Value *Pointer, bool isLoad, + BasicBlock *BB, + SmallVectorImpl &Result); + /// removeInstruction - Remove an instruction from the dependence analysis, /// updating the dependence of instructions that previously depended on it. void removeInstruction(Instruction *InstToRemove); Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60649&r1=60648&r2=60649&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Dec 6 20:15:47 2008 @@ -101,8 +101,11 @@ return MemDepResult::getClobber(Inst); } - // No dependence found. - return MemDepResult::getNonLocal(); + // No dependence found. If this is the entry block of the function, it is a + // clobber, otherwise it is non-local. + if (BB != &BB->getParent()->getEntryBlock()) + return MemDepResult::getNonLocal(); + return MemDepResult::getClobber(ScanIt); } /// getPointerDependencyFrom - Return the instruction on which a memory @@ -111,10 +114,7 @@ MemDepResult MemoryDependenceAnalysis:: getPointerDependencyFrom(Value *MemPtr, uint64_t MemSize, bool isLoad, BasicBlock::iterator ScanIt, BasicBlock *BB) { - // The first instruction in a block is always non-local. - if (ScanIt == BB->begin()) - return MemDepResult::getNonLocal(); - + // Walk backwards through the basic block, looking for dependencies while (ScanIt != BB->begin()) { Instruction *Inst = --ScanIt; @@ -174,8 +174,11 @@ return MemDepResult::getClobber(Inst); } - // If we found nothing, return the non-local flag. - return MemDepResult::getNonLocal(); + // No dependence found. If this is the entry block of the function, it is a + // clobber, otherwise it is non-local. + if (BB != &BB->getParent()->getEntryBlock()) + return MemDepResult::getNonLocal(); + return MemDepResult::getClobber(ScanIt); } /// getDependency - Return the instruction on which a memory operation @@ -209,8 +212,12 @@ // Do the scan. if (BasicBlock::iterator(QueryInst) == QueryParent->begin()) { - // First instruction in the block -> non local. - LocalCache = MemDepResult::getNonLocal(); + // No dependence found. If this is the entry block of the function, it is a + // clobber, otherwise it is non-local. + if (QueryParent != &QueryParent->getParent()->getEntryBlock()) + LocalCache = MemDepResult::getNonLocal(); + else + LocalCache = MemDepResult::getClobber(QueryInst); } else if (StoreInst *SI = dyn_cast(QueryInst)) { // If this is a volatile store, don't mess around with it. Just return the // previous instruction as a clobber. @@ -264,6 +271,7 @@ /// const MemoryDependenceAnalysis::NonLocalDepInfo & MemoryDependenceAnalysis::getNonLocalDependency(Instruction *QueryInst) { + // FIXME: Make this only be for callsites in the future. assert(isa(QueryInst) || isa(QueryInst) || isa(QueryInst) || isa(QueryInst)); assert(getDependency(QueryInst).isNonLocal() && @@ -359,9 +367,13 @@ Value *MemPtr = 0; uint64_t MemSize = 0; - if (BasicBlock::iterator(QueryInst) == DirtyBB->begin()) { - // First instruction in the block -> non local. - Dep = MemDepResult::getNonLocal(); + if (ScanPos == DirtyBB->begin()) { + // No dependence found. If this is the entry block of the function, it is a + // clobber, otherwise it is non-local. + if (DirtyBB != &DirtyBB->getParent()->getEntryBlock()) + Dep = MemDepResult::getNonLocal(); + else + Dep = MemDepResult::getClobber(ScanPos); } else if (StoreInst *SI = dyn_cast(QueryInst)) { // If this is a volatile store, don't mess around with it. Just return the // previous instruction as a clobber. @@ -415,6 +427,63 @@ return Cache; } +/// getNonLocalPointerDependency - Perform a full dependency query for an +/// access to the specified (non-volatile) memory location, returning the +/// set of instructions that either define or clobber the value. +/// +/// This method assumes the pointer has a "NonLocal" dependency within its +/// own block. +/// +void MemoryDependenceAnalysis:: +getNonLocalPointerDependency(Value *Pointer, bool isLoad, BasicBlock *FromBB, + SmallVectorImpl &Result) { + // We know that the pointer value is live into FromBB find the def/clobbers + // from presecessors. + SmallVector, 32> Worklist; + + for (pred_iterator PI = pred_begin(FromBB), E = pred_end(FromBB); PI != E; + ++PI) + // TODO: PHI TRANSLATE. + Worklist.push_back(std::make_pair(*PI, Pointer)); + + const Type *EltTy = cast(Pointer->getType())->getElementType(); + uint64_t PointeeSize = TD->getTypeStoreSize(EltTy); + + // While we have blocks to analyze, get their values. + SmallPtrSet Visited; + while (!Worklist.empty()) { + FromBB = Worklist.back().first; + Pointer = Worklist.back().second; + Worklist.pop_back(); + + // Analyze the dependency of *Pointer in FromBB. See if we already have + // been here. + if (!Visited.insert(FromBB)) + continue; + + // FIXME: CACHE! + + MemDepResult Dep = + getPointerDependencyFrom(Pointer, PointeeSize, isLoad, + FromBB->end(), FromBB); + + // If we got a Def or Clobber, add this to the list of results. + if (!Dep.isNonLocal()) { + Result.push_back(NonLocalDepEntry(FromBB, Dep)); + continue; + } + + // Otherwise, we have to process all the predecessors of this block to scan + // them as well. + for (pred_iterator PI = pred_begin(FromBB), E = pred_end(FromBB); PI != E; + ++PI) + // TODO: PHI TRANSLATE. + Worklist.push_back(std::make_pair(*PI, Pointer)); + } +} + + + /// removeInstruction - Remove an instruction from the dependence analysis, /// updating the dependence of instructions that previously depended on it. /// This method attempts to keep the cache coherent using the reverse map. From sabre at nondot.org Sat Dec 6 20:56:57 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 07 Dec 2008 02:56:57 -0000 Subject: [llvm-commits] [llvm] r60650 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200812070256.mB72uwqG009000@zion.cs.uiuc.edu> Author: lattner Date: Sat Dec 6 20:56:57 2008 New Revision: 60650 URL: http://llvm.org/viewvc/llvm-project?rev=60650&view=rev Log: Some internal refactoring to make it easier to cache results. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60650&r1=60649&r2=60650&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Sat Dec 6 20:56:57 2008 @@ -151,7 +151,7 @@ typedef std::pair NonLocalDepEntry; typedef std::vector NonLocalDepInfo; private: - + /// PerInstNLInfo - This is the instruction we keep for each cached access /// that we have for an instruction. The pointer is an owning pointer and /// the bool indicates whether we have any dirty bits in the set. @@ -219,9 +219,7 @@ /// access to the specified (non-volatile) memory location, returning the /// set of instructions that either define or clobber the value. /// - /// This method assumes the pointer has a "NonLocal" dependency within BB - /// and assumes that Result is empty when you call it. - /// + /// This method assumes the pointer has a "NonLocal" dependency within BB. void getNonLocalPointerDependency(Value *Pointer, bool isLoad, BasicBlock *BB, SmallVectorImpl &Result); @@ -243,6 +241,12 @@ BasicBlock::iterator ScanIt, BasicBlock *BB); + void getNonLocalPointerDepInternal(Value *Pointer, uint64_t Size, + bool isLoad, BasicBlock *BB, + SmallVectorImpl &Result, + SmallPtrSet &Visited); + + /// verifyRemoved - Verify that the specified instruction does not occur /// in our internal data structures. void verifyRemoved(Instruction *Inst) const; Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60650&r1=60649&r2=60650&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Dec 6 20:56:57 2008 @@ -437,53 +437,62 @@ void MemoryDependenceAnalysis:: getNonLocalPointerDependency(Value *Pointer, bool isLoad, BasicBlock *FromBB, SmallVectorImpl &Result) { + Result.clear(); + // We know that the pointer value is live into FromBB find the def/clobbers // from presecessors. - SmallVector, 32> Worklist; - - for (pred_iterator PI = pred_begin(FromBB), E = pred_end(FromBB); PI != E; - ++PI) - // TODO: PHI TRANSLATE. - Worklist.push_back(std::make_pair(*PI, Pointer)); const Type *EltTy = cast(Pointer->getType())->getElementType(); uint64_t PointeeSize = TD->getTypeStoreSize(EltTy); // While we have blocks to analyze, get their values. SmallPtrSet Visited; + + for (pred_iterator PI = pred_begin(FromBB), E = pred_end(FromBB); PI != E; + ++PI) { + // TODO: PHI TRANSLATE. + getNonLocalPointerDepInternal(Pointer, PointeeSize, isLoad, *PI, + Result, Visited); + } +} + +void MemoryDependenceAnalysis:: +getNonLocalPointerDepInternal(Value *Pointer, uint64_t PointeeSize, + bool isLoad, BasicBlock *StartBB, + SmallVectorImpl &Result, + SmallPtrSet &Visited) { + SmallVector Worklist; + Worklist.push_back(StartBB); + while (!Worklist.empty()) { - FromBB = Worklist.back().first; - Pointer = Worklist.back().second; - Worklist.pop_back(); + BasicBlock *BB = Worklist.pop_back_val(); // Analyze the dependency of *Pointer in FromBB. See if we already have // been here. - if (!Visited.insert(FromBB)) + if (!Visited.insert(BB)) continue; // FIXME: CACHE! MemDepResult Dep = - getPointerDependencyFrom(Pointer, PointeeSize, isLoad, - FromBB->end(), FromBB); + getPointerDependencyFrom(Pointer, PointeeSize, isLoad, BB->end(), BB); // If we got a Def or Clobber, add this to the list of results. if (!Dep.isNonLocal()) { - Result.push_back(NonLocalDepEntry(FromBB, Dep)); + Result.push_back(NonLocalDepEntry(BB, Dep)); continue; } // Otherwise, we have to process all the predecessors of this block to scan // them as well. - for (pred_iterator PI = pred_begin(FromBB), E = pred_end(FromBB); PI != E; - ++PI) + for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) { // TODO: PHI TRANSLATE. - Worklist.push_back(std::make_pair(*PI, Pointer)); + Worklist.push_back(*PI); + } } } - /// removeInstruction - Remove an instruction from the dependence analysis, /// updating the dependence of instructions that previously depended on it. /// This method attempts to keep the cache coherent using the reverse map. From nicholas at mxc.ca Sat Dec 6 21:49:53 2008 From: nicholas at mxc.ca (Nick Lewycky) Date: Sun, 07 Dec 2008 03:49:53 -0000 Subject: [llvm-commits] [llvm] r60651 - in /llvm/trunk/lib/Target/X86: X86Instr64bit.td X86InstrInfo.td Message-ID: <200812070349.mB73nsHh010428@zion.cs.uiuc.edu> Author: nicholas Date: Sat Dec 6 21:49:52 2008 New Revision: 60651 URL: http://llvm.org/viewvc/llvm-project?rev=60651&view=rev Log: Fix typo, psuedo -> pseudo. Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td llvm/trunk/lib/Target/X86/X86InstrInfo.td Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Instr64bit.td?rev=60651&r1=60650&r2=60651&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Instr64bit.td (original) +++ llvm/trunk/lib/Target/X86/X86Instr64bit.td Sat Dec 6 21:49:52 2008 @@ -1181,28 +1181,28 @@ let Constraints = "$val = $dst", Defs = [EFLAGS], usesCustomDAGSchedInserter = 1 in { def ATOMAND64 : I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val), - "#ATOMAND64 PSUEDO!", + "#ATOMAND64 PSEUDO!", [(set GR64:$dst, (atomic_load_and_64 addr:$ptr, GR64:$val))]>; def ATOMOR64 : I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val), - "#ATOMOR64 PSUEDO!", + "#ATOMOR64 PSEUDO!", [(set GR64:$dst, (atomic_load_or_64 addr:$ptr, GR64:$val))]>; def ATOMXOR64 : I<0, Pseudo,(outs GR64:$dst),(ins i64mem:$ptr, GR64:$val), - "#ATOMXOR64 PSUEDO!", + "#ATOMXOR64 PSEUDO!", [(set GR64:$dst, (atomic_load_xor_64 addr:$ptr, GR64:$val))]>; def ATOMNAND64 : I<0, Pseudo,(outs GR64:$dst),(ins i64mem:$ptr, GR64:$val), - "#ATOMNAND64 PSUEDO!", + "#ATOMNAND64 PSEUDO!", [(set GR64:$dst, (atomic_load_nand_64 addr:$ptr, GR64:$val))]>; def ATOMMIN64: I<0, Pseudo, (outs GR64:$dst), (ins i64mem:$ptr, GR64:$val), - "#ATOMMIN64 PSUEDO!", + "#ATOMMIN64 PSEUDO!", [(set GR64:$dst, (atomic_load_min_64 addr:$ptr, GR64:$val))]>; def ATOMMAX64: I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val), - "#ATOMMAX64 PSUEDO!", + "#ATOMMAX64 PSEUDO!", [(set GR64:$dst, (atomic_load_max_64 addr:$ptr, GR64:$val))]>; def ATOMUMIN64: I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val), - "#ATOMUMIN64 PSUEDO!", + "#ATOMUMIN64 PSEUDO!", [(set GR64:$dst, (atomic_load_umin_64 addr:$ptr, GR64:$val))]>; def ATOMUMAX64: I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val), - "#ATOMUMAX64 PSUEDO!", + "#ATOMUMAX64 PSEUDO!", [(set GR64:$dst, (atomic_load_umax_64 addr:$ptr, GR64:$val))]>; } Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=60651&r1=60650&r2=60651&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Sat Dec 6 21:49:52 2008 @@ -2787,66 +2787,66 @@ let Constraints = "$val = $dst", Defs = [EFLAGS], usesCustomDAGSchedInserter = 1 in { def ATOMAND32 : I<0, Pseudo, (outs GR32:$dst),(ins i32mem:$ptr, GR32:$val), - "#ATOMAND32 PSUEDO!", + "#ATOMAND32 PSEUDO!", [(set GR32:$dst, (atomic_load_and_32 addr:$ptr, GR32:$val))]>; def ATOMOR32 : I<0, Pseudo, (outs GR32:$dst),(ins i32mem:$ptr, GR32:$val), - "#ATOMOR32 PSUEDO!", + "#ATOMOR32 PSEUDO!", [(set GR32:$dst, (atomic_load_or_32 addr:$ptr, GR32:$val))]>; def ATOMXOR32 : I<0, Pseudo,(outs GR32:$dst),(ins i32mem:$ptr, GR32:$val), - "#ATOMXOR32 PSUEDO!", + "#ATOMXOR32 PSEUDO!", [(set GR32:$dst, (atomic_load_xor_32 addr:$ptr, GR32:$val))]>; def ATOMNAND32 : I<0, Pseudo,(outs GR32:$dst),(ins i32mem:$ptr, GR32:$val), - "#ATOMNAND32 PSUEDO!", + "#ATOMNAND32 PSEUDO!", [(set GR32:$dst, (atomic_load_nand_32 addr:$ptr, GR32:$val))]>; def ATOMMIN32: I<0, Pseudo, (outs GR32:$dst), (ins i32mem:$ptr, GR32:$val), - "#ATOMMIN32 PSUEDO!", + "#ATOMMIN32 PSEUDO!", [(set GR32:$dst, (atomic_load_min_32 addr:$ptr, GR32:$val))]>; def ATOMMAX32: I<0, Pseudo, (outs GR32:$dst),(ins i32mem:$ptr, GR32:$val), - "#ATOMMAX32 PSUEDO!", + "#ATOMMAX32 PSEUDO!", [(set GR32:$dst, (atomic_load_max_32 addr:$ptr, GR32:$val))]>; def ATOMUMIN32: I<0, Pseudo, (outs GR32:$dst),(ins i32mem:$ptr, GR32:$val), - "#ATOMUMIN32 PSUEDO!", + "#ATOMUMIN32 PSEUDO!", [(set GR32:$dst, (atomic_load_umin_32 addr:$ptr, GR32:$val))]>; def ATOMUMAX32: I<0, Pseudo, (outs GR32:$dst),(ins i32mem:$ptr, GR32:$val), - "#ATOMUMAX32 PSUEDO!", + "#ATOMUMAX32 PSEUDO!", [(set GR32:$dst, (atomic_load_umax_32 addr:$ptr, GR32:$val))]>; def ATOMAND16 : I<0, Pseudo, (outs GR16:$dst),(ins i16mem:$ptr, GR16:$val), - "#ATOMAND16 PSUEDO!", + "#ATOMAND16 PSEUDO!", [(set GR16:$dst, (atomic_load_and_16 addr:$ptr, GR16:$val))]>; def ATOMOR16 : I<0, Pseudo, (outs GR16:$dst),(ins i16mem:$ptr, GR16:$val), - "#ATOMOR16 PSUEDO!", + "#ATOMOR16 PSEUDO!", [(set GR16:$dst, (atomic_load_or_16 addr:$ptr, GR16:$val))]>; def ATOMXOR16 : I<0, Pseudo,(outs GR16:$dst),(ins i16mem:$ptr, GR16:$val), - "#ATOMXOR16 PSUEDO!", + "#ATOMXOR16 PSEUDO!", [(set GR16:$dst, (atomic_load_xor_16 addr:$ptr, GR16:$val))]>; def ATOMNAND16 : I<0, Pseudo,(outs GR16:$dst),(ins i16mem:$ptr, GR16:$val), - "#ATOMNAND16 PSUEDO!", + "#ATOMNAND16 PSEUDO!", [(set GR16:$dst, (atomic_load_nand_16 addr:$ptr, GR16:$val))]>; def ATOMMIN16: I<0, Pseudo, (outs GR16:$dst), (ins i16mem:$ptr, GR16:$val), - "#ATOMMIN16 PSUEDO!", + "#ATOMMIN16 PSEUDO!", [(set GR16:$dst, (atomic_load_min_16 addr:$ptr, GR16:$val))]>; def ATOMMAX16: I<0, Pseudo, (outs GR16:$dst),(ins i16mem:$ptr, GR16:$val), - "#ATOMMAX16 PSUEDO!", + "#ATOMMAX16 PSEUDO!", [(set GR16:$dst, (atomic_load_max_16 addr:$ptr, GR16:$val))]>; def ATOMUMIN16: I<0, Pseudo, (outs GR16:$dst),(ins i16mem:$ptr, GR16:$val), - "#ATOMUMIN16 PSUEDO!", + "#ATOMUMIN16 PSEUDO!", [(set GR16:$dst, (atomic_load_umin_16 addr:$ptr, GR16:$val))]>; def ATOMUMAX16: I<0, Pseudo, (outs GR16:$dst),(ins i16mem:$ptr, GR16:$val), - "#ATOMUMAX16 PSUEDO!", + "#ATOMUMAX16 PSEUDO!", [(set GR16:$dst, (atomic_load_umax_16 addr:$ptr, GR16:$val))]>; def ATOMAND8 : I<0, Pseudo, (outs GR8:$dst),(ins i8mem:$ptr, GR8:$val), - "#ATOMAND8 PSUEDO!", + "#ATOMAND8 PSEUDO!", [(set GR8:$dst, (atomic_load_and_8 addr:$ptr, GR8:$val))]>; def ATOMOR8 : I<0, Pseudo, (outs GR8:$dst),(ins i8mem:$ptr, GR8:$val), - "#ATOMOR8 PSUEDO!", + "#ATOMOR8 PSEUDO!", [(set GR8:$dst, (atomic_load_or_8 addr:$ptr, GR8:$val))]>; def ATOMXOR8 : I<0, Pseudo,(outs GR8:$dst),(ins i8mem:$ptr, GR8:$val), - "#ATOMXOR8 PSUEDO!", + "#ATOMXOR8 PSEUDO!", [(set GR8:$dst, (atomic_load_xor_8 addr:$ptr, GR8:$val))]>; def ATOMNAND8 : I<0, Pseudo,(outs GR8:$dst),(ins i8mem:$ptr, GR8:$val), - "#ATOMNAND8 PSUEDO!", + "#ATOMNAND8 PSEUDO!", [(set GR8:$dst, (atomic_load_nand_8 addr:$ptr, GR8:$val))]>; } @@ -2857,25 +2857,25 @@ usesCustomDAGSchedInserter = 1 in { def ATOMAND6432 : I<0, Pseudo, (outs GR32:$dst1, GR32:$dst2), (ins i64mem:$ptr, GR32:$val1, GR32:$val2), - "#ATOMAND6432 PSUEDO!", []>; + "#ATOMAND6432 PSEUDO!", []>; def ATOMOR6432 : I<0, Pseudo, (outs GR32:$dst1, GR32:$dst2), (ins i64mem:$ptr, GR32:$val1, GR32:$val2), - "#ATOMOR6432 PSUEDO!", []>; + "#ATOMOR6432 PSEUDO!", []>; def ATOMXOR6432 : I<0, Pseudo, (outs GR32:$dst1, GR32:$dst2), (ins i64mem:$ptr, GR32:$val1, GR32:$val2), - "#ATOMXOR6432 PSUEDO!", []>; + "#ATOMXOR6432 PSEUDO!", []>; def ATOMNAND6432 : I<0, Pseudo, (outs GR32:$dst1, GR32:$dst2), (ins i64mem:$ptr, GR32:$val1, GR32:$val2), - "#ATOMNAND6432 PSUEDO!", []>; + "#ATOMNAND6432 PSEUDO!", []>; def ATOMADD6432 : I<0, Pseudo, (outs GR32:$dst1, GR32:$dst2), (ins i64mem:$ptr, GR32:$val1, GR32:$val2), - "#ATOMADD6432 PSUEDO!", []>; + "#ATOMADD6432 PSEUDO!", []>; def ATOMSUB6432 : I<0, Pseudo, (outs GR32:$dst1, GR32:$dst2), (ins i64mem:$ptr, GR32:$val1, GR32:$val2), - "#ATOMSUB6432 PSUEDO!", []>; + "#ATOMSUB6432 PSEUDO!", []>; def ATOMSWAP6432 : I<0, Pseudo, (outs GR32:$dst1, GR32:$dst2), (ins i64mem:$ptr, GR32:$val1, GR32:$val2), - "#ATOMSWAP6432 PSUEDO!", []>; + "#ATOMSWAP6432 PSEUDO!", []>; } //===----------------------------------------------------------------------===// From resistor at mac.com Sat Dec 6 23:33:20 2008 From: resistor at mac.com (Owen Anderson) Date: Sun, 07 Dec 2008 05:33:20 -0000 Subject: [llvm-commits] [llvm] r60652 - /llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp Message-ID: <200812070533.mB75XKdc013238@zion.cs.uiuc.edu> Author: resistor Date: Sat Dec 6 23:33:18 2008 New Revision: 60652 URL: http://llvm.org/viewvc/llvm-project?rev=60652&view=rev Log: Switch to top-down mode and fix a crasher this exposed caused by an error in the live interval updating. Modified: llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp Modified: llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp?rev=60652&r1=60651&r2=60652&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp (original) +++ llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp Sat Dec 6 23:33:18 2008 @@ -442,6 +442,9 @@ SE = MBB->succ_end(); SI != SE; ++SI) WorkList.push_back(*SI); + SmallPtrSet ProcessedBlocks; + ProcessedBlocks.insert(MBB); + while (!WorkList.empty()) { MBB = WorkList.back(); WorkList.pop_back(); @@ -459,6 +462,13 @@ } Processed.insert(LR); } + + ProcessedBlocks.insert(MBB); + if (LR) + for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(), + SE = MBB->succ_end(); SI != SE; ++SI) + if (!ProcessedBlocks.count(*SI)) + WorkList.push_back(*SI); } for (LiveInterval::iterator I = CurrLI->begin(), E = CurrLI->end(); @@ -1039,7 +1049,7 @@ // Make sure blocks are numbered in order. MF.RenumberBlocks(); -#if 0 +#if 1 // FIXME: Go top down. MachineBasicBlock *Entry = MF.begin(); SmallPtrSet Visited; From sabre at nondot.org Sun Dec 7 01:22:45 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 07 Dec 2008 07:22:45 -0000 Subject: [llvm-commits] [llvm] r60653 - in /llvm/trunk: lib/Transforms/Utils/SimplifyCFG.cpp test/Transforms/SimplifyCFG/2008-12-06-SingleEntryPhi.ll Message-ID: <200812070722.mB77MjNj016113@zion.cs.uiuc.edu> Author: lattner Date: Sun Dec 7 01:22:45 2008 New Revision: 60653 URL: http://llvm.org/viewvc/llvm-project?rev=60653&view=rev Log: fix a bug I introduced in simplifycfg handling single entry phi nodes. FoldSingleEntryPHINodes deletes the PHI, so there is no need to delete it afterward. Added: llvm/trunk/test/Transforms/SimplifyCFG/2008-12-06-SingleEntryPhi.ll Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=60653&r1=60652&r2=60653&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Sun Dec 7 01:22:45 2008 @@ -1102,7 +1102,6 @@ // Degenerate case of a single entry PHI. if (PN->getNumIncomingValues() == 1) { FoldSingleEntryPHINodes(PN->getParent()); - PN->eraseFromParent(); return true; } Added: llvm/trunk/test/Transforms/SimplifyCFG/2008-12-06-SingleEntryPhi.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/2008-12-06-SingleEntryPhi.ll?rev=60653&view=auto ============================================================================== --- llvm/trunk/test/Transforms/SimplifyCFG/2008-12-06-SingleEntryPhi.ll (added) +++ llvm/trunk/test/Transforms/SimplifyCFG/2008-12-06-SingleEntryPhi.ll Sun Dec 7 01:22:45 2008 @@ -0,0 +1,13 @@ +; RUN: llvm-as < %s | opt -simplifycfg | llvm-dis +define i32 @test() { +entry: + br label %T +T: + %C = phi i1 [false, %entry] + br i1 %C, label %X, label %Y +X: + ret i32 2 +Y: + add i32 1, 2 + ret i32 1 +} From nicholas at mxc.ca Sun Dec 7 02:19:53 2008 From: nicholas at mxc.ca (Nick Lewycky) Date: Sun, 07 Dec 2008 00:19:53 -0800 Subject: [llvm-commits] two-byte return optimization for AMD Message-ID: <493B8729.6000300@mxc.ca> The AMD optimization manual suggests avoiding branches to 'ret' instructions, preferring to emit 'rep; ret'. The attached patch implements this. This doesn't apply very often across llvm-test. The largest is kimwitu++ which produces 28 of these two-byte rets. The performance impact seems to be less than noise, at least on my system. Please review! Nick -------------- next part -------------- A non-text attachment was scrubbed... Name: x86-twobyteret.patch Type: text/x-diff Size: 8830 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081207/71f2bc7f/attachment.bin From sabre at nondot.org Sun Dec 7 02:50:21 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 07 Dec 2008 08:50:21 -0000 Subject: [llvm-commits] [llvm] r60654 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200812070850.mB78oLCe023214@zion.cs.uiuc.edu> Author: lattner Date: Sun Dec 7 02:50:20 2008 New Revision: 60654 URL: http://llvm.org/viewvc/llvm-project?rev=60654&view=rev Log: add support for caching pointer dependence queries. Nothing uses this yet so it "can't" break anything. That said, it does appear to work. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60654&r1=60653&r2=60654&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Sun Dec 7 02:50:20 2008 @@ -151,7 +151,25 @@ typedef std::pair NonLocalDepEntry; typedef std::vector NonLocalDepInfo; private: - + /// ValueIsLoadPair - This is a pair where the bool is true if + /// the dependence is a read only dependence, false if read/write. + typedef PointerIntPair ValueIsLoadPair; + + /// CachedNonLocalPointerInfo - This map stores the cached results of doing + /// a pointer lookup at the bottom of a block. Key key of this map is the + /// pointer+isload bit, the value is a list of result> mappings. + typedef DenseMapCachedNonLocalPointerInfo; + CachedNonLocalPointerInfo NonLocalPointerDeps; + + // A map from instructions to their non-local pointer dependencies. + // The elements of the SmallPtrSet are ValueIsLoadPair's. + typedef DenseMap > ReverseNonLocalPtrDepTy; + ReverseNonLocalPtrDepTy ReverseNonLocalPtrDeps; + + + + /// PerInstNLInfo - This is the instruction we keep for each cached access /// that we have for an instruction. The pointer is an owning pointer and /// the bool indicates whether we have any dirty bits in the set. @@ -185,9 +203,10 @@ void releaseMemory() { LocalDeps.clear(); NonLocalDeps.clear(); - NonLocalDeps.clear(); + NonLocalPointerDeps.clear(); ReverseLocalDeps.clear(); ReverseNonLocalDeps.clear(); + ReverseNonLocalPtrDeps.clear(); } /// getAnalysisUsage - Does not modify anything. It uses Value Numbering @@ -229,10 +248,6 @@ void removeInstruction(Instruction *InstToRemove); private: - - /// getDependencyFrom - Return the instruction on which the memory location - /// '*Pointer' depends. This starts scanning from the instruction before - /// the position indicated by ScanIt. MemDepResult getPointerDependencyFrom(Value *Pointer, uint64_t MemSize, bool isLoad, BasicBlock::iterator ScanIt, @@ -240,12 +255,11 @@ MemDepResult getCallSiteDependencyFrom(CallSite C, BasicBlock::iterator ScanIt, BasicBlock *BB); - void getNonLocalPointerDepInternal(Value *Pointer, uint64_t Size, bool isLoad, BasicBlock *BB, SmallVectorImpl &Result, SmallPtrSet &Visited); - + void RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair P); /// verifyRemoved - Verify that the specified instruction does not occur /// in our internal data structures. Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60654&r1=60653&r2=60654&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sun Dec 7 02:50:20 2008 @@ -21,9 +21,7 @@ #include "llvm/Function.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/ADT/Statistic.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/Support/CFG.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Target/TargetData.h" using namespace llvm; @@ -31,6 +29,14 @@ STATISTIC(NumCacheNonLocal, "Number of fully cached non-local responses"); STATISTIC(NumCacheDirtyNonLocal, "Number of dirty cached non-local responses"); STATISTIC(NumUncacheNonLocal, "Number of uncached non-local responses"); + +STATISTIC(NumCacheNonLocalPtr, + "Number of fully cached non-local ptr responses"); +STATISTIC(NumCacheDirtyNonLocalPtr, + "Number of cached, but dirty, non-local ptr responses"); +STATISTIC(NumUncacheNonLocalPtr, + "Number of uncached non-local ptr responses"); + char MemoryDependenceAnalysis::ID = 0; // Register this pass... @@ -74,7 +80,7 @@ Pointer = F->getPointerOperand(); // FreeInsts erase the entire structure - PointerSize = ~0UL; + PointerSize = ~0ULL; } else if (isa(Inst) || isa(Inst)) { CallSite InstCS = CallSite::get(Inst); // If these two calls do not interfere, look past it. @@ -115,7 +121,7 @@ getPointerDependencyFrom(Value *MemPtr, uint64_t MemSize, bool isLoad, BasicBlock::iterator ScanIt, BasicBlock *BB) { - // Walk backwards through the basic block, looking for dependencies + // Walk backwards through the basic block, looking for dependencies. while (ScanIt != BB->begin()) { Instruction *Inst = --ScanIt; @@ -134,6 +140,8 @@ // May-alias loads don't depend on each other without a dependence. if (isLoad && R == AliasAnalysis::MayAlias) continue; + // Stores depend on may and must aliased loads, loads depend on must-alias + // loads. return MemDepResult::getDef(Inst); } @@ -200,8 +208,10 @@ ScanPos = Inst; SmallPtrSet &InstMap = ReverseLocalDeps[Inst]; - InstMap.erase(QueryInst); + bool Found = InstMap.erase(QueryInst); + assert(Found && "Invalid reverse map!"); Found=Found; if (InstMap.empty()) + // FIXME: use an iterator to avoid looking up inst again. ReverseLocalDeps.erase(Inst); } @@ -356,7 +366,9 @@ // We're removing QueryInst's use of Inst. SmallPtrSet &InstMap = ReverseNonLocalDeps[Inst]; - InstMap.erase(QueryInst); + bool Found = InstMap.erase(QueryInst); + assert(Found && "Invalid reverse map!"); Found=Found; + // FIXME: Use an iterator to avoid looking up inst again. if (InstMap.empty()) ReverseNonLocalDeps.erase(Inst); } } @@ -441,7 +453,6 @@ // We know that the pointer value is live into FromBB find the def/clobbers // from presecessors. - const Type *EltTy = cast(Pointer->getType())->getElementType(); uint64_t PointeeSize = TD->getTypeStoreSize(EltTy); @@ -464,6 +475,17 @@ SmallVector Worklist; Worklist.push_back(StartBB); + // Look up the cached info for Pointer. + ValueIsLoadPair CacheKey(Pointer, isLoad); + NonLocalDepInfo *Cache = &NonLocalPointerDeps[CacheKey]; + + // Keep track of the entries that we know are sorted. Previously cached + // entries will all be sorted. The entries we add we only sort on demand (we + // don't insert every element into its sorted position). We know that we + // won't get any reuse from currently inserted values, because we don't + // revisit blocks after we insert info for them. + unsigned NumSortedEntries = Cache->size(); + while (!Worklist.empty()) { BasicBlock *BB = Worklist.pop_back_val(); @@ -471,11 +493,70 @@ // been here. if (!Visited.insert(BB)) continue; + + // Get the dependency info for Pointer in BB. If we have cached + // information, we will use it, otherwise we compute it. - // FIXME: CACHE! + // Do a binary search to see if we already have an entry for this block in + // the cache set. If so, find it. + NonLocalDepInfo::iterator Entry = + std::upper_bound(Cache->begin(), Cache->begin()+NumSortedEntries, + std::make_pair(BB, MemDepResult())); + if (Entry != Cache->begin() && (&*Entry)[-1].first == BB) + --Entry; - MemDepResult Dep = - getPointerDependencyFrom(Pointer, PointeeSize, isLoad, BB->end(), BB); + MemDepResult *ExistingResult = 0; + if (Entry != Cache->begin()+NumSortedEntries && Entry->first == BB) + ExistingResult = &Entry->second; + + // If we have a cached entry, and it is non-dirty, use it as the value for + // this dependency. + MemDepResult Dep; + if (ExistingResult && !ExistingResult->isDirty()) { + Dep = *ExistingResult; + ++NumCacheNonLocalPtr; + } else { + // Otherwise, we have to scan for the value. If we have a dirty cache + // entry, start scanning from its position, otherwise we scan from the end + // of the block. + BasicBlock::iterator ScanPos = BB->end(); + if (ExistingResult && ExistingResult->getInst()) { + assert(ExistingResult->getInst()->getParent() == BB && + "Instruction invalidated?"); + ++NumCacheDirtyNonLocalPtr; + ScanPos = ExistingResult->getInst(); + + // Eliminating the dirty entry from 'Cache', so update the reverse info. + SmallPtrSet &InstMap = ReverseNonLocalPtrDeps[ScanPos]; + bool Contained = InstMap.erase(CacheKey.getOpaqueValue()); + assert(Contained && "Invalid cache entry"); Contained=Contained; + // FIXME: Use an iterator to avoid a repeated lookup in ".erase". + if (InstMap.empty()) ReverseNonLocalPtrDeps.erase(ScanPos); + } else { + ++NumUncacheNonLocalPtr; + } + + // Scan the block for the dependency. + Dep = getPointerDependencyFrom(Pointer, PointeeSize, isLoad, ScanPos, BB); + + // If we had a dirty entry for the block, update it. Otherwise, just add + // a new entry. + if (ExistingResult) + *ExistingResult = Dep; + else + Cache->push_back(std::make_pair(BB, Dep)); + + // If the block has a dependency (i.e. it isn't completely transparent to + // the value), remember the reverse association because we just added it + // to Cache! + if (!Dep.isNonLocal()) { + // Keep the ReverseNonLocalPtrDeps map up to date so we can efficiently + // update MemDep when we remove instructions. + Instruction *Inst = Dep.getInst(); + assert(Inst && "Didn't depend on anything?"); + ReverseNonLocalPtrDeps[Inst].insert(CacheKey.getOpaqueValue()); + } + } // If we got a Def or Clobber, add this to the list of results. if (!Dep.isNonLocal()) { @@ -490,6 +571,40 @@ Worklist.push_back(*PI); } } + + // If we computed new values, re-sort Cache. + if (NumSortedEntries != Cache->size()) + std::sort(Cache->begin(), Cache->end()); +} + +/// RemoveCachedNonLocalPointerDependencies - If P exists in +/// CachedNonLocalPointerInfo, remove it. +void MemoryDependenceAnalysis:: +RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair P) { + CachedNonLocalPointerInfo::iterator It = + NonLocalPointerDeps.find(P); + if (It == NonLocalPointerDeps.end()) return; + + // Remove all of the entries in the BB->val map. This involves removing + // instructions from the reverse map. + NonLocalDepInfo &PInfo = It->second; + + for (unsigned i = 0, e = PInfo.size(); i != e; ++i) { + Instruction *Target = PInfo[i].second.getInst(); + if (Target == 0) continue; // Ignore non-local dep results. + assert(Target->getParent() == PInfo[i].first && Target != P.getPointer()); + + // Eliminating the dirty entry from 'Cache', so update the reverse info. + SmallPtrSet &InstMap = ReverseNonLocalPtrDeps[Target]; + bool Contained = InstMap.erase(P.getOpaqueValue()); + assert(Contained && "Invalid cache entry"); Contained=Contained; + + // FIXME: Use an iterator to avoid a repeated lookup in ".erase". + if (InstMap.empty()) ReverseNonLocalPtrDeps.erase(Target); + } + + // Remove P from NonLocalPointerDeps (which deletes NonLocalDepInfo). + NonLocalPointerDeps.erase(It); } @@ -516,14 +631,27 @@ // Remove us from DepInst's reverse set now that the local dep info is gone. if (Instruction *Inst = LocalDepEntry->second.getInst()) { SmallPtrSet &RLD = ReverseLocalDeps[Inst]; - RLD.erase(RemInst); + bool Found = RLD.erase(RemInst); + assert(Found && "Invalid reverse map!"); Found=Found; + // FIXME: Use an iterator to avoid looking up Inst again. if (RLD.empty()) ReverseLocalDeps.erase(Inst); } // Remove this local dependency info. LocalDeps.erase(LocalDepEntry); - } + } + + // If we have any cached pointer dependencies on this instruction, remove + // them. If the instruction has non-pointer type, then it can't be a pointer + // base. + + // Remove it from both the load info and the store info. The instruction + // can't be in either of these maps if it is non-pointer. + if (isa(RemInst->getType())) { + RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair(RemInst, false)); + RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair(RemInst, true)); + } // Loop over all of the things that depend on the instruction we're removing. // @@ -532,7 +660,7 @@ ReverseDepMapType::iterator ReverseDepIt = ReverseLocalDeps.find(RemInst); if (ReverseDepIt != ReverseLocalDeps.end()) { SmallPtrSet &ReverseDeps = ReverseDepIt->second; - // RemInst can't be the terminator if it has stuff depending on it. + // RemInst can't be the terminator if it has local stuff depending on it. assert(!ReverseDeps.empty() && !isa(RemInst) && "Nothing can locally depend on a terminator"); @@ -540,7 +668,7 @@ // dependent on the instruction after RemInst. It will have the dirty flag // set so it will rescan. This saves having to scan the entire block to get // to this point. - Instruction *NewDepInst = next(BasicBlock::iterator(RemInst)); + Instruction *NewDepInst = ++BasicBlock::iterator(RemInst); for (SmallPtrSet::iterator I = ReverseDeps.begin(), E = ReverseDeps.end(); I != E; ++I) { @@ -568,8 +696,8 @@ ReverseDepIt = ReverseNonLocalDeps.find(RemInst); if (ReverseDepIt != ReverseNonLocalDeps.end()) { - SmallPtrSet& set = ReverseDepIt->second; - for (SmallPtrSet::iterator I = set.begin(), E = set.end(); + SmallPtrSet &Set = ReverseDepIt->second; + for (SmallPtrSet::iterator I = Set.begin(), E = Set.end(); I != E; ++I) { assert(*I != RemInst && "Already removed NonLocalDep info for RemInst"); @@ -584,7 +712,7 @@ // Convert to a dirty entry for the subsequent instruction. Instruction *NextI = 0; if (!RemInst->isTerminator()) { - NextI = next(BasicBlock::iterator(RemInst)); + NextI = ++BasicBlock::iterator(RemInst); ReverseDepsToAdd.push_back(std::make_pair(NextI, *I)); } DI->second = MemDepResult::getDirty(NextI); @@ -601,6 +729,50 @@ } } + // If the instruction is in ReverseNonLocalPtrDeps then it appears as a + // value in the NonLocalPointerDeps info. + ReverseNonLocalPtrDepTy::iterator ReversePtrDepIt = + ReverseNonLocalPtrDeps.find(RemInst); + if (ReversePtrDepIt != ReverseNonLocalPtrDeps.end()) { + SmallPtrSet &Set = ReversePtrDepIt->second; + SmallVector,8> ReversePtrDepsToAdd; + + for (SmallPtrSet::iterator I = Set.begin(), E = Set.end(); + I != E; ++I) { + ValueIsLoadPair P; + P.setFromOpaqueValue(*I); + assert(P.getPointer() != RemInst && + "Already removed NonLocalPointerDeps info for RemInst"); + + NonLocalDepInfo &NLPDI = NonLocalPointerDeps[P]; + + MemDepResult NewDirtyVal; + if (!RemInst->isTerminator()) + NewDirtyVal = MemDepResult::getDirty(++BasicBlock::iterator(RemInst)); + + // Update any entries for RemInst to use the instruction after it. + for (NonLocalDepInfo::iterator DI = NLPDI.begin(), DE = NLPDI.end(); + DI != DE; ++DI) { + if (DI->second.getInst() != RemInst) continue; + + // Convert to a dirty entry for the subsequent instruction. + DI->second = NewDirtyVal; + + if (Instruction *NewDirtyInst = NewDirtyVal.getInst()) + ReversePtrDepsToAdd.push_back(std::make_pair(NewDirtyInst, P)); + } + } + + ReverseNonLocalPtrDeps.erase(ReversePtrDepIt); + + while (!ReversePtrDepsToAdd.empty()) { + ReverseNonLocalPtrDeps[ReversePtrDepsToAdd.back().first] + .insert(ReversePtrDepsToAdd.back().second.getOpaqueValue()); + ReversePtrDepsToAdd.pop_back(); + } + } + + assert(!NonLocalDeps.count(RemInst) && "RemInst got reinserted?"); AA->deleteValue(RemInst); DEBUG(verifyRemoved(RemInst)); @@ -616,6 +788,15 @@ "Inst occurs in data structures"); } + for (CachedNonLocalPointerInfo::const_iterator I =NonLocalPointerDeps.begin(), + E = NonLocalPointerDeps.end(); I != E; ++I) { + assert(I->first.getPointer() != D && "Inst occurs in NLPD map key"); + const NonLocalDepInfo &Val = I->second; + for (NonLocalDepInfo::const_iterator II = Val.begin(), E = Val.end(); + II != E; ++II) + assert(II->second.getInst() != D && "Inst occurs as NLPD value"); + } + for (NonLocalDepMapType::const_iterator I = NonLocalDeps.begin(), E = NonLocalDeps.end(); I != E; ++I) { assert(I->first != D && "Inst occurs in data structures"); @@ -641,4 +822,17 @@ EE = I->second.end(); II != EE; ++II) assert(*II != D && "Inst occurs in data structures"); } + + for (ReverseNonLocalPtrDepTy::const_iterator + I = ReverseNonLocalPtrDeps.begin(), + E = ReverseNonLocalPtrDeps.end(); I != E; ++I) { + assert(I->first != D && "Inst occurs in rev NLPD map"); + + for (SmallPtrSet::const_iterator II = I->second.begin(), + E = I->second.end(); II != E; ++II) + assert(*II != ValueIsLoadPair(D, false).getOpaqueValue() && + *II != ValueIsLoadPair(D, true).getOpaqueValue() && + "Inst occurs in ReverseNonLocalPtrDeps map"); + } + } From baldrick at free.fr Sun Dec 7 10:29:50 2008 From: baldrick at free.fr (Duncan Sands) Date: Sun, 7 Dec 2008 17:29:50 +0100 Subject: [llvm-commits] [llvm] r60654 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp In-Reply-To: <200812070850.mB78oLCe023214@zion.cs.uiuc.edu> References: <200812070850.mB78oLCe023214@zion.cs.uiuc.edu> Message-ID: <200812071729.50733.baldrick@free.fr> Hi Chris, > + /// a pointer lookup at the bottom of a block. Key key of this map is the Key key? Ciao, Duncan. From foldr at codedgers.com Sun Dec 7 10:41:12 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Sun, 07 Dec 2008 16:41:12 -0000 Subject: [llvm-commits] [llvm] r60656 - in /llvm/trunk: include/llvm/CompilerDriver/Action.h include/llvm/CompilerDriver/Common.td include/llvm/CompilerDriver/Tool.h include/llvm/CompilerDriver/Tools.td tools/llvmc/driver/CompilationGraph.cpp tools/llvmc/driver/Tool.cpp utils/TableGen/LLVMCConfigurationEmitter.cpp Message-ID: <200812071641.mB7GfCd5002209@zion.cs.uiuc.edu> Author: foldr Date: Sun Dec 7 10:41:11 2008 New Revision: 60656 URL: http://llvm.org/viewvc/llvm-project?rev=60656&view=rev Log: Use (actions) instead of option properties, support external options. Also includes a major refactoring. See documentation for more information. Added: llvm/trunk/tools/llvmc/driver/Tool.cpp Modified: llvm/trunk/include/llvm/CompilerDriver/Action.h llvm/trunk/include/llvm/CompilerDriver/Common.td llvm/trunk/include/llvm/CompilerDriver/Tool.h llvm/trunk/include/llvm/CompilerDriver/Tools.td llvm/trunk/tools/llvmc/driver/CompilationGraph.cpp llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Modified: llvm/trunk/include/llvm/CompilerDriver/Action.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CompilerDriver/Action.h?rev=60656&r1=60655&r2=60656&view=diff ============================================================================== --- llvm/trunk/include/llvm/CompilerDriver/Action.h (original) +++ llvm/trunk/include/llvm/CompilerDriver/Action.h Sun Dec 7 10:41:11 2008 @@ -27,14 +27,22 @@ std::string Command_; /// Args_ - Command arguments. Stdout redirection ("> file") is allowed. std::vector Args_; + /// StopCompilation_ - Should we stop compilation after executing + /// this action? + bool StopCompilation_; + /// OutFile_ - The output file name. + std::string OutFile_; + public: - Action() {} - Action (const std::string& C, const StrVector& A) - : Command_(C), Args_(A) + Action (const std::string& C, const StrVector& A, + bool S, const std::string& O) + : Command_(C), Args_(A), StopCompilation_(S), OutFile_(O) {} /// Execute - Executes the represented action. - int Execute() const; + int Execute () const; + bool StopCompilation () const { return StopCompilation_; } + const std::string& OutFile() { return OutFile_; } }; } Modified: llvm/trunk/include/llvm/CompilerDriver/Common.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CompilerDriver/Common.td?rev=60656&r1=60655&r2=60656&view=diff ============================================================================== --- llvm/trunk/include/llvm/CompilerDriver/Common.td (original) +++ llvm/trunk/include/llvm/CompilerDriver/Common.td Sun Dec 7 10:41:11 2008 @@ -15,7 +15,7 @@ list properties = l; } -// Possible Tool properties +// Possible Tool properties. def in_language; def out_language; @@ -23,8 +23,9 @@ def cmd_line; def join; def sink; +def actions; -// Possible option types +// Possible option types. def alias_option; def switch_option; @@ -33,17 +34,16 @@ def prefix_option; def prefix_list_option; -// Possible option properties +def extern_switch; +def extern_parameter; +def extern_list; + +// Possible option properties. -def append_cmd; -def forward; -def forward_as; def help; def hidden; def really_hidden; def required; -def stop_compilation; -def unpack_values; // Empty DAG marker. def empty; @@ -51,6 +51,10 @@ // The 'case' construct. def case; +// Boolean operators. +def and; +def or; + // Primitive tests. def switch_on; def parameter_equals; @@ -59,9 +63,13 @@ def not_empty; def default; -// Boolean operators. -def and; -def or; +// Possible actions. + +def append_cmd; +def forward; +def forward_as; +def stop_compilation; +def unpack_values; // Increase/decrease the edge weight. def inc_weight; Modified: llvm/trunk/include/llvm/CompilerDriver/Tool.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CompilerDriver/Tool.h?rev=60656&r1=60655&r2=60656&view=diff ============================================================================== --- llvm/trunk/include/llvm/CompilerDriver/Tool.h (original) +++ llvm/trunk/include/llvm/CompilerDriver/Tool.h Sun Dec 7 10:41:11 2008 @@ -36,22 +36,29 @@ virtual ~Tool() {} virtual Action GenerateAction (const PathVector& inFiles, - const llvm::sys::Path& outFile, + bool HasChildren, + const llvm::sys::Path& TempDir, const InputLanguagesSet& InLangs, const LanguageMap& LangMap) const = 0; virtual Action GenerateAction (const llvm::sys::Path& inFile, - const llvm::sys::Path& outFile, + bool HasChildren, + const llvm::sys::Path& TempDir, const InputLanguagesSet& InLangs, const LanguageMap& LangMap) const = 0; virtual const char* Name() const = 0; virtual const char** InputLanguages() const = 0; virtual const char* OutputLanguage() const = 0; - virtual const char* OutputSuffix() const = 0; - virtual bool IsLast() const = 0; virtual bool IsJoin() const = 0; + + protected: + /// OutFileName - Generate the output file name. + llvm::sys::Path OutFilename(const llvm::sys::Path& In, + const llvm::sys::Path& TempDir, + bool StopCompilation, + const char* OutputSuffix) const; }; /// JoinTool - A Tool that has an associated input file list. @@ -61,10 +68,11 @@ void ClearJoinList() { JoinList_.clear(); } bool JoinListEmpty() const { return JoinList_.empty(); } - Action GenerateAction(const llvm::sys::Path& outFile, + Action GenerateAction(bool HasChildren, + const llvm::sys::Path& TempDir, const InputLanguagesSet& InLangs, const LanguageMap& LangMap) const { - return GenerateAction(JoinList_, outFile, InLangs, LangMap); + return GenerateAction(JoinList_, HasChildren, TempDir, InLangs, LangMap); } // We shouldn't shadow base class's version of GenerateAction. using Tool::GenerateAction; Modified: llvm/trunk/include/llvm/CompilerDriver/Tools.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CompilerDriver/Tools.td?rev=60656&r1=60655&r2=60656&view=diff ============================================================================== --- llvm/trunk/include/llvm/CompilerDriver/Tools.td (original) +++ llvm/trunk/include/llvm/CompilerDriver/Tools.td Sun Dec 7 10:41:11 2008 @@ -11,6 +11,35 @@ // //===----------------------------------------------------------------------===// +def OptList : OptionList<[ + (switch_option "emit-llvm", + (help "Emit LLVM bitcode files instead of native object files")), + (switch_option "E", + (help "Stop after the preprocessing stage, do not run the compiler")), + (switch_option "fsyntax-only", + (help "Stop after checking the input for syntax errors")), + (switch_option "opt", + (help "Enable opt")), + (switch_option "S", + (help "Stop after compilation, do not assemble")), + (switch_option "c", + (help "Compile and assemble, but do not link")), + (parameter_option "linker", + (help "Choose linker (possible values: gcc, g++)")), + (parameter_list_option "include", + (help "Include the named file prior to preprocessing")), + (prefix_list_option "I", + (help "Add a directory to include path")), + (prefix_list_option "Wa,", + (help "Pass options to assembler")), + (prefix_list_option "L", + (help "Add a directory to link path")), + (prefix_list_option "l", + (help "Search a library when linking")), + (prefix_list_option "Wl,", + (help "Pass options to linker")) +]>; + class llvm_gcc_based : Tool< [(in_language in_lang), (out_language "llvm-bitcode"), @@ -25,16 +54,13 @@ !strconcat(cmd_prefix, " -fsyntax-only $INFILE"), (default), !strconcat(cmd_prefix, " -c $INFILE -o $OUTFILE -emit-llvm"))), - (switch_option "emit-llvm", (stop_compilation), - (help "Emit LLVM intermediate files instead of native object files")), - (switch_option "E", (stop_compilation), - (help "Stop after the preprocessing stage, do not run the compiler")), - (switch_option "fsyntax-only", (stop_compilation), - (help "Stop after checking the input for syntax errors")), - (parameter_list_option "include", (forward), - (help "Include the named file prior to preprocessing")), - (prefix_list_option "I", (forward), - (help "Add a directory to include path")), + (actions + (case + (switch_on "emit-llvm"), (stop_compilation), + (switch_on "E"), (stop_compilation), + (switch_on "fsyntax-only"), (stop_compilation), + (not_empty "include"), (forward "include"), + (not_empty "I"), (forward "include"))), (sink) ]>; @@ -46,7 +72,6 @@ def opt : Tool< [(in_language "llvm-bitcode"), (out_language "llvm-bitcode"), - (switch_option "opt", (help "Enable opt")), (output_suffix "bc"), (cmd_line "opt -f $INFILE -o $OUTFILE") ]>; @@ -62,8 +87,8 @@ [(in_language "llvm-bitcode"), (out_language "assembler"), (output_suffix "s"), - (switch_option "S", (stop_compilation), - (help "Stop after compilation, do not assemble")), + (actions (case + (switch_on "S"), (stop_compilation))), (cmd_line "llc -f $INFILE -o $OUTFILE") ]>; @@ -72,36 +97,28 @@ (out_language "object-code"), (output_suffix "o"), (cmd_line "llvm-gcc -c -x assembler $INFILE -o $OUTFILE"), - (switch_option "c", (stop_compilation), - (help "Compile and assemble, but do not link")), - (prefix_list_option "Wa,", (unpack_values), (help "Pass options to assembler")) + (actions (case + (switch_on "c"), (stop_compilation), + (not_empty "Wa,"), (unpack_values "Wa,"))) ]>; -// Default linker -def llvm_gcc_linker : Tool< +// Base class for linkers +class llvm_gcc_based_linker : Tool< [(in_language "object-code"), (out_language "executable"), (output_suffix "out"), - (cmd_line "llvm-gcc $INFILE -o $OUTFILE"), + (cmd_line !strconcat(cmd_prefix, " $INFILE -o $OUTFILE")), (join), - (prefix_list_option "L", (forward), (help "Add a directory to link path")), - (prefix_list_option "l", (forward), (help "Search a library when linking")), - (prefix_list_option "Wl,", (unpack_values), (help "Pass options to linker")) + (actions (case + (not_empty "L"), (forward "L"), + (not_empty "l"), (forward "l"), + (not_empty "Wl,"), (unpack_values "Wl,"))) ]>; +// Default linker +def llvm_gcc_linker : llvm_gcc_based_linker<"llvm-gcc">; // Alternative linker for C++ -def llvm_gcc_cpp_linker : Tool< -[(in_language "object-code"), - (out_language "executable"), - (output_suffix "out"), - (cmd_line "llvm-g++ $INFILE -o $OUTFILE"), - (join), - (parameter_option "linker", - (help "Choose linker (possible values: gcc, g++)")), - (prefix_list_option "L", (forward)), - (prefix_list_option "l", (forward)), - (prefix_list_option "Wl,", (unpack_values)) -]>; +def llvm_gcc_cpp_linker : llvm_gcc_based_linker<"llvm-g++">; // Language map Modified: llvm/trunk/tools/llvmc/driver/CompilationGraph.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/driver/CompilationGraph.cpp?rev=60656&r1=60655&r2=60656&view=diff ============================================================================== --- llvm/trunk/tools/llvmc/driver/CompilationGraph.cpp (original) +++ llvm/trunk/tools/llvmc/driver/CompilationGraph.cpp Sun Dec 7 10:41:11 2008 @@ -29,7 +29,6 @@ using namespace llvmc; extern cl::list InputFilenames; -extern cl::opt OutputFilename; extern cl::list Languages; namespace llvmc { @@ -143,30 +142,6 @@ B.IncrInEdges(); } -namespace { - sys::Path MakeTempFile(const sys::Path& TempDir, const std::string& BaseName, - const std::string& Suffix) { - sys::Path Out; - - // Make sure we don't end up with path names like '/file.o' if the - // TempDir is empty. - if (TempDir.empty()) { - Out.set(BaseName); - } - else { - Out = TempDir; - Out.appendComponent(BaseName); - } - Out.appendSuffix(Suffix); - // NOTE: makeUnique always *creates* a unique temporary file, - // which is good, since there will be no races. However, some - // tools do not like it when the output file already exists, so - // they have to be placated with -f or something like that. - Out.makeUnique(true, NULL); - return Out; - } -} - // Pass input file through the chain until we bump into a Join node or // a node that says that it is the last. void CompilationGraph::PassThroughGraph (const sys::Path& InFile, @@ -174,12 +149,10 @@ const InputLanguagesSet& InLangs, const sys::Path& TempDir, const LanguageMap& LangMap) const { - bool Last = false; sys::Path In = InFile; const Node* CurNode = StartNode; - while(!Last) { - sys::Path Out; + while(true) { Tool* CurTool = CurNode->ToolPtr.getPtr(); if (CurTool->IsJoin()) { @@ -188,32 +161,19 @@ break; } - // Since toolchains do not have to end with a Join node, we should - // check if this Node is the last. - if (!CurNode->HasChildren() || CurTool->IsLast()) { - if (!OutputFilename.empty()) { - Out.set(OutputFilename); - } - else { - Out.set(In.getBasename()); - Out.appendSuffix(CurTool->OutputSuffix()); - } - Last = true; - } - else { - Out = MakeTempFile(TempDir, In.getBasename(), CurTool->OutputSuffix()); - } + Action CurAction = CurTool->GenerateAction(In, CurNode->HasChildren(), + TempDir, InLangs, LangMap); - if (int ret = CurTool->GenerateAction(In, Out, InLangs, LangMap).Execute()) + if (int ret = CurAction.Execute()) throw error_code(ret); - if (Last) + if (CurAction.StopCompilation()) return; CurNode = &getNode(ChooseEdge(CurNode->OutEdges, InLangs, CurNode->Name())->ToolName()); - In = Out; Out.clear(); + In = CurAction.OutFile(); } } @@ -351,36 +311,24 @@ sys::Path Out; const Node* CurNode = *B; JoinTool* JT = &dynamic_cast(*CurNode->ToolPtr.getPtr()); - bool IsLast = false; // Are there any files in the join list? if (JT->JoinListEmpty()) continue; - // Is this the last tool in the toolchain? - // NOTE: we can process several toolchains in parallel. - if (!CurNode->HasChildren() || JT->IsLast()) { - if (OutputFilename.empty()) { - Out.set("a"); - Out.appendSuffix(JT->OutputSuffix()); - } - else - Out.set(OutputFilename); - IsLast = true; - } - else { - Out = MakeTempFile(TempDir, "tmp", JT->OutputSuffix()); - } + Action CurAction = JT->GenerateAction(CurNode->HasChildren(), + TempDir, InLangs, LangMap); - if (int ret = JT->GenerateAction(Out, InLangs, LangMap).Execute()) + if (int ret = CurAction.Execute()) throw error_code(ret); - if (!IsLast) { - const Node* NextNode = - &getNode(ChooseEdge(CurNode->OutEdges, InLangs, - CurNode->Name())->ToolName()); + if (CurAction.StopCompilation()) + return 0; + + const Node* NextNode = + &getNode(ChooseEdge(CurNode->OutEdges, InLangs, + CurNode->Name())->ToolName()); PassThroughGraph(Out, NextNode, InLangs, TempDir, LangMap); - } } return 0; Added: llvm/trunk/tools/llvmc/driver/Tool.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/driver/Tool.cpp?rev=60656&view=auto ============================================================================== --- llvm/trunk/tools/llvmc/driver/Tool.cpp (added) +++ llvm/trunk/tools/llvmc/driver/Tool.cpp Sun Dec 7 10:41:11 2008 @@ -0,0 +1,74 @@ +//===--- Tool.cpp - The LLVM Compiler Driver --------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open +// Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Tool base class - implementation details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/CompilerDriver/Tool.h" + +#include "llvm/System/Path.h" +#include "llvm/Support/CommandLine.h" + +using namespace llvm; +using namespace llvmc; + +extern cl::opt OutputFilename; + +namespace { + sys::Path MakeTempFile(const sys::Path& TempDir, const std::string& BaseName, + const std::string& Suffix) { + sys::Path Out; + + // Make sure we don't end up with path names like '/file.o' if the + // TempDir is empty. + if (TempDir.empty()) { + Out.set(BaseName); + } + else { + Out = TempDir; + Out.appendComponent(BaseName); + } + Out.appendSuffix(Suffix); + // NOTE: makeUnique always *creates* a unique temporary file, + // which is good, since there will be no races. However, some + // tools do not like it when the output file already exists, so + // they have to be placated with -f or something like that. + Out.makeUnique(true, NULL); + return Out; + } +} + +sys::Path Tool::OutFilename(const sys::Path& In, + const sys::Path& TempDir, + bool StopCompilation, + const char* OutputSuffix) const { + sys::Path Out; + + if (StopCompilation) { + if (!OutputFilename.empty()) { + Out.set(OutputFilename); + } + else if (IsJoin()) { + Out.set("a"); + Out.appendSuffix(OutputSuffix); + } + else { + Out.set(In.getBasename()); + Out.appendSuffix(OutputSuffix); + } + } + else { + if (IsJoin()) + Out = MakeTempFile(TempDir, "tmp", OutputSuffix); + else + Out = MakeTempFile(TempDir, In.getBasename(), OutputSuffix); + } + return Out; +} Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=60656&r1=60655&r2=60656&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Sun Dec 7 10:41:11 2008 @@ -45,7 +45,6 @@ const char * Indent1 = " "; const char * Indent2 = " "; const char * Indent3 = " "; -const char * Indent4 = " "; // Default help string. const char * DefaultHelpString = "NO HELP MESSAGE PROVIDED"; @@ -56,6 +55,13 @@ //===----------------------------------------------------------------------===// /// Helper functions +/// Id - An 'identity' function object. +struct Id { + template + void operator()(const T&) const { + } +}; + int InitPtrToInt(const Init* ptr) { const IntInit& val = dynamic_cast(*ptr); return val.getValue(); @@ -89,426 +95,330 @@ return d->getOperator()->getAsString() == "empty"; } +// EscapeVariableName - Escape commas and other symbols not allowed +// in the C++ variable names. Makes it possible to use options named +// like "Wa," (useful for prefix options). +std::string EscapeVariableName(const std::string& Var) { + std::string ret; + for (unsigned i = 0; i != Var.size(); ++i) { + char cur_char = Var[i]; + if (cur_char == ',') { + ret += "_comma_"; + } + else if (cur_char == '+') { + ret += "_plus_"; + } + else if (cur_char == '-') { + ret += "_dash_"; + } + else { + ret.push_back(cur_char); + } + } + return ret; +} + //===----------------------------------------------------------------------===// /// Back-end specific code -// A command-line option can have one of the following types: -// -// Alias - an alias for another option. -// -// Switch - a simple switch without arguments, e.g. -O2 -// -// Parameter - an option that takes one(and only one) argument, e.g. -o file, -// --output=file -// -// ParameterList - same as Parameter, but more than one occurence -// of the option is allowed, e.g. -lm -lpthread -// -// Prefix - argument is everything after the prefix, -// e.g. -Wa,-foo,-bar, -DNAME=VALUE -// -// PrefixList - same as Prefix, but more than one option occurence is -// allowed. +/// OptionType - One of six different option types. See the +/// documentation for detailed description of differences. +/// Extern* options are those that are defined in some other plugin. namespace OptionType { - enum OptionType { Alias, Switch, - Parameter, ParameterList, Prefix, PrefixList}; + enum OptionType { Alias, Switch, Parameter, ParameterList, + Prefix, PrefixList, + ExternSwitch, ExternParameter, ExternList }; + +bool IsList (OptionType t) { + return (t == ParameterList || t == PrefixList || t == ExternList); +} + +bool IsSwitch (OptionType t) { + return (t == Switch || t == ExternSwitch); +} + +bool IsParameter (OptionType t) { + return (t == Parameter || t == Prefix || t == ExternParameter); } -bool IsListOptionType (OptionType::OptionType t) { - return (t == OptionType::ParameterList || t == OptionType::PrefixList); } -// Code duplication here is necessary because one option can affect -// several tools and those tools may have different actions associated -// with this option. GlobalOptionDescriptions are used to generate -// the option registration code, while ToolOptionDescriptions are used -// to generate tool-specific code. +OptionType::OptionType stringToOptionType(const std::string& T) { + if (T == "alias_option") + return OptionType::Alias; + else if (T == "switch_option") + return OptionType::Switch; + else if (T == "parameter_option") + return OptionType::Parameter; + else if (T == "parameter_list_option") + return OptionType::ParameterList; + else if (T == "prefix_option") + return OptionType::Prefix; + else if (T == "prefix_list_option") + return OptionType::PrefixList; + else if (T == "extern_switch") + return OptionType::ExternSwitch; + else if (T == "extern_parameter") + return OptionType::ExternParameter; + else if (T == "extern_list") + return OptionType::ExternList; + else + throw "Unknown option type: " + T + '!'; +} + +namespace OptionDescriptionFlags { + enum OptionDescriptionFlags { Required = 0x1, Hidden = 0x2, + ReallyHidden = 0x4 }; +} -/// OptionDescription - Base class for option descriptions. +/// OptionDescription - Represents data contained in a single +/// OptionList entry. struct OptionDescription { OptionType::OptionType Type; std::string Name; + unsigned Flags; + std::string Help; OptionDescription(OptionType::OptionType t = OptionType::Switch, - const std::string& n = "") - : Type(t), Name(n) + const std::string& n = "", + const std::string& h = DefaultHelpString) + : Type(t), Name(n), Flags(0x0), Help(h) {} - const char* GenTypeDeclaration() const { - switch (Type) { - case OptionType::Alias: - return "cl::alias"; - case OptionType::PrefixList: - case OptionType::ParameterList: - return "cl::list"; - case OptionType::Switch: - return "cl::opt"; - case OptionType::Parameter: - case OptionType::Prefix: - default: - return "cl::opt"; - } - } + /// GenTypeDeclaration - Returns the C++ variable type of this + /// option. + const char* GenTypeDeclaration() const; + + /// GenVariableName - Returns the variable name used in the + /// generated C++ code. + std::string GenVariableName() const; - // Escape commas and other symbols not allowed in the C++ variable - // names. Makes it possible to use options with names like "Wa," - // (useful for prefix options). - std::string EscapeVariableName(const std::string& Var) const { - std::string ret; - for (unsigned i = 0; i != Var.size(); ++i) { - char cur_char = Var[i]; - if (cur_char == ',') { - ret += "_comma_"; - } - else if (cur_char == '+') { - ret += "_plus_"; - } - else if (cur_char == '-') { - ret += "_dash_"; - } - else { - ret.push_back(cur_char); - } - } - return ret; - } + /// Merge - Merge two option descriptions. + void Merge (const OptionDescription& other); - std::string GenVariableName() const { - const std::string& EscapedName = EscapeVariableName(Name); - switch (Type) { - case OptionType::Alias: - return "AutoGeneratedAlias" + EscapedName; - case OptionType::Switch: - return "AutoGeneratedSwitch" + EscapedName; - case OptionType::Prefix: - return "AutoGeneratedPrefix" + EscapedName; - case OptionType::PrefixList: - return "AutoGeneratedPrefixList" + EscapedName; - case OptionType::Parameter: - return "AutoGeneratedParameter" + EscapedName; - case OptionType::ParameterList: - default: - return "AutoGeneratedParameterList" + EscapedName; - } - } + // Misc convenient getters/setters. + + bool isAlias() const; + bool isExtern() const; + + bool isRequired() const; + void setRequired(); + + bool isHidden() const; + void setHidden(); + bool isReallyHidden() const; + void setReallyHidden(); }; -// Global option description. +void OptionDescription::Merge (const OptionDescription& other) +{ + if (other.Type != Type) + throw "Conflicting definitions for the option " + Name + "!"; + + if (Help == other.Help || Help == DefaultHelpString) + Help = other.Help; + else if (other.Help != DefaultHelpString) { + llvm::cerr << "Warning: several different help strings" + " defined for option " + Name + "\n"; + } -namespace GlobalOptionDescriptionFlags { - enum GlobalOptionDescriptionFlags { Required = 0x1, Hidden = 0x2, - ReallyHidden = 0x4 }; + Flags |= other.Flags; } -struct GlobalOptionDescription : public OptionDescription { - std::string Help; - unsigned Flags; +bool OptionDescription::isAlias() const { + return Type == OptionType::Alias; +} - // We need to provide a default constructor because - // StringMap can only store DefaultConstructible objects. - GlobalOptionDescription() : OptionDescription(), Flags(0) - {} +bool OptionDescription::isExtern() const { + return (Type == OptionType::ExternList || Type == OptionType::ExternParameter + || Type == OptionType::ExternSwitch); +} - GlobalOptionDescription (OptionType::OptionType t, const std::string& n, - const std::string& h = DefaultHelpString) - : OptionDescription(t, n), Help(h), Flags(0) - {} +bool OptionDescription::isRequired() const { + return Flags & OptionDescriptionFlags::Required; +} +void OptionDescription::setRequired() { + Flags |= OptionDescriptionFlags::Required; +} - bool isRequired() const { - return Flags & GlobalOptionDescriptionFlags::Required; - } - void setRequired() { - Flags |= GlobalOptionDescriptionFlags::Required; - } +bool OptionDescription::isHidden() const { + return Flags & OptionDescriptionFlags::Hidden; +} +void OptionDescription::setHidden() { + Flags |= OptionDescriptionFlags::Hidden; +} - bool isHidden() const { - return Flags & GlobalOptionDescriptionFlags::Hidden; - } - void setHidden() { - Flags |= GlobalOptionDescriptionFlags::Hidden; - } +bool OptionDescription::isReallyHidden() const { + return Flags & OptionDescriptionFlags::ReallyHidden; +} +void OptionDescription::setReallyHidden() { + Flags |= OptionDescriptionFlags::ReallyHidden; +} - bool isReallyHidden() const { - return Flags & GlobalOptionDescriptionFlags::ReallyHidden; - } - void setReallyHidden() { - Flags |= GlobalOptionDescriptionFlags::ReallyHidden; +const char* OptionDescription::GenTypeDeclaration() const { + switch (Type) { + case OptionType::Alias: + return "cl::alias"; + case OptionType::ExternList: + case OptionType::PrefixList: + case OptionType::ParameterList: + return "cl::list"; + case OptionType::Switch: + case OptionType::ExternSwitch: + return "cl::opt"; + case OptionType::ExternParameter: + case OptionType::Parameter: + case OptionType::Prefix: + default: + return "cl::opt"; } +} - /// Merge - Merge two option descriptions. - void Merge (const GlobalOptionDescription& other) - { - if (other.Type != Type) - throw "Conflicting definitions for the option " + Name + "!"; - - if (Help == other.Help || Help == DefaultHelpString) - Help = other.Help; - else if (other.Help != DefaultHelpString) { - llvm::cerr << "Warning: several different help strings" - " defined for option " + Name + "\n"; - } - - Flags |= other.Flags; +std::string OptionDescription::GenVariableName() const { + const std::string& EscapedName = EscapeVariableName(Name); + switch (Type) { + case OptionType::Alias: + return "AutoGeneratedAlias_" + EscapedName; + case OptionType::PrefixList: + case OptionType::ParameterList: + case OptionType::ExternList: + return "AutoGeneratedList_" + EscapedName; + case OptionType::ExternSwitch: + case OptionType::Switch: + return "AutoGeneratedSwitch_" + EscapedName; + case OptionType::ExternParameter: + case OptionType::Prefix: + case OptionType::Parameter: + default: + return "AutoGeneratedParameter_" + EscapedName; } -}; +} -/// GlobalOptionDescriptions - A GlobalOptionDescription array -/// together with some flags affecting generation of option -/// declarations. -struct GlobalOptionDescriptions { - typedef StringMap container_type; - typedef container_type::const_iterator const_iterator; +/// OptionDescriptions - An OptionDescription array plus some helper +/// functions. +class OptionDescriptions { + typedef StringMap container_type; - /// Descriptions - A list of GlobalOptionDescriptions. + /// Descriptions - A list of OptionDescriptions. container_type Descriptions; - /// HasSink - Should the emitter generate a "cl::sink" option? - bool HasSink; +public: /// FindOption - exception-throwing wrapper for find(). - const GlobalOptionDescription& FindOption(const std::string& OptName) const { - const_iterator I = Descriptions.find(OptName); - if (I != Descriptions.end()) - return I->second; - else - throw OptName + ": no such option!"; - } + const OptionDescription& FindOption(const std::string& OptName) const; - /// insertDescription - Insert new GlobalOptionDescription into - /// GlobalOptionDescriptions list - void insertDescription (const GlobalOptionDescription& o) - { - container_type::iterator I = Descriptions.find(o.Name); - if (I != Descriptions.end()) { - GlobalOptionDescription& D = I->second; - D.Merge(o); - } - else { - Descriptions[o.Name] = o; - } - } + /// insertDescription - Insert new OptionDescription into + /// OptionDescriptions list + void InsertDescription (const OptionDescription& o); // Support for STL-style iteration + typedef container_type::const_iterator const_iterator; const_iterator begin() const { return Descriptions.begin(); } const_iterator end() const { return Descriptions.end(); } }; - -// Tool-local option description. - -// Properties without arguments are implemented as flags. -namespace ToolOptionDescriptionFlags { - enum ToolOptionDescriptionFlags { StopCompilation = 0x1, - Forward = 0x2, UnpackValues = 0x4}; -} -namespace OptionPropertyType { - enum OptionPropertyType { AppendCmd, ForwardAs, OutputSuffix }; +const OptionDescription& +OptionDescriptions::FindOption(const std::string& OptName) const +{ + const_iterator I = Descriptions.find(OptName); + if (I != Descriptions.end()) + return I->second; + else + throw OptName + ": no such option!"; } -typedef std::pair -OptionProperty; -typedef SmallVector OptionPropertyList; - -struct ToolOptionDescription : public OptionDescription { - unsigned Flags; - OptionPropertyList Props; - - // StringMap can only store DefaultConstructible objects - ToolOptionDescription() : OptionDescription(), Flags(0) {} - - ToolOptionDescription (OptionType::OptionType t, const std::string& n) - : OptionDescription(t, n) - {} - - // Various boolean properties - bool isStopCompilation() const { - return Flags & ToolOptionDescriptionFlags::StopCompilation; - } - void setStopCompilation() { - Flags |= ToolOptionDescriptionFlags::StopCompilation; - } - - bool isForward() const { - return Flags & ToolOptionDescriptionFlags::Forward; - } - void setForward() { - Flags |= ToolOptionDescriptionFlags::Forward; - } - - bool isUnpackValues() const { - return Flags & ToolOptionDescriptionFlags::UnpackValues; - } - void setUnpackValues() { - Flags |= ToolOptionDescriptionFlags::UnpackValues; +void OptionDescriptions::InsertDescription (const OptionDescription& o) +{ + container_type::iterator I = Descriptions.find(o.Name); + if (I != Descriptions.end()) { + OptionDescription& D = I->second; + D.Merge(o); } - - void AddProperty (OptionPropertyType::OptionPropertyType t, - const std::string& val) - { - Props.push_back(std::make_pair(t, val)); + else { + Descriptions[o.Name] = o; } -}; - -typedef StringMap ToolOptionDescriptions; - -// Tool information record - -namespace ToolFlags { - enum ToolFlags { Join = 0x1, Sink = 0x2 }; } -struct ToolProperties : public RefCountedBase { - std::string Name; - Init* CmdLine; - StrVector InLanguage; - std::string OutLanguage; - std::string OutputSuffix; - unsigned Flags; - ToolOptionDescriptions OptDescs; - - // Various boolean properties - void setSink() { Flags |= ToolFlags::Sink; } - bool isSink() const { return Flags & ToolFlags::Sink; } - void setJoin() { Flags |= ToolFlags::Join; } - bool isJoin() const { return Flags & ToolFlags::Join; } - - // Default ctor here is needed because StringMap can only store - // DefaultConstructible objects - ToolProperties() : CmdLine(0), Flags(0) {} - ToolProperties (const std::string& n) : Name(n), CmdLine(0), Flags(0) {} -}; - - -/// ToolPropertiesList - A list of Tool information records -/// IntrusiveRefCntPtrs are used here because StringMap has no copy -/// constructor (and we want to avoid copying ToolProperties anyway). -typedef std::vector > ToolPropertiesList; - - -/// CollectOptionProperties - Function object for iterating over a -/// list (usually, a DAG) of option property records. -class CollectOptionProperties { -private: +/// HandlerTable - A base class for function objects implemented as +/// 'tables of handlers'. +template +class HandlerTable { +protected: // Implementation details. - /// OptionPropertyHandler - a function that extracts information - /// about a given option property from its DAG representation. - typedef void (CollectOptionProperties::* OptionPropertyHandler) - (const DagInit*); - - /// OptionPropertyHandlerMap - A map from option property names to - /// option property handlers - typedef StringMap OptionPropertyHandlerMap; + /// Handler - + typedef void (T::* Handler) (const DagInit*); + /// HandlerMap - A map from property names to property handlers + typedef StringMap HandlerMap; - static OptionPropertyHandlerMap optionPropertyHandlers_; + static HandlerMap Handlers_; static bool staticMembersInitialized_; - /// This is where the information is stored - - /// toolProps_ - Properties of the current Tool. - ToolProperties* toolProps_; - /// optDescs_ - OptionDescriptions table (used to register options - /// globally). - GlobalOptionDescription& optDesc_; - + T* childPtr; public: - explicit CollectOptionProperties(ToolProperties* TP, - GlobalOptionDescription& OD) - : toolProps_(TP), optDesc_(OD) - { - if (!staticMembersInitialized_) { - optionPropertyHandlers_["append_cmd"] = - &CollectOptionProperties::onAppendCmd; - optionPropertyHandlers_["forward"] = - &CollectOptionProperties::onForward; - optionPropertyHandlers_["forward_as"] = - &CollectOptionProperties::onForwardAs; - optionPropertyHandlers_["help"] = - &CollectOptionProperties::onHelp; - optionPropertyHandlers_["hidden"] = - &CollectOptionProperties::onHidden; - optionPropertyHandlers_["output_suffix"] = - &CollectOptionProperties::onOutputSuffix; - optionPropertyHandlers_["really_hidden"] = - &CollectOptionProperties::onReallyHidden; - optionPropertyHandlers_["required"] = - &CollectOptionProperties::onRequired; - optionPropertyHandlers_["stop_compilation"] = - &CollectOptionProperties::onStopCompilation; - optionPropertyHandlers_["unpack_values"] = - &CollectOptionProperties::onUnpackValues; - - staticMembersInitialized_ = true; - } - } + HandlerTable(T* cp) : childPtr(cp) + {} - /// operator() - Gets called for every option property; Just forwards - /// to the corresponding property handler. + /// operator() - Just forwards to the corresponding property + /// handler. void operator() (Init* i) { - const DagInit& option_property = InitPtrToDag(i); - const std::string& option_property_name - = option_property.getOperator()->getAsString(); - OptionPropertyHandlerMap::iterator method - = optionPropertyHandlers_.find(option_property_name); - - if (method != optionPropertyHandlers_.end()) { - OptionPropertyHandler h = method->second; - (this->*h)(&option_property); + const DagInit& property = InitPtrToDag(i); + const std::string& property_name = property.getOperator()->getAsString(); + typename HandlerMap::iterator method = Handlers_.find(property_name); + + if (method != Handlers_.end()) { + Handler h = method->second; + (childPtr->*h)(&property); } else { - throw "Unknown option property: " + option_property_name + "!"; + throw "No handler found for property " + property_name + "!"; } } -private: + void AddHandler(const char* Property, Handler Handl) { + Handlers_[Property] = Handl; + } +}; - /// Option property handlers -- - /// Methods that handle properties that are common for all types of - /// options (like append_cmd, stop_compilation) +template typename HandlerTable::HandlerMap +HandlerTable::Handlers_; +template bool HandlerTable::staticMembersInitialized_ = false; - void onAppendCmd (const DagInit* d) { - checkNumberOfArguments(d, 1); - checkToolProps(d); - const std::string& cmd = InitPtrToString(d->getArg(0)); - toolProps_->OptDescs[optDesc_.Name]. - AddProperty(OptionPropertyType::AppendCmd, cmd); - } +/// CollectOptionProperties - Function object for iterating over an +/// option property list. +class CollectOptionProperties : public HandlerTable { +private: - void onOutputSuffix (const DagInit* d) { - checkNumberOfArguments(d, 1); - checkToolProps(d); - const std::string& suf = InitPtrToString(d->getArg(0)); + /// optDescs_ - OptionDescriptions table. This is where the + /// information is stored. + OptionDescription& optDesc_; - if (toolProps_->OptDescs[optDesc_.Name].Type != OptionType::Switch) - throw "Option " + optDesc_.Name - + " can't have 'output_suffix' property since it isn't a switch!"; +public: - toolProps_->OptDescs[optDesc_.Name].AddProperty - (OptionPropertyType::OutputSuffix, suf); - } + explicit CollectOptionProperties(OptionDescription& OD) + : HandlerTable(this), optDesc_(OD) + { + if (!staticMembersInitialized_) { + AddHandler("help", &CollectOptionProperties::onHelp); + AddHandler("hidden", &CollectOptionProperties::onHidden); + AddHandler("really_hidden", &CollectOptionProperties::onReallyHidden); + AddHandler("required", &CollectOptionProperties::onRequired); - void onForward (const DagInit* d) { - checkNumberOfArguments(d, 0); - checkToolProps(d); - toolProps_->OptDescs[optDesc_.Name].setForward(); + staticMembersInitialized_ = true; + } } - void onForwardAs (const DagInit* d) { - checkNumberOfArguments(d, 1); - checkToolProps(d); - const std::string& cmd = InitPtrToString(d->getArg(0)); +private: - toolProps_->OptDescs[optDesc_.Name]. - AddProperty(OptionPropertyType::ForwardAs, cmd); - } + /// Option property handlers -- + /// Methods that handle option properties such as (help) or (hidden). void onHelp (const DagInit* d) { checkNumberOfArguments(d, 1); const std::string& help_message = InitPtrToString(d->getArg(0)); - optDesc_.Help = help_message; } @@ -530,20 +440,6 @@ optDesc_.setRequired(); } - void onStopCompilation (const DagInit* d) { - checkNumberOfArguments(d, 0); - checkToolProps(d); - if (optDesc_.Type != OptionType::Switch) - throw std::string("Only options of type Switch can stop compilation!"); - toolProps_->OptDescs[optDesc_.Name].setStopCompilation(); - } - - void onUnpackValues (const DagInit* d) { - checkNumberOfArguments(d, 0); - checkToolProps(d); - toolProps_->OptDescs[optDesc_.Name].setUnpackValues(); - } - // Helper functions /// checkToolProps - Throw an error if toolProps_ == 0. @@ -555,146 +451,128 @@ }; -CollectOptionProperties::OptionPropertyHandlerMap -CollectOptionProperties::optionPropertyHandlers_; - -bool CollectOptionProperties::staticMembersInitialized_ = false; - - -/// processOptionProperties - Go through the list of option -/// properties and call a corresponding handler for each. -void processOptionProperties (const DagInit* d, ToolProperties* t, - GlobalOptionDescription& o) { - checkNumberOfArguments(d, 2); - DagInit::const_arg_iterator B = d->arg_begin(); - // Skip the first argument: it's always the option name. - ++B; - std::for_each(B, d->arg_end(), CollectOptionProperties(t, o)); -} - -/// AddOption - A function object wrapper for -/// processOptionProperties. Used by CollectProperties and -/// CollectPropertiesFromOptionList. +/// AddOption - A function object that is applied to every option +/// description. Used by CollectOptionDescriptions. class AddOption { private: - GlobalOptionDescriptions& OptDescs_; - ToolProperties* ToolProps_; + OptionDescriptions& OptDescs_; public: - explicit AddOption(GlobalOptionDescriptions& OD, ToolProperties* TP = 0) - : OptDescs_(OD), ToolProps_(TP) + explicit AddOption(OptionDescriptions& OD) : OptDescs_(OD) {} void operator()(const Init* i) { const DagInit& d = InitPtrToDag(i); - checkNumberOfArguments(&d, 2); + checkNumberOfArguments(&d, 1); const OptionType::OptionType Type = - getOptionType(d.getOperator()->getAsString()); + stringToOptionType(d.getOperator()->getAsString()); const std::string& Name = InitPtrToString(d.getArg(0)); - GlobalOptionDescription OD(Type, Name); - if (Type != OptionType::Alias) { - processOptionProperties(&d, ToolProps_, OD); - if (ToolProps_) { - ToolProps_->OptDescs[Name].Type = Type; - ToolProps_->OptDescs[Name].Name = Name; - } - } - else { + OptionDescription OD(Type, Name); + + if (!OD.isExtern()) + checkNumberOfArguments(&d, 2); + + if (OD.isAlias()) { + // Aliases store the aliased option name in the 'Help' field. OD.Help = InitPtrToString(d.getArg(1)); } - OptDescs_.insertDescription(OD); + else if (!OD.isExtern()) { + processOptionProperties(&d, OD); + } + OptDescs_.InsertDescription(OD); } private: - OptionType::OptionType getOptionType(const std::string& T) const { - if (T == "alias_option") - return OptionType::Alias; - else if (T == "switch_option") - return OptionType::Switch; - else if (T == "parameter_option") - return OptionType::Parameter; - else if (T == "parameter_list_option") - return OptionType::ParameterList; - else if (T == "prefix_option") - return OptionType::Prefix; - else if (T == "prefix_list_option") - return OptionType::PrefixList; - else - throw "Unknown option type: " + T + '!'; + /// processOptionProperties - Go through the list of option + /// properties and call a corresponding handler for each. + static void processOptionProperties (const DagInit* d, OptionDescription& o) { + checkNumberOfArguments(d, 2); + DagInit::const_arg_iterator B = d->arg_begin(); + // Skip the first argument: it's always the option name. + ++B; + std::for_each(B, d->arg_end(), CollectOptionProperties(o)); } + }; +/// CollectOptionDescriptions - Collects option properties from all +/// OptionLists. +void CollectOptionDescriptions (RecordVector::const_iterator B, + RecordVector::const_iterator E, + OptionDescriptions& OptDescs) +{ + // For every OptionList: + for (; B!=E; ++B) { + RecordVector::value_type T = *B; + // Throws an exception if the value does not exist. + ListInit* PropList = T->getValueAsListInit("options"); -/// CollectProperties - Function object for iterating over a list of -/// tool property records. -class CollectProperties { -private: + // For every option description in this list: + // collect the information and + std::for_each(PropList->begin(), PropList->end(), AddOption(OptDescs)); + } +} - // Implementation details +// Tool information record - /// PropertyHandler - a function that extracts information - /// about a given tool property from its DAG representation - typedef void (CollectProperties::*PropertyHandler)(const DagInit*); - - /// PropertyHandlerMap - A map from property names to property - /// handlers. - typedef StringMap PropertyHandlerMap; +namespace ToolFlags { + enum ToolFlags { Join = 0x1, Sink = 0x2 }; +} - // Static maps from strings to CollectProperties methods("handlers") - static PropertyHandlerMap propertyHandlers_; - static bool staticMembersInitialized_; +struct ToolDescription : public RefCountedBase { + std::string Name; + Init* CmdLine; + Init* Actions; + StrVector InLanguage; + std::string OutLanguage; + std::string OutputSuffix; + unsigned Flags; + // Various boolean properties + void setSink() { Flags |= ToolFlags::Sink; } + bool isSink() const { return Flags & ToolFlags::Sink; } + void setJoin() { Flags |= ToolFlags::Join; } + bool isJoin() const { return Flags & ToolFlags::Join; } + + // Default ctor here is needed because StringMap can only store + // DefaultConstructible objects + ToolDescription() : CmdLine(0), Actions(0), Flags(0) {} + ToolDescription (const std::string& n) + : Name(n), CmdLine(0), Actions(0), Flags(0) + {} +}; - /// This is where the information is stored +/// ToolDescriptions - A list of Tool information records. +typedef std::vector > ToolDescriptions; - /// toolProps_ - Properties of the current Tool. - ToolProperties& toolProps_; - /// optDescs_ - OptionDescriptions table (used to register options - /// globally). - GlobalOptionDescriptions& optDescs_; + +/// CollectToolProperties - Function object for iterating over a list of +/// tool property records. +class CollectToolProperties : public HandlerTable { +private: + + /// toolDesc_ - Properties of the current Tool. This is where the + /// information is stored. + ToolDescription& toolDesc_; public: - explicit CollectProperties (ToolProperties& p, GlobalOptionDescriptions& d) - : toolProps_(p), optDescs_(d) + explicit CollectToolProperties (ToolDescription& d) + : HandlerTable(this) , toolDesc_(d) { if (!staticMembersInitialized_) { - propertyHandlers_["cmd_line"] = &CollectProperties::onCmdLine; - propertyHandlers_["in_language"] = &CollectProperties::onInLanguage; - propertyHandlers_["join"] = &CollectProperties::onJoin; - propertyHandlers_["out_language"] = &CollectProperties::onOutLanguage; - propertyHandlers_["output_suffix"] = &CollectProperties::onOutputSuffix; - propertyHandlers_["parameter_option"] - = &CollectProperties::addOption; - propertyHandlers_["parameter_list_option"] = - &CollectProperties::addOption; - propertyHandlers_["prefix_option"] = &CollectProperties::addOption; - propertyHandlers_["prefix_list_option"] = - &CollectProperties::addOption; - propertyHandlers_["sink"] = &CollectProperties::onSink; - propertyHandlers_["switch_option"] = &CollectProperties::addOption; - propertyHandlers_["alias_option"] = &CollectProperties::addOption; - staticMembersInitialized_ = true; - } - } + AddHandler("actions", &CollectToolProperties::onActions); + AddHandler("cmd_line", &CollectToolProperties::onCmdLine); + AddHandler("in_language", &CollectToolProperties::onInLanguage); + AddHandler("join", &CollectToolProperties::onJoin); + AddHandler("out_language", &CollectToolProperties::onOutLanguage); + AddHandler("output_suffix", &CollectToolProperties::onOutputSuffix); + AddHandler("sink", &CollectToolProperties::onSink); - /// operator() - Gets called for every tool property; Just forwards - /// to the corresponding property handler. - void operator() (Init* i) { - const DagInit& d = InitPtrToDag(i); - const std::string& property_name = d.getOperator()->getAsString(); - PropertyHandlerMap::iterator method - = propertyHandlers_.find(property_name); - - if (method != propertyHandlers_.end()) { - PropertyHandler h = method->second; - (this->*h)(&d); - } - else { - throw "Unknown tool property: " + property_name + "!"; + staticMembersInitialized_ = true; } } @@ -704,9 +582,14 @@ /// Functions that extract information about tool properties from /// DAG representation. + void onActions (const DagInit* d) { + checkNumberOfArguments(d, 1); + toolDesc_.Actions = d->getArg(0); + } + void onCmdLine (const DagInit* d) { checkNumberOfArguments(d, 1); - toolProps_.CmdLine = d->getArg(0); + toolDesc_.CmdLine = d->getArg(0); } void onInLanguage (const DagInit* d) { @@ -716,12 +599,12 @@ // Find out the argument's type. if (typeid(*arg) == typeid(StringInit)) { // It's a string. - toolProps_.InLanguage.push_back(InitPtrToString(arg)); + toolDesc_.InLanguage.push_back(InitPtrToString(arg)); } else { // It's a list. const ListInit& lst = InitPtrToList(arg); - StrVector& out = toolProps_.InLanguage; + StrVector& out = toolDesc_.InLanguage; // Copy strings to the output vector. for (ListInit::const_iterator B = lst.begin(), E = lst.end(); @@ -738,46 +621,33 @@ void onJoin (const DagInit* d) { checkNumberOfArguments(d, 0); - toolProps_.setJoin(); + toolDesc_.setJoin(); } void onOutLanguage (const DagInit* d) { checkNumberOfArguments(d, 1); - toolProps_.OutLanguage = InitPtrToString(d->getArg(0)); + toolDesc_.OutLanguage = InitPtrToString(d->getArg(0)); } void onOutputSuffix (const DagInit* d) { checkNumberOfArguments(d, 1); - toolProps_.OutputSuffix = InitPtrToString(d->getArg(0)); + toolDesc_.OutputSuffix = InitPtrToString(d->getArg(0)); } void onSink (const DagInit* d) { checkNumberOfArguments(d, 0); - optDescs_.HasSink = true; - toolProps_.setSink(); - } - - // Just forwards to the AddOption function object. Somewhat - // non-optimal, but avoids code duplication. - void addOption (const DagInit* d) { - checkNumberOfArguments(d, 2); - AddOption(optDescs_, &toolProps_)(d); + toolDesc_.setSink(); } }; -// Defintions of static members of CollectProperties. -CollectProperties::PropertyHandlerMap CollectProperties::propertyHandlers_; -bool CollectProperties::staticMembersInitialized_ = false; - -/// CollectToolProperties - Gather information about tool properties +/// CollectToolDescriptions - Gather information about tool properties /// from the parsed TableGen data (basically a wrapper for the -/// CollectProperties function object). -void CollectToolProperties (RecordVector::const_iterator B, - RecordVector::const_iterator E, - ToolPropertiesList& TPList, - GlobalOptionDescriptions& OptDescs) +/// CollectToolProperties function object). +void CollectToolDescriptions (RecordVector::const_iterator B, + RecordVector::const_iterator E, + ToolDescriptions& ToolDescs) { // Iterate over a properties list of every Tool definition for (;B!=E;++B) { @@ -785,55 +655,211 @@ // Throws an exception if the value does not exist. ListInit* PropList = T->getValueAsListInit("properties"); - IntrusiveRefCntPtr - ToolProps(new ToolProperties(T->getName())); + IntrusiveRefCntPtr + ToolDesc(new ToolDescription(T->getName())); std::for_each(PropList->begin(), PropList->end(), - CollectProperties(*ToolProps, OptDescs)); - TPList.push_back(ToolProps); + CollectToolProperties(*ToolDesc)); + ToolDescs.push_back(ToolDesc); } } +/// FillInEdgeVector - Merge all compilation graph definitions into +/// one single edge list. +void FillInEdgeVector(RecordVector::const_iterator B, + RecordVector::const_iterator E, RecordVector& Out) { + for (; B != E; ++B) { + const ListInit* edges = (*B)->getValueAsListInit("edges"); + + for (unsigned i = 0; i < edges->size(); ++i) + Out.push_back(edges->getElementAsRecord(i)); + } +} -/// CollectPropertiesFromOptionLists - Gather information about -/// *global* option properties from all OptionLists. -void CollectPropertiesFromOptionLists (RecordVector::const_iterator B, - RecordVector::const_iterator E, - GlobalOptionDescriptions& OptDescs) -{ - // Iterate over a properties list of every Tool definition +/// CalculatePriority - Calculate the priority of this plugin. +int CalculatePriority(RecordVector::const_iterator B, + RecordVector::const_iterator E) { + int total = 0; for (; B!=E; ++B) { - RecordVector::value_type T = *B; - // Throws an exception if the value does not exist. - ListInit* PropList = T->getValueAsListInit("options"); + total += static_cast((*B)->getValueAsInt("priority")); + } + return total; +} - std::for_each(PropList->begin(), PropList->end(), AddOption(OptDescs)); +/// NotInGraph - Helper function object for FilterNotInGraph. +struct NotInGraph { +private: + const llvm::StringSet<>& ToolsInGraph_; + +public: + NotInGraph(const llvm::StringSet<>& ToolsInGraph) + : ToolsInGraph_(ToolsInGraph) + {} + + bool operator()(const IntrusiveRefCntPtr& x) { + return (ToolsInGraph_.count(x->Name) == 0); + } +}; + +/// FilterNotInGraph - Filter out from ToolDescs all Tools not +/// mentioned in the compilation graph definition. +void FilterNotInGraph (const RecordVector& EdgeVector, + ToolDescriptions& ToolDescs) { + + // List all tools mentioned in the graph. + llvm::StringSet<> ToolsInGraph; + + for (RecordVector::const_iterator B = EdgeVector.begin(), + E = EdgeVector.end(); B != E; ++B) { + + const Record* Edge = *B; + const std::string& A = Edge->getValueAsString("a"); + const std::string& B = Edge->getValueAsString("b"); + + if (A != "root") + ToolsInGraph.insert(A); + ToolsInGraph.insert(B); + } + + // Filter ToolPropertiesList. + ToolDescriptions::iterator new_end = + std::remove_if(ToolDescs.begin(), ToolDescs.end(), + NotInGraph(ToolsInGraph)); + ToolDescs.erase(new_end, ToolDescs.end()); +} + +/// FillInToolToLang - Fills in two tables that map tool names to +/// (input, output) languages. Helper function used by TypecheckGraph(). +void FillInToolToLang (const ToolDescriptions& ToolDescs, + StringMap >& ToolToInLang, + StringMap& ToolToOutLang) { + for (ToolDescriptions::const_iterator B = ToolDescs.begin(), + E = ToolDescs.end(); B != E; ++B) { + const ToolDescription& D = *(*B); + for (StrVector::const_iterator B = D.InLanguage.begin(), + E = D.InLanguage.end(); B != E; ++B) + ToolToInLang[D.Name].insert(*B); + ToolToOutLang[D.Name] = D.OutLanguage; } } +/// TypecheckGraph - Check that names for output and input languages +/// on all edges do match. This doesn't do much when the information +/// about the whole graph is not available (i.e. when compiling most +/// plugins). +void TypecheckGraph (const RecordVector& EdgeVector, + const ToolDescriptions& ToolDescs) { + StringMap > ToolToInLang; + StringMap ToolToOutLang; + + FillInToolToLang(ToolDescs, ToolToInLang, ToolToOutLang); + StringMap::iterator IAE = ToolToOutLang.end(); + StringMap >::iterator IBE = ToolToInLang.end(); + + for (RecordVector::const_iterator B = EdgeVector.begin(), + E = EdgeVector.end(); B != E; ++B) { + const Record* Edge = *B; + const std::string& A = Edge->getValueAsString("a"); + const std::string& B = Edge->getValueAsString("b"); + StringMap::iterator IA = ToolToOutLang.find(A); + StringMap >::iterator IB = ToolToInLang.find(B); + + if (A != "root") { + if (IA != IAE && IB != IBE && IB->second.count(IA->second) == 0) + throw "Edge " + A + "->" + B + + ": output->input language mismatch"; + } + + if (B == "root") + throw std::string("Edges back to the root are not allowed!"); + } +} + +/// WalkCase - Walks the 'case' expression DAG and invokes +/// TestCallback on every test, and StatementCallback on every +/// statement. Handles 'case' nesting, but not the 'and' and 'or' +/// combinators. +// TODO: Re-implement EmitCaseConstructHandler on top of this function? +template +void WalkCase(Init* Case, F1 TestCallback, F2 StatementCallback) { + const DagInit& d = InitPtrToDag(Case); + bool even = false; + for (DagInit::const_arg_iterator B = d.arg_begin(), E = d.arg_end(); + B != E; ++B) { + Init* arg = *B; + if (even && dynamic_cast(arg) + && static_cast(arg)->getOperator()->getAsString() == "case") + WalkCase(arg, TestCallback, StatementCallback); + else if (!even) + TestCallback(arg); + else + StatementCallback(arg); + even = !even; + } +} + +/// ExtractOptionNames - A helper function object used by +/// CheckForSuperfluousOptions() to walk the 'case' DAG. +class ExtractOptionNames { + llvm::StringSet<>& OptionNames_; +public: + ExtractOptionNames(llvm::StringSet<>& OptionNames) : OptionNames_(OptionNames) + {} + + void operator()(const Init* Statement) { + const DagInit& Stmt = InitPtrToDag(Statement); + const std::string& ActionName = Stmt.getOperator()->getAsString(); + if (ActionName == "forward" || ActionName == "forward_as" || + ActionName == "unpack_values" || ActionName == "switch_on" || + ActionName == "parameter_equals" || ActionName == "element_in_list" || + ActionName == "not_empty") { + checkNumberOfArguments(&Stmt, 1); + const std::string& Name = InitPtrToString(Stmt.getArg(0)); + OptionNames_.insert(Name); + } + else if (ActionName == "and" || ActionName == "or") { + for (unsigned i = 0, NumArgs = Stmt.getNumArgs(); i < NumArgs; ++i) { + this->operator()(Stmt.getArg(i)); + } + } + } +}; + /// CheckForSuperfluousOptions - Check that there are no side /// effect-free options (specified only in the OptionList). Otherwise, /// output a warning. -void CheckForSuperfluousOptions (const ToolPropertiesList& TPList, - const GlobalOptionDescriptions& OptDescs) { +void CheckForSuperfluousOptions (const RecordVector& Edges, + const ToolDescriptions& ToolDescs, + const OptionDescriptions& OptDescs) { llvm::StringSet<> nonSuperfluousOptions; - // Add all options mentioned in the TPList to the set of + // Add all options mentioned in the ToolDesc.Actions to the set of // non-superfluous options. - for (ToolPropertiesList::const_iterator B = TPList.begin(), - E = TPList.end(); B != E; ++B) { - const ToolProperties& TP = *(*B); - for (ToolOptionDescriptions::const_iterator B = TP.OptDescs.begin(), - E = TP.OptDescs.end(); B != E; ++B) { - nonSuperfluousOptions.insert(B->first()); - } + for (ToolDescriptions::const_iterator B = ToolDescs.begin(), + E = ToolDescs.end(); B != E; ++B) { + const ToolDescription& TD = *(*B); + ExtractOptionNames Callback(nonSuperfluousOptions); + if (TD.Actions) + WalkCase(TD.Actions, Callback, Callback); + } + + // Add all options mentioned in the 'case' clauses of the + // OptionalEdges of the compilation graph to the set of + // non-superfluous options. + for (RecordVector::const_iterator B = Edges.begin(), E = Edges.end(); + B != E; ++B) { + const Record* Edge = *B; + DagInit* Weight = Edge->getValueAsDag("weight"); + + if (!isDagEmpty(Weight)) + WalkCase(Weight, ExtractOptionNames(nonSuperfluousOptions), Id()); } // Check that all options in OptDescs belong to the set of // non-superfluous options. - for (GlobalOptionDescriptions::const_iterator B = OptDescs.begin(), + for (OptionDescriptions::const_iterator B = OptDescs.begin(), E = OptDescs.end(); B != E; ++B) { - const GlobalOptionDescription& Val = B->second; + const OptionDescription& Val = B->second; if (!nonSuperfluousOptions.count(Val.Name) && Val.Type != OptionType::Alias) llvm::cerr << "Warning: option '-" << Val.Name << "' has no effect! " @@ -845,14 +871,14 @@ /// EmitCaseConstructHandler. bool EmitCaseTest1Arg(const std::string& TestName, const DagInit& d, - const GlobalOptionDescriptions& OptDescs, + const OptionDescriptions& OptDescs, std::ostream& O) { checkNumberOfArguments(&d, 1); const std::string& OptName = InitPtrToString(d.getArg(0)); if (TestName == "switch_on") { - const GlobalOptionDescription& OptDesc = OptDescs.FindOption(OptName); - if (OptDesc.Type != OptionType::Switch) - throw OptName + ": incorrect option type!"; + const OptionDescription& OptDesc = OptDescs.FindOption(OptName); + if (!OptionType::IsSwitch(OptDesc.Type)) + throw OptName + ": incorrect option type - should be a switch!"; O << OptDesc.GenVariableName(); return true; } else if (TestName == "input_languages_contain") { @@ -871,9 +897,10 @@ return true; } else { - const GlobalOptionDescription& OptDesc = OptDescs.FindOption(OptName); - if (OptDesc.Type == OptionType::Switch) - throw OptName + ": incorrect option type!"; + const OptionDescription& OptDesc = OptDescs.FindOption(OptName); + if (OptionType::IsSwitch(OptDesc.Type)) + throw OptName + + ": incorrect option type - should be a list or parameter!"; O << '!' << OptDesc.GenVariableName() << ".empty()"; return true; } @@ -887,24 +914,22 @@ bool EmitCaseTest2Args(const std::string& TestName, const DagInit& d, const char* IndentLevel, - const GlobalOptionDescriptions& OptDescs, + const OptionDescriptions& OptDescs, std::ostream& O) { checkNumberOfArguments(&d, 2); const std::string& OptName = InitPtrToString(d.getArg(0)); const std::string& OptArg = InitPtrToString(d.getArg(1)); - const GlobalOptionDescription& OptDesc = OptDescs.FindOption(OptName); + const OptionDescription& OptDesc = OptDescs.FindOption(OptName); if (TestName == "parameter_equals") { - if (OptDesc.Type != OptionType::Parameter - && OptDesc.Type != OptionType::Prefix) - throw OptName + ": incorrect option type!"; + if (!OptionType::IsParameter(OptDesc.Type)) + throw OptName + ": incorrect option type - should be a parameter!"; O << OptDesc.GenVariableName() << " == \"" << OptArg << "\""; return true; } else if (TestName == "element_in_list") { - if (OptDesc.Type != OptionType::ParameterList - && OptDesc.Type != OptionType::PrefixList) - throw OptName + ": incorrect option type!"; + if (!OptionType::IsList(OptDesc.Type)) + throw OptName + ": incorrect option type - should be a list!"; const std::string& VarName = OptDesc.GenVariableName(); O << "std::find(" << VarName << ".begin(),\n" << IndentLevel << Indent1 << VarName << ".end(), \"" @@ -918,14 +943,14 @@ // Forward declaration. // EmitLogicalOperationTest and EmitCaseTest are mutually recursive. void EmitCaseTest(const DagInit& d, const char* IndentLevel, - const GlobalOptionDescriptions& OptDescs, + const OptionDescriptions& OptDescs, std::ostream& O); /// EmitLogicalOperationTest - Helper function used by /// EmitCaseConstructHandler. void EmitLogicalOperationTest(const DagInit& d, const char* LogicOp, const char* IndentLevel, - const GlobalOptionDescriptions& OptDescs, + const OptionDescriptions& OptDescs, std::ostream& O) { O << '('; for (unsigned j = 0, NumArgs = d.getNumArgs(); j < NumArgs; ++j) { @@ -940,7 +965,7 @@ /// EmitCaseTest - Helper function used by EmitCaseConstructHandler. void EmitCaseTest(const DagInit& d, const char* IndentLevel, - const GlobalOptionDescriptions& OptDescs, + const OptionDescriptions& OptDescs, std::ostream& O) { const std::string& TestName = d.getOperator()->getAsString(); @@ -960,178 +985,55 @@ // Takes a function object that should emit code for every case clause. // Callback's type is // void F(Init* Statement, const char* IndentLevel, std::ostream& O). -template -void EmitCaseConstructHandler(const DagInit* d, const char* IndentLevel, - F Callback, bool EmitElseIf, - const GlobalOptionDescriptions& OptDescs, - std::ostream& O) { - assert(d->getOperator()->getAsString() == "case"); - - unsigned numArgs = d->getNumArgs(); - if (d->getNumArgs() < 2) - throw "There should be at least one clause in the 'case' expression:\n" - + d->getAsString(); - - for (unsigned i = 0; i != numArgs; ++i) { - const DagInit& Test = InitPtrToDag(d->getArg(i)); - - // Emit the test. - if (Test.getOperator()->getAsString() == "default") { - if (i+2 != numArgs) - throw std::string("The 'default' clause should be the last in the" - "'case' construct!"); - O << IndentLevel << "else {\n"; - } - else { - O << IndentLevel << ((i != 0 && EmitElseIf) ? "else if (" : "if ("); - EmitCaseTest(Test, IndentLevel, OptDescs, O); - O << ") {\n"; - } - - // Emit the corresponding statement. - ++i; - if (i == numArgs) - throw "Case construct handler: no corresponding action " - "found for the test " + Test.getAsString() + '!'; - - Init* arg = d->getArg(i); - if (dynamic_cast(arg) - && static_cast(arg)->getOperator()->getAsString() == "case") { - EmitCaseConstructHandler(static_cast(arg), - (std::string(IndentLevel) + Indent1).c_str(), - Callback, EmitElseIf, OptDescs, O); - } - else { - Callback(arg, IndentLevel, O); - } - O << IndentLevel << "}\n"; - } -} - -/// EmitForwardOptionPropertyHandlingCode - Helper function used to -/// implement EmitOptionPropertyHandlingCode(). Emits code for -/// handling the (forward) and (forward_as) option properties. -void EmitForwardOptionPropertyHandlingCode (const ToolOptionDescription& D, - const std::string& NewName, - std::ostream& O) { - const std::string& Name = NewName.empty() - ? ("-" + D.Name) - : NewName; - - switch (D.Type) { - case OptionType::Switch: - O << Indent3 << "vec.push_back(\"" << Name << "\");\n"; - break; - case OptionType::Parameter: - O << Indent3 << "vec.push_back(\"" << Name << "\");\n"; - O << Indent3 << "vec.push_back(" << D.GenVariableName() << ");\n"; - break; - case OptionType::Prefix: - O << Indent3 << "vec.push_back(\"" << Name << "\" + " - << D.GenVariableName() << ");\n"; - break; - case OptionType::PrefixList: - O << Indent3 << "for (" << D.GenTypeDeclaration() - << "::iterator B = " << D.GenVariableName() << ".begin(),\n" - << Indent3 << "E = " << D.GenVariableName() << ".end(); B != E; ++B)\n" - << Indent4 << "vec.push_back(\"" << Name << "\" + " - << "*B);\n"; - break; - case OptionType::ParameterList: - O << Indent3 << "for (" << D.GenTypeDeclaration() - << "::iterator B = " << D.GenVariableName() << ".begin(),\n" - << Indent3 << "E = " << D.GenVariableName() - << ".end() ; B != E; ++B) {\n" - << Indent4 << "vec.push_back(\"" << Name << "\");\n" - << Indent4 << "vec.push_back(*B);\n" - << Indent3 << "}\n"; - break; - case OptionType::Alias: - default: - throw std::string("Aliases are not allowed in tool option descriptions!"); - } -} - -// ToolOptionHasInterestingProperties - A helper function used by -// EmitOptionPropertyHandlingCode() that tells us whether we should -// emit any property handling code at all. -bool ToolOptionHasInterestingProperties(const ToolOptionDescription& D) { - bool ret = false; - for (OptionPropertyList::const_iterator B = D.Props.begin(), - E = D.Props.end(); B != E; ++B) { - const OptionProperty& OptProp = *B; - if (OptProp.first == OptionPropertyType::AppendCmd - || OptProp.first == OptionPropertyType::ForwardAs) - ret = true; - } - if (D.isForward() || D.isUnpackValues()) - ret = true; - return ret; -} +template +void EmitCaseConstructHandler(const Init* Dag, const char* IndentLevel, + F Callback, bool EmitElseIf, + const OptionDescriptions& OptDescs, + std::ostream& O) { + const DagInit* d = &InitPtrToDag(Dag); + if (d->getOperator()->getAsString() != "case") + throw std::string("EmitCaseConstructHandler should be invoked" + " only on 'case' expressions!"); -/// EmitOptionPropertyHandlingCode - Helper function used by -/// EmitGenerateActionMethod(). Emits code that handles option -/// properties. -void EmitOptionPropertyHandlingCode (const ToolOptionDescription& D, - std::ostream& O) -{ - if (!ToolOptionHasInterestingProperties(D)) - return; - // Start of the if-clause. - O << Indent2 << "if ("; - if (D.Type == OptionType::Switch) - O << D.GenVariableName(); - else - O << '!' << D.GenVariableName() << ".empty()"; + unsigned numArgs = d->getNumArgs(); + if (d->getNumArgs() < 2) + throw "There should be at least one clause in the 'case' expression:\n" + + d->getAsString(); - O <<") {\n"; + for (unsigned i = 0; i != numArgs; ++i) { + const DagInit& Test = InitPtrToDag(d->getArg(i)); - // Handle option properties that take an argument. - for (OptionPropertyList::const_iterator B = D.Props.begin(), - E = D.Props.end(); B!=E; ++B) { - const OptionProperty& val = *B; - - switch (val.first) { - // (append_cmd cmd) property - case OptionPropertyType::AppendCmd: - O << Indent3 << "vec.push_back(\"" << val.second << "\");\n"; - break; - // (forward_as) property - case OptionPropertyType::ForwardAs: - EmitForwardOptionPropertyHandlingCode(D, val.second, O); - break; - // Other properties with argument - default: - break; + // Emit the test. + if (Test.getOperator()->getAsString() == "default") { + if (i+2 != numArgs) + throw std::string("The 'default' clause should be the last in the" + "'case' construct!"); + O << IndentLevel << "else {\n"; + } + else { + O << IndentLevel << ((i != 0 && EmitElseIf) ? "else if (" : "if ("); + EmitCaseTest(Test, IndentLevel, OptDescs, O); + O << ") {\n"; } - } - // Handle flags - - // (forward) property - if (D.isForward()) - EmitForwardOptionPropertyHandlingCode(D, "", O); - - // (unpack_values) property - if (D.isUnpackValues()) { - if (IsListOptionType(D.Type)) { - O << Indent3 << "for (" << D.GenTypeDeclaration() - << "::iterator B = " << D.GenVariableName() << ".begin(),\n" - << Indent3 << "E = " << D.GenVariableName() - << ".end(); B != E; ++B)\n" - << Indent4 << "llvm::SplitString(*B, vec, \",\");\n"; - } - else if (D.Type == OptionType::Prefix || D.Type == OptionType::Parameter){ - O << Indent3 << "llvm::SplitString(" - << D.GenVariableName() << ", vec, \",\");\n"; + // Emit the corresponding statement. + ++i; + if (i == numArgs) + throw "Case construct handler: no corresponding action " + "found for the test " + Test.getAsString() + '!'; + + Init* arg = d->getArg(i); + const DagInit* nd = dynamic_cast(arg); + if (nd && (nd->getOperator()->getAsString() == "case")) { + // Handle the nested 'case'. + EmitCaseConstructHandler(nd, (std::string(IndentLevel) + Indent1).c_str(), + Callback, EmitElseIf, OptDescs, O); } else { - throw std::string("Switches can't have unpack_values property!"); + Callback(arg, (std::string(IndentLevel) + Indent1).c_str(), O); } + O << IndentLevel << "}\n"; } - - // End of the if-clause. - O << Indent2 << "}\n"; } /// SubstituteSpecialCommands - Perform string substitution for $CALL @@ -1172,7 +1074,7 @@ /// EmitCmdLineVecFill - Emit code that fills in the command line /// vector. Helper function used by EmitGenerateActionMethod(). void EmitCmdLineVecFill(const Init* CmdLine, const std::string& ToolName, - bool Version, const char* IndentLevel, + bool IsJoin, const char* IndentLevel, std::ostream& O) { StrVector StrVec; SplitString(InitPtrToString(CmdLine), StrVec); @@ -1186,7 +1088,7 @@ O << IndentLevel; if (cmd.at(0) == '$') { if (cmd == "$INFILE") { - if (Version) + if (IsJoin) O << "for (PathVector::const_iterator B = inFiles.begin()" << ", E = inFiles.end();\n" << IndentLevel << "B != E; ++B)\n" @@ -1195,7 +1097,7 @@ O << "vec.push_back(inFile.toString());\n"; } else if (cmd == "$OUTFILE") { - O << "vec.push_back(outFile.toString());\n"; + O << "vec.push_back(out_file);\n"; } else { O << "vec.push_back(" << SubstituteSpecialCommands(cmd); @@ -1216,151 +1118,236 @@ /// EmitCmdLineVecFill(). Used by EmitGenerateActionMethod() as an /// argument to EmitCaseConstructHandler(). class EmitCmdLineVecFillCallback { - bool Version; + bool IsJoin; const std::string& ToolName; public: - EmitCmdLineVecFillCallback(bool Ver, const std::string& TN) - : Version(Ver), ToolName(TN) {} + EmitCmdLineVecFillCallback(bool J, const std::string& TN) + : IsJoin(J), ToolName(TN) {} + + void operator()(const Init* Statement, const char* IndentLevel, + std::ostream& O) const + { + EmitCmdLineVecFill(Statement, ToolName, IsJoin, + IndentLevel, O); + } +}; + +/// EmitForwardOptionPropertyHandlingCode - Helper function used to +/// implement EmitActionHandler. Emits code for +/// handling the (forward) and (forward_as) option properties. +void EmitForwardOptionPropertyHandlingCode (const OptionDescription& D, + const char* Indent, + const std::string& NewName, + std::ostream& O) { + const std::string& Name = NewName.empty() + ? ("-" + D.Name) + : NewName; + + switch (D.Type) { + case OptionType::Switch: + case OptionType::ExternSwitch: + O << Indent << "vec.push_back(\"" << Name << "\");\n"; + break; + case OptionType::Parameter: + case OptionType::ExternParameter: + O << Indent << "vec.push_back(\"" << Name << "\");\n"; + O << Indent << "vec.push_back(" << D.GenVariableName() << ");\n"; + break; + case OptionType::Prefix: + O << Indent << "vec.push_back(\"" << Name << "\" + " + << D.GenVariableName() << ");\n"; + break; + case OptionType::PrefixList: + O << Indent << "for (" << D.GenTypeDeclaration() + << "::iterator B = " << D.GenVariableName() << ".begin(),\n" + << Indent << "E = " << D.GenVariableName() << ".end(); B != E; ++B)\n" + << Indent << Indent1 << "vec.push_back(\"" << Name << "\" + " + << "*B);\n"; + break; + case OptionType::ParameterList: + case OptionType::ExternList: + O << Indent << "for (" << D.GenTypeDeclaration() + << "::iterator B = " << D.GenVariableName() << ".begin(),\n" + << Indent << "E = " << D.GenVariableName() + << ".end() ; B != E; ++B) {\n" + << Indent << Indent1 << "vec.push_back(\"" << Name << "\");\n" + << Indent << Indent1 << "vec.push_back(*B);\n" + << Indent << "}\n"; + break; + case OptionType::Alias: + default: + throw std::string("Aliases are not allowed in tool option descriptions!"); + } +} + +/// EmitActionHandler - Emit code that handles actions. Used by +/// EmitGenerateActionMethod() as an argument to +/// EmitCaseConstructHandler(). +class EmitActionHandler { + const OptionDescriptions& OptDescs; + public: + EmitActionHandler(const OptionDescriptions& OD) + : OptDescs(OD) {} void operator()(const Init* Statement, const char* IndentLevel, std::ostream& O) const { - EmitCmdLineVecFill(Statement, ToolName, Version, - (std::string(IndentLevel) + Indent1).c_str(), O); + const DagInit& Dag = InitPtrToDag(Statement); + const std::string& ActionName = Dag.getOperator()->getAsString(); + + if (ActionName == "append_cmd") { + checkNumberOfArguments(&Dag, 1); + const std::string& Cmd = InitPtrToString(Dag.getArg(0)); + O << IndentLevel << "vec.push_back(\"" << Cmd << "\");\n"; + } + else if (ActionName == "forward") { + checkNumberOfArguments(&Dag, 1); + const std::string& Name = InitPtrToString(Dag.getArg(0)); + EmitForwardOptionPropertyHandlingCode(OptDescs.FindOption(Name), + IndentLevel, "", O); + } + else if (ActionName == "forward_as") { + checkNumberOfArguments(&Dag, 2); + const std::string& Name = InitPtrToString(Dag.getArg(0)); + const std::string& NewName = InitPtrToString(Dag.getArg(0)); + EmitForwardOptionPropertyHandlingCode(OptDescs.FindOption(Name), + IndentLevel, NewName, O); + } + else if (ActionName == "output_suffix") { + checkNumberOfArguments(&Dag, 1); + const std::string& OutSuf = InitPtrToString(Dag.getArg(0)); + O << IndentLevel << "output_suffix = \"" << OutSuf << "\";\n"; + } + else if (ActionName == "stop_compilation") { + O << IndentLevel << "stop_compilation = true;\n"; + } + else if (ActionName == "unpack_values") { + checkNumberOfArguments(&Dag, 1); + const std::string& Name = InitPtrToString(Dag.getArg(0)); + const OptionDescription& D = OptDescs.FindOption(Name); + + if (OptionType::IsList(D.Type)) { + O << IndentLevel << "for (" << D.GenTypeDeclaration() + << "::iterator B = " << D.GenVariableName() << ".begin(),\n" + << IndentLevel << "E = " << D.GenVariableName() + << ".end(); B != E; ++B)\n" + << IndentLevel << Indent1 << "llvm::SplitString(*B, vec, \",\");\n"; + } + else if (OptionType::IsParameter(D.Type)){ + O << Indent3 << "llvm::SplitString(" + << D.GenVariableName() << ", vec, \",\");\n"; + } + else { + throw "Option '" + D.Name + + "': switches can't have the 'unpack_values' property!"; + } + } + else { + throw "Unknown action name: " + ActionName + "!"; + } } }; // EmitGenerateActionMethod - Emit one of two versions of the // Tool::GenerateAction() method. -void EmitGenerateActionMethod (const ToolProperties& P, - const GlobalOptionDescriptions& OptDescs, - bool Version, std::ostream& O) { - if (Version) +void EmitGenerateActionMethod (const ToolDescription& D, + const OptionDescriptions& OptDescs, + bool IsJoin, std::ostream& O) { + if (IsJoin) O << Indent1 << "Action GenerateAction(const PathVector& inFiles,\n"; else O << Indent1 << "Action GenerateAction(const sys::Path& inFile,\n"; - O << Indent2 << "const sys::Path& outFile,\n" + O << Indent2 << "bool HasChildren,\n" + << Indent2 << "const llvm::sys::Path& TempDir,\n" << Indent2 << "const InputLanguagesSet& InLangs,\n" << Indent2 << "const LanguageMap& LangMap) const\n" << Indent1 << "{\n" << Indent2 << "std::string cmd;\n" - << Indent2 << "std::vector vec;\n"; + << Indent2 << "std::vector vec;\n" + << Indent2 << "bool stop_compilation = !HasChildren;\n" + << Indent2 << "const char* output_suffix = \"" << D.OutputSuffix << "\";\n" + << Indent2 << "std::string out_file;\n\n"; + + // For every understood option, emit handling code. + if (D.Actions) + EmitCaseConstructHandler(D.Actions, Indent2, EmitActionHandler(OptDescs), + false, OptDescs, O); + + O << '\n' << Indent2 + << "out_file = OutFilename(" << (IsJoin ? "sys::Path(),\n" : "inFile,\n") + << Indent3 << "TempDir, stop_compilation, output_suffix).toString();\n\n"; // cmd_line is either a string or a 'case' construct. - if (typeid(*P.CmdLine) == typeid(StringInit)) - EmitCmdLineVecFill(P.CmdLine, P.Name, Version, Indent2, O); + if (!D.CmdLine) + throw "Tool " + D.Name + " has no cmd_line property!"; + else if (typeid(*D.CmdLine) == typeid(StringInit)) + EmitCmdLineVecFill(D.CmdLine, D.Name, IsJoin, Indent2, O); else - EmitCaseConstructHandler(&InitPtrToDag(P.CmdLine), Indent2, - EmitCmdLineVecFillCallback(Version, P.Name), + EmitCaseConstructHandler(D.CmdLine, Indent2, + EmitCmdLineVecFillCallback(IsJoin, D.Name), true, OptDescs, O); - // For every understood option, emit handling code. - for (ToolOptionDescriptions::const_iterator B = P.OptDescs.begin(), - E = P.OptDescs.end(); B != E; ++B) { - const ToolOptionDescription& val = B->second; - EmitOptionPropertyHandlingCode(val, O); - } - // Handle the Sink property. - if (P.isSink()) { + if (D.isSink()) { O << Indent2 << "if (!" << SinkOptionName << ".empty()) {\n" << Indent3 << "vec.insert(vec.end(), " << SinkOptionName << ".begin(), " << SinkOptionName << ".end());\n" << Indent2 << "}\n"; } - O << Indent2 << "return Action(cmd, vec);\n" + O << Indent2 << "return Action(cmd, vec, stop_compilation, out_file);\n" << Indent1 << "}\n\n"; } /// EmitGenerateActionMethods - Emit two GenerateAction() methods for /// a given Tool class. -void EmitGenerateActionMethods (const ToolProperties& P, - const GlobalOptionDescriptions& OptDescs, +void EmitGenerateActionMethods (const ToolDescription& ToolDesc, + const OptionDescriptions& OptDescs, std::ostream& O) { - if (!P.isJoin()) + if (!ToolDesc.isJoin()) O << Indent1 << "Action GenerateAction(const PathVector& inFiles,\n" - << Indent2 << "const llvm::sys::Path& outFile,\n" + << Indent2 << "bool HasChildren,\n" + << Indent2 << "const llvm::sys::Path& TempDir,\n" << Indent2 << "const InputLanguagesSet& InLangs,\n" << Indent2 << "const LanguageMap& LangMap) const\n" << Indent1 << "{\n" - << Indent2 << "throw std::runtime_error(\"" << P.Name + << Indent2 << "throw std::runtime_error(\"" << ToolDesc.Name << " is not a Join tool!\");\n" << Indent1 << "}\n\n"; else - EmitGenerateActionMethod(P, OptDescs, true, O); - - EmitGenerateActionMethod(P, OptDescs, false, O); -} - -/// EmitIsLastMethod - Emit the IsLast() method for a given Tool -/// class. -void EmitIsLastMethod (const ToolProperties& P, std::ostream& O) { - O << Indent1 << "bool IsLast() const {\n" - << Indent2 << "bool last = false;\n"; - - for (ToolOptionDescriptions::const_iterator B = P.OptDescs.begin(), - E = P.OptDescs.end(); B != E; ++B) { - const ToolOptionDescription& val = B->second; - - if (val.isStopCompilation()) - O << Indent2 - << "if (" << val.GenVariableName() - << ")\n" << Indent3 << "last = true;\n"; - } + EmitGenerateActionMethod(ToolDesc, OptDescs, true, O); - O << Indent2 << "return last;\n" - << Indent1 << "}\n\n"; + EmitGenerateActionMethod(ToolDesc, OptDescs, false, O); } /// EmitInOutLanguageMethods - Emit the [Input,Output]Language() /// methods for a given Tool class. -void EmitInOutLanguageMethods (const ToolProperties& P, std::ostream& O) { +void EmitInOutLanguageMethods (const ToolDescription& D, std::ostream& O) { O << Indent1 << "const char** InputLanguages() const {\n" << Indent2 << "return InputLanguages_;\n" << Indent1 << "}\n\n"; - O << Indent1 << "const char* OutputLanguage() const {\n" - << Indent2 << "return \"" << P.OutLanguage << "\";\n" - << Indent1 << "}\n\n"; -} - -/// EmitOutputSuffixMethod - Emit the OutputSuffix() method for a -/// given Tool class. -void EmitOutputSuffixMethod (const ToolProperties& P, std::ostream& O) { - O << Indent1 << "const char* OutputSuffix() const {\n" - << Indent2 << "const char* ret = \"" << P.OutputSuffix << "\";\n"; - - for (ToolOptionDescriptions::const_iterator B = P.OptDescs.begin(), - E = P.OptDescs.end(); B != E; ++B) { - const ToolOptionDescription& OptDesc = B->second; - for (OptionPropertyList::const_iterator B = OptDesc.Props.begin(), - E = OptDesc.Props.end(); B != E; ++B) { - const OptionProperty& OptProp = *B; - if (OptProp.first == OptionPropertyType::OutputSuffix) { - O << Indent2 << "if (" << OptDesc.GenVariableName() << ")\n" - << Indent3 << "ret = \"" << OptProp.second << "\";\n"; - } - } - } + if (D.OutLanguage.empty()) + throw "Tool " + D.Name + " has no 'out_language' property!"; - O << Indent2 << "return ret;\n" + O << Indent1 << "const char* OutputLanguage() const {\n" + << Indent2 << "return \"" << D.OutLanguage << "\";\n" << Indent1 << "}\n\n"; } /// EmitNameMethod - Emit the Name() method for a given Tool class. -void EmitNameMethod (const ToolProperties& P, std::ostream& O) { +void EmitNameMethod (const ToolDescription& D, std::ostream& O) { O << Indent1 << "const char* Name() const {\n" - << Indent2 << "return \"" << P.Name << "\";\n" + << Indent2 << "return \"" << D.Name << "\";\n" << Indent1 << "}\n\n"; } /// EmitIsJoinMethod - Emit the IsJoin() method for a given Tool /// class. -void EmitIsJoinMethod (const ToolProperties& P, std::ostream& O) { +void EmitIsJoinMethod (const ToolDescription& D, std::ostream& O) { O << Indent1 << "bool IsJoin() const {\n"; - if (P.isJoin()) + if (D.isJoin()) O << Indent2 << "return true;\n"; else O << Indent2 << "return false;\n"; @@ -1369,24 +1356,27 @@ /// EmitStaticMemberDefinitions - Emit static member definitions for a /// given Tool class. -void EmitStaticMemberDefinitions(const ToolProperties& P, std::ostream& O) { - O << "const char* " << P.Name << "::InputLanguages_[] = {"; - for (StrVector::const_iterator B = P.InLanguage.begin(), - E = P.InLanguage.end(); B != E; ++B) +void EmitStaticMemberDefinitions(const ToolDescription& D, std::ostream& O) { + if (D.InLanguage.empty()) + throw "Tool " + D.Name + " has no 'in_language' property!"; + + O << "const char* " << D.Name << "::InputLanguages_[] = {"; + for (StrVector::const_iterator B = D.InLanguage.begin(), + E = D.InLanguage.end(); B != E; ++B) O << '\"' << *B << "\", "; O << "0};\n\n"; } /// EmitToolClassDefinition - Emit a Tool class definition. -void EmitToolClassDefinition (const ToolProperties& P, - const GlobalOptionDescriptions& OptDescs, +void EmitToolClassDefinition (const ToolDescription& D, + const OptionDescriptions& OptDescs, std::ostream& O) { - if (P.Name == "root") + if (D.Name == "root") return; // Header - O << "class " << P.Name << " : public "; - if (P.isJoin()) + O << "class " << D.Name << " : public "; + if (D.isJoin()) O << "JoinTool"; else O << "Tool"; @@ -1395,40 +1385,48 @@ << Indent1 << "static const char* InputLanguages_[];\n\n"; O << "public:\n"; - EmitNameMethod(P, O); - EmitInOutLanguageMethods(P, O); - EmitOutputSuffixMethod(P, O); - EmitIsJoinMethod(P, O); - EmitGenerateActionMethods(P, OptDescs, O); - EmitIsLastMethod(P, O); + EmitNameMethod(D, O); + EmitInOutLanguageMethods(D, O); + EmitIsJoinMethod(D, O); + EmitGenerateActionMethods(D, OptDescs, O); // Close class definition O << "};\n"; - EmitStaticMemberDefinitions(P, O); + EmitStaticMemberDefinitions(D, O); } -/// EmitOptionDescriptions - Iterate over a list of option -/// descriptions and emit registration code. -void EmitOptionDescriptions (const GlobalOptionDescriptions& descs, - std::ostream& O) +/// EmitOptionDefintions - Iterate over a list of option descriptions +/// and emit registration code. +void EmitOptionDefintions (const OptionDescriptions& descs, + bool HasSink, + std::ostream& O) { - std::vector Aliases; + std::vector Aliases; // Emit static cl::Option variables. - for (GlobalOptionDescriptions::const_iterator B = descs.begin(), + for (OptionDescriptions::const_iterator B = descs.begin(), E = descs.end(); B!=E; ++B) { - const GlobalOptionDescription& val = B->second; + const OptionDescription& val = B->second; if (val.Type == OptionType::Alias) { Aliases.push_back(val); continue; } + if (val.isExtern()) + O << "extern "; + O << val.GenTypeDeclaration() << ' ' - << val.GenVariableName() - << "(\"" << val.Name << '\"'; + << val.GenVariableName(); + + if (val.isExtern()) { + O << ";\n"; + continue; + } + + O << "(\"" << val.Name << '\"'; if (val.Type == OptionType::Prefix || val.Type == OptionType::PrefixList) O << ", cl::Prefix"; @@ -1462,26 +1460,22 @@ } // Emit the aliases (they should go after all the 'proper' options). - for (std::vector::const_iterator + for (std::vector::const_iterator B = Aliases.begin(), E = Aliases.end(); B != E; ++B) { - const GlobalOptionDescription& val = *B; + const OptionDescription& val = *B; O << val.GenTypeDeclaration() << ' ' << val.GenVariableName() << "(\"" << val.Name << '\"'; - GlobalOptionDescriptions::container_type - ::const_iterator F = descs.Descriptions.find(val.Help); - if (F != descs.Descriptions.end()) - O << ", cl::aliasopt(" << F->second.GenVariableName() << ")"; - else - throw val.Name + ": alias to an unknown option!"; + const OptionDescription& D = descs.FindOption(val.Help); + O << ", cl::aliasopt(" << D.GenVariableName() << ")"; O << ", cl::desc(\"" << "An alias for -" + val.Help << "\"));\n"; } // Emit the sink option. - if (descs.HasSink) + if (HasSink) O << "cl::list " << SinkOptionName << "(cl::Sink);\n"; O << '\n'; @@ -1520,53 +1514,6 @@ O << "}\n\n}\n\n"; } -/// FillInToolToLang - Fills in two tables that map tool names to -/// (input, output) languages. Used by the typechecker. -void FillInToolToLang (const ToolPropertiesList& TPList, - StringMap >& ToolToInLang, - StringMap& ToolToOutLang) { - for (ToolPropertiesList::const_iterator B = TPList.begin(), E = TPList.end(); - B != E; ++B) { - const ToolProperties& P = *(*B); - for (StrVector::const_iterator B = P.InLanguage.begin(), - E = P.InLanguage.end(); B != E; ++B) - ToolToInLang[P.Name].insert(*B); - ToolToOutLang[P.Name] = P.OutLanguage; - } -} - -/// TypecheckGraph - Check that names for output and input languages -/// on all edges do match. This doesn't do much when the information -/// about the whole graph is not available (i.e. when compiling most -/// plugins). -void TypecheckGraph (const RecordVector& EdgeVector, - const ToolPropertiesList& TPList) { - StringMap > ToolToInLang; - StringMap ToolToOutLang; - - FillInToolToLang(TPList, ToolToInLang, ToolToOutLang); - StringMap::iterator IAE = ToolToOutLang.end(); - StringMap >::iterator IBE = ToolToInLang.end(); - - for (RecordVector::const_iterator Beg = EdgeVector.begin(), - E = EdgeVector.end(); Beg != E; ++Beg) { - const Record* Edge = *Beg; - const std::string& A = Edge->getValueAsString("a"); - const std::string& B = Edge->getValueAsString("b"); - StringMap::iterator IA = ToolToOutLang.find(A); - StringMap >::iterator IB = ToolToInLang.find(B); - - if (A != "root") { - if (IA != IAE && IB != IBE && IB->second.count(IA->second) == 0) - throw "Edge " + A + "->" + B - + ": output->input language mismatch"; - } - - if (B == "root") - throw std::string("Edges back to the root are not allowed!"); - } -} - /// IncDecWeight - Helper function passed to EmitCaseConstructHandler() /// by EmitEdgeClass(). void IncDecWeight (const Init* i, const char* IndentLevel, @@ -1575,9 +1522,9 @@ const std::string& OpName = d.getOperator()->getAsString(); if (OpName == "inc_weight") - O << IndentLevel << Indent1 << "ret += "; + O << IndentLevel << "ret += "; else if (OpName == "dec_weight") - O << IndentLevel << Indent1 << "ret -= "; + O << IndentLevel << "ret -= "; else throw "Unknown operator in edge properties list: " + OpName + '!'; @@ -1590,7 +1537,7 @@ /// EmitEdgeClass - Emit a single Edge# class. void EmitEdgeClass (unsigned N, const std::string& Target, - DagInit* Case, const GlobalOptionDescriptions& OptDescs, + DagInit* Case, const OptionDescriptions& OptDescs, std::ostream& O) { // Class constructor. @@ -1612,7 +1559,7 @@ /// EmitEdgeClasses - Emit Edge* classes that represent graph edges. void EmitEdgeClasses (const RecordVector& EdgeVector, - const GlobalOptionDescriptions& OptDescs, + const OptionDescriptions& OptDescs, std::ostream& O) { int i = 0; for (RecordVector::const_iterator Beg = EdgeVector.begin(), @@ -1630,14 +1577,14 @@ /// EmitPopulateCompilationGraph - Emit the PopulateCompilationGraph() /// function. void EmitPopulateCompilationGraph (const RecordVector& EdgeVector, - const ToolPropertiesList& ToolProps, + const ToolDescriptions& ToolDescs, std::ostream& O) { O << "namespace {\n\n"; O << "void PopulateCompilationGraphLocal(CompilationGraph& G) {\n"; - for (ToolPropertiesList::const_iterator B = ToolProps.begin(), - E = ToolProps.end(); B != E; ++B) + for (ToolDescriptions::const_iterator B = ToolDescs.begin(), + E = ToolDescs.end(); B != E; ++B) O << Indent1 << "G.insertNode(new " << (*B)->Name << "());\n"; O << '\n'; @@ -1669,73 +1616,61 @@ /// ExtractHookNames - Extract the hook names from all instances of /// $CALL(HookName) in the provided command line string. Helper /// function used by FillInHookNames(). -void ExtractHookNames(const Init* CmdLine, StrVector& HookNames) { - StrVector cmds; - llvm::SplitString(InitPtrToString(CmdLine), cmds); - for (StrVector::const_iterator B = cmds.begin(), E = cmds.end(); - B != E; ++B) { - const std::string& cmd = *B; - if (cmd.find("$CALL(") == 0) { - if (cmd.size() == 6) - throw std::string("$CALL invocation: empty argument list!"); - HookNames.push_back(std::string(cmd.begin() + 6, - cmd.begin() + cmd.find(")"))); - } - } -} +class ExtractHookNames { + llvm::StringSet<>& HookNames_; +public: + ExtractHookNames(llvm::StringSet<>& HookNames) + : HookNames_(HookNames_) {} -/// ExtractHookNamesFromCaseConstruct - Extract hook names from the -/// 'case' expression, handle nesting. Helper function used by -/// FillInHookNames(). -void ExtractHookNamesFromCaseConstruct(Init* Case, StrVector& HookNames) { - const DagInit& d = InitPtrToDag(Case); - bool even = false; - for (DagInit::const_arg_iterator B = d.arg_begin(), E = d.arg_end(); - B != E; ++B) { - Init* arg = *B; - if (even && dynamic_cast(arg) - && static_cast(arg)->getOperator()->getAsString() == "case") - ExtractHookNamesFromCaseConstruct(arg, HookNames); - else if (even) - ExtractHookNames(arg, HookNames); - even = !even; + void operator()(const Init* CmdLine) { + StrVector cmds; + llvm::SplitString(InitPtrToString(CmdLine), cmds); + for (StrVector::const_iterator B = cmds.begin(), E = cmds.end(); + B != E; ++B) { + const std::string& cmd = *B; + if (cmd.find("$CALL(") == 0) { + if (cmd.size() == 6) + throw std::string("$CALL invocation: empty argument list!"); + HookNames_.insert(std::string(cmd.begin() + 6, + cmd.begin() + cmd.find(")"))); + } + } } -} +}; /// FillInHookNames - Actually extract the hook names from all command /// line strings. Helper function used by EmitHookDeclarations(). -void FillInHookNames(const ToolPropertiesList& TPList, - StrVector& HookNames) { +void FillInHookNames(const ToolDescriptions& ToolDescs, + llvm::StringSet<>& HookNames) +{ // For all command lines: - for (ToolPropertiesList::const_iterator B = TPList.begin(), - E = TPList.end(); B != E; ++B) { - const ToolProperties& P = *(*B); - if (!P.CmdLine) + for (ToolDescriptions::const_iterator B = ToolDescs.begin(), + E = ToolDescs.end(); B != E; ++B) { + const ToolDescription& D = *(*B); + if (!D.CmdLine) continue; - if (dynamic_cast(P.CmdLine)) + if (dynamic_cast(D.CmdLine)) // This is a string. - ExtractHookNames(P.CmdLine, HookNames); + ExtractHookNames(HookNames).operator()(D.CmdLine); else // This is a 'case' construct. - ExtractHookNamesFromCaseConstruct(P.CmdLine, HookNames); + WalkCase(D.CmdLine, Id(), ExtractHookNames(HookNames)); } } /// EmitHookDeclarations - Parse CmdLine fields of all the tool /// property records and emit hook function declaration for each /// instance of $CALL(HookName). -void EmitHookDeclarations(const ToolPropertiesList& ToolProps, - std::ostream& O) { - StrVector HookNames; - FillInHookNames(ToolProps, HookNames); +void EmitHookDeclarations(const ToolDescriptions& ToolDescs, std::ostream& O) { + llvm::StringSet<> HookNames; + FillInHookNames(ToolDescs, HookNames); if (HookNames.empty()) return; - std::sort(HookNames.begin(), HookNames.end()); - StrVector::const_iterator E = std::unique(HookNames.begin(), HookNames.end()); O << "namespace hooks {\n"; - for (StrVector::const_iterator B = HookNames.begin(); B != E; ++B) - O << Indent1 << "std::string " << *B << "();\n"; + for (StringSet<>::const_iterator B = HookNames.begin(), E = HookNames.end(); + B != E; ++B) + O << Indent1 << "std::string " << B->first() << "();\n"; O << "}\n\n"; } @@ -1777,138 +1712,113 @@ << "{ return s == NULL ? \"\" : s; }\n\n"; } -/// NotInGraph - Helper function object for FilterNotInGraph. -struct NotInGraph { -private: - const llvm::StringSet<>& ToolsInGraph_; - -public: - NotInGraph(const llvm::StringSet<>& ToolsInGraph) - : ToolsInGraph_(ToolsInGraph) - {} - bool operator()(const IntrusiveRefCntPtr& x) { - return (ToolsInGraph_.count(x->Name) == 0); - } +/// PluginData - Holds all information about a plugin. +struct PluginData { + OptionDescriptions OptDescs; + bool HasSink; + ToolDescriptions ToolDescs; + RecordVector Edges; + int Priority; }; -/// FilterNotInGraph - Filter out from ToolProps all Tools not -/// mentioned in the compilation graph definition. -void FilterNotInGraph (const RecordVector& EdgeVector, - ToolPropertiesList& ToolProps) { - - // List all tools mentioned in the graph. - llvm::StringSet<> ToolsInGraph; - - for (RecordVector::const_iterator Beg = EdgeVector.begin(), - E = EdgeVector.end(); Beg != E; ++Beg) { - - const Record* Edge = *Beg; - const std::string& A = Edge->getValueAsString("a"); - const std::string& B = Edge->getValueAsString("b"); - - if (A != "root") - ToolsInGraph.insert(A); - ToolsInGraph.insert(B); - } - - // Filter ToolPropertiesList. - ToolPropertiesList::iterator new_end = - std::remove_if(ToolProps.begin(), ToolProps.end(), - NotInGraph(ToolsInGraph)); - ToolProps.erase(new_end, ToolProps.end()); -} - -/// CalculatePriority - Calculate the priority of this plugin. -int CalculatePriority(RecordVector::const_iterator B, - RecordVector::const_iterator E) { - int total = 0; - for (; B!=E; ++B) { - total += static_cast((*B)->getValueAsInt("priority")); - } - return total; -} - -/// FillInEdgeVector - Merge all compilation graph definitions into -/// one single edge list. -void FillInEdgeVector(RecordVector::const_iterator B, - RecordVector::const_iterator E, RecordVector& Out) { - for (; B != E; ++B) { - const ListInit* edges = (*B)->getValueAsListInit("edges"); - - for (unsigned i = 0; i < edges->size(); ++i) - Out.push_back(edges->getElementAsRecord(i)); - } -} +/// HasSink - Go through the list of tool descriptions and check if +/// there is one with the 'sink' property set. +bool HasSink(const ToolDescriptions& ToolDescs) { + for (ToolDescriptions::const_iterator B = ToolDescs.begin(), + E = ToolDescs.end(); B != E; ++B) + if ((*B)->isSink()) + return true; -// End of anonymous namespace + return false; } -/// run - The back-end entry point. -void LLVMCConfigurationEmitter::run (std::ostream &O) { - try { - - // Emit file header. - EmitSourceFileHeader("LLVMC Configuration Library", O); - EmitIncludes(O); - - // Collect tool properties. - RecordVector Tools = Records.getAllDerivedDefinitions("Tool"); - ToolPropertiesList ToolProps; - GlobalOptionDescriptions OptDescs; - CollectToolProperties(Tools.begin(), Tools.end(), ToolProps, OptDescs); - +/// CollectPluginData - Collect tool and option properties, +/// compilation graph edges and plugin priority from the parse tree. +void CollectPluginData (const RecordKeeper& Records, PluginData& Data) { // Collect option properties. const RecordVector& OptionLists = Records.getAllDerivedDefinitions("OptionList"); - CollectPropertiesFromOptionLists(OptionLists.begin(), OptionLists.end(), - OptDescs); + CollectOptionDescriptions(OptionLists.begin(), OptionLists.end(), + Data.OptDescs); + + // Collect tool properties. + const RecordVector& Tools = Records.getAllDerivedDefinitions("Tool"); + CollectToolDescriptions(Tools.begin(), Tools.end(), Data.ToolDescs); + Data.HasSink = HasSink(Data.ToolDescs); // Collect compilation graph edges. const RecordVector& CompilationGraphs = Records.getAllDerivedDefinitions("CompilationGraph"); - RecordVector EdgeVector; FillInEdgeVector(CompilationGraphs.begin(), CompilationGraphs.end(), - EdgeVector); + Data.Edges); + // Calculate the priority of this plugin. + const RecordVector& Priorities = + Records.getAllDerivedDefinitions("PluginPriority"); + Data.Priority = CalculatePriority(Priorities.begin(), Priorities.end()); +} + +/// CheckPluginData - Perform some sanity checks on the collected data. +void CheckPluginData(PluginData& Data) { // Filter out all tools not mentioned in the compilation graph. - FilterNotInGraph(EdgeVector, ToolProps); + FilterNotInGraph(Data.Edges, Data.ToolDescs); // Typecheck the compilation graph. - TypecheckGraph(EdgeVector, ToolProps); + TypecheckGraph(Data.Edges, Data.ToolDescs); // Check that there are no options without side effects (specified // only in the OptionList). - CheckForSuperfluousOptions(ToolProps, OptDescs); + CheckForSuperfluousOptions(Data.Edges, Data.ToolDescs, Data.OptDescs); + +} + +void EmitPluginCode(const PluginData& Data, std::ostream& O) { + // Emit file header. + EmitIncludes(O); // Emit global option registration code. - EmitOptionDescriptions(OptDescs, O); + EmitOptionDefintions(Data.OptDescs, Data.HasSink, O); // Emit hook declarations. - EmitHookDeclarations(ToolProps, O); + EmitHookDeclarations(Data.ToolDescs, O); // Emit PopulateLanguageMap() function // (a language map maps from file extensions to language names). EmitPopulateLanguageMap(Records, O); // Emit Tool classes. - for (ToolPropertiesList::const_iterator B = ToolProps.begin(), - E = ToolProps.end(); B!=E; ++B) - EmitToolClassDefinition(*(*B), OptDescs, O); + for (ToolDescriptions::const_iterator B = Data.ToolDescs.begin(), + E = Data.ToolDescs.end(); B!=E; ++B) + EmitToolClassDefinition(*(*B), Data.OptDescs, O); // Emit Edge# classes. - EmitEdgeClasses(EdgeVector, OptDescs, O); + EmitEdgeClasses(Data.Edges, Data.OptDescs, O); // Emit PopulateCompilationGraph() function. - EmitPopulateCompilationGraph(EdgeVector, ToolProps, O); + EmitPopulateCompilationGraph(Data.Edges, Data.ToolDescs, O); // Emit code for plugin registration. - const RecordVector& Priorities = - Records.getAllDerivedDefinitions("PluginPriority"); - EmitRegisterPlugin(CalculatePriority(Priorities.begin(), - Priorities.end()), O); + EmitRegisterPlugin(Data.Priority, O); // EOF +} + + +// End of anonymous namespace +} + +/// run - The back-end entry point. +void LLVMCConfigurationEmitter::run (std::ostream &O) { + try { + PluginData Data; + + CollectPluginData(Records, Data); + CheckPluginData(Data); + + EmitSourceFileHeader("LLVMC Configuration Library", O); + EmitPluginCode(Data, O); + } catch (std::exception& Error) { throw Error.what() + std::string(" - usually this means a syntax error."); } From foldr at codedgers.com Sun Dec 7 10:41:51 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Sun, 07 Dec 2008 16:41:51 -0000 Subject: [llvm-commits] [llvm] r60657 - in /llvm/trunk/test/LLVMC: EmptyCompilationGraph.td ExternOptions.td MultipleCompilationGraphs.td NoActions.td NoCompilationGraph.td TestWarnings.td llvmc.exp Message-ID: <200812071641.mB7GfpW0002266@zion.cs.uiuc.edu> Author: foldr Date: Sun Dec 7 10:41:50 2008 New Revision: 60657 URL: http://llvm.org/viewvc/llvm-project?rev=60657&view=rev Log: Add tests for tblgen's LLVMC backend. Added: llvm/trunk/test/LLVMC/EmptyCompilationGraph.td llvm/trunk/test/LLVMC/ExternOptions.td llvm/trunk/test/LLVMC/MultipleCompilationGraphs.td llvm/trunk/test/LLVMC/NoActions.td llvm/trunk/test/LLVMC/NoCompilationGraph.td llvm/trunk/test/LLVMC/TestWarnings.td Modified: llvm/trunk/test/LLVMC/llvmc.exp Added: llvm/trunk/test/LLVMC/EmptyCompilationGraph.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/EmptyCompilationGraph.td?rev=60657&view=auto ============================================================================== --- llvm/trunk/test/LLVMC/EmptyCompilationGraph.td (added) +++ llvm/trunk/test/LLVMC/EmptyCompilationGraph.td Sun Dec 7 10:41:50 2008 @@ -0,0 +1,6 @@ +// Check that the compilation graph can be empty. +// RUN: tblgen -I $srcroot/include --gen-llvmc %s + +include "llvm/CompilerDriver/Common.td" + +def Graph : CompilationGraph<[]>; Added: llvm/trunk/test/LLVMC/ExternOptions.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/ExternOptions.td?rev=60657&view=auto ============================================================================== --- llvm/trunk/test/LLVMC/ExternOptions.td (added) +++ llvm/trunk/test/LLVMC/ExternOptions.td Sun Dec 7 10:41:50 2008 @@ -0,0 +1,20 @@ +// Check that extern options work. +// The dummy tool and graph are required to silence warnings. +// RUN: tblgen -I $srcroot/include --gen-llvmc %s | grep extern + +include "llvm/CompilerDriver/Common.td" + +def OptList : OptionList<[(extern_switch "Wall"), + (extern_parameter "std"), (extern_list "L")]>; + +def dummy_tool : Tool<[ +(cmd_line "dummy_cmd"), +(in_language "dummy"), +(out_language "dummy"), +(actions (case + (switch_on "Wall"), (stop_compilation), + (not_empty "std"), (stop_compilation), + (not_empty "L"), (stop_compilation))) +]>; + +def DummyGraph : CompilationGraph<[SimpleEdge<"root", "dummy_tool">]>; Added: llvm/trunk/test/LLVMC/MultipleCompilationGraphs.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/MultipleCompilationGraphs.td?rev=60657&view=auto ============================================================================== --- llvm/trunk/test/LLVMC/MultipleCompilationGraphs.td (added) +++ llvm/trunk/test/LLVMC/MultipleCompilationGraphs.td Sun Dec 7 10:41:50 2008 @@ -0,0 +1,8 @@ +// Check that multiple compilation graphs are allowed. +// RUN: tblgen -I $srcroot/include --gen-llvmc %s + +include "llvm/CompilerDriver/Common.td" + +def Graph1 : CompilationGraph<[]>; +def Graph2 : CompilationGraph<[]>; +def Graph3 : CompilationGraph<[]>; Added: llvm/trunk/test/LLVMC/NoActions.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/NoActions.td?rev=60657&view=auto ============================================================================== --- llvm/trunk/test/LLVMC/NoActions.td (added) +++ llvm/trunk/test/LLVMC/NoActions.td Sun Dec 7 10:41:50 2008 @@ -0,0 +1,12 @@ +// Check that tools without associated actions are accepted. +// RUN: tblgen -I $srcroot/include --gen-llvmc %s | grep dummy_tool + +include "llvm/CompilerDriver/Common.td" + +def dummy_tool : Tool<[ +(cmd_line "dummy_cmd"), +(in_language "dummy"), +(out_language "dummy") +]>; + +def DummyGraph : CompilationGraph<[SimpleEdge<"root", "dummy_tool">]>; Added: llvm/trunk/test/LLVMC/NoCompilationGraph.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/NoCompilationGraph.td?rev=60657&view=auto ============================================================================== --- llvm/trunk/test/LLVMC/NoCompilationGraph.td (added) +++ llvm/trunk/test/LLVMC/NoCompilationGraph.td Sun Dec 7 10:41:50 2008 @@ -0,0 +1,4 @@ +// Check that the compilation graph is not required. +// RUN: tblgen -I $srcroot/include --gen-llvmc %s + +include "llvm/CompilerDriver/Common.td" Added: llvm/trunk/test/LLVMC/TestWarnings.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/TestWarnings.td?rev=60657&view=auto ============================================================================== --- llvm/trunk/test/LLVMC/TestWarnings.td (added) +++ llvm/trunk/test/LLVMC/TestWarnings.td Sun Dec 7 10:41:50 2008 @@ -0,0 +1,8 @@ +// Check that the compiler warns about unused options!. +// RUN: tblgen -I $srcroot/include --gen-llvmc %s | grep extern +// XFAIL: * + +include "llvm/CompilerDriver/Common.td" + +def OptList : OptionList<[(extern_switch "Wall"), + (extern_parameter "std"), (extern_list "L")]>; Modified: llvm/trunk/test/LLVMC/llvmc.exp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/llvmc.exp?rev=60657&r1=60656&r2=60657&view=diff ============================================================================== --- llvm/trunk/test/LLVMC/llvmc.exp (original) +++ llvm/trunk/test/LLVMC/llvmc.exp Sun Dec 7 10:41:50 2008 @@ -8,3 +8,4 @@ RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{cpp}]] } +RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{td}]] From foldr at codedgers.com Sun Dec 7 10:42:22 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Sun, 07 Dec 2008 16:42:22 -0000 Subject: [llvm-commits] [llvm] r60658 - /llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Message-ID: <200812071642.mB7GgMsX002291@zion.cs.uiuc.edu> Author: foldr Date: Sun Dec 7 10:42:22 2008 New Revision: 60658 URL: http://llvm.org/viewvc/llvm-project?rev=60658&view=rev Log: Add a (progn)-like construct for (actions). Implemented as a DAG list. Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=60658&r1=60657&r2=60658&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Sun Dec 7 10:42:22 2008 @@ -802,11 +802,8 @@ /// CheckForSuperfluousOptions() to walk the 'case' DAG. class ExtractOptionNames { llvm::StringSet<>& OptionNames_; -public: - ExtractOptionNames(llvm::StringSet<>& OptionNames) : OptionNames_(OptionNames) - {} - void operator()(const Init* Statement) { + void processDag(const Init* Statement) { const DagInit& Stmt = InitPtrToDag(Statement); const std::string& ActionName = Stmt.getOperator()->getAsString(); if (ActionName == "forward" || ActionName == "forward_as" || @@ -819,10 +816,26 @@ } else if (ActionName == "and" || ActionName == "or") { for (unsigned i = 0, NumArgs = Stmt.getNumArgs(); i < NumArgs; ++i) { - this->operator()(Stmt.getArg(i)); + this->processDag(Stmt.getArg(i)); } } } + +public: + ExtractOptionNames(llvm::StringSet<>& OptionNames) : OptionNames_(OptionNames) + {} + + void operator()(const Init* Statement) { + if (typeid(*Statement) == typeid(ListInit)) { + const ListInit& DagList = *static_cast(Statement); + for (ListInit::const_iterator B = DagList.begin(), E = DagList.end(); + B != E; ++B) + this->processDag(*B); + } + else { + this->processDag(Statement); + } + } }; /// CheckForSuperfluousOptions - Check that there are no side @@ -1185,12 +1198,9 @@ /// EmitCaseConstructHandler(). class EmitActionHandler { const OptionDescriptions& OptDescs; - public: - EmitActionHandler(const OptionDescriptions& OD) - : OptDescs(OD) {} - void operator()(const Init* Statement, const char* IndentLevel, - std::ostream& O) const + void processActionDag(const Init* Statement, const char* IndentLevel, + std::ostream& O) const { const DagInit& Dag = InitPtrToDag(Statement); const std::string& ActionName = Dag.getOperator()->getAsString(); @@ -1246,6 +1256,23 @@ throw "Unknown action name: " + ActionName + "!"; } } + public: + EmitActionHandler(const OptionDescriptions& OD) + : OptDescs(OD) {} + + void operator()(const Init* Statement, const char* IndentLevel, + std::ostream& O) const + { + if (typeid(*Statement) == typeid(ListInit)) { + const ListInit& DagList = *static_cast(Statement); + for (ListInit::const_iterator B = DagList.begin(), E = DagList.end(); + B != E; ++B) + this->processActionDag(*B, IndentLevel, O); + } + else { + this->processActionDag(Statement, IndentLevel, O); + } + } }; // EmitGenerateActionMethod - Emit one of two versions of the From foldr at codedgers.com Sun Dec 7 10:42:47 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Sun, 07 Dec 2008 16:42:47 -0000 Subject: [llvm-commits] [llvm] r60659 - /llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Message-ID: <200812071642.mB7GglRd002315@zion.cs.uiuc.edu> Author: foldr Date: Sun Dec 7 10:42:47 2008 New Revision: 60659 URL: http://llvm.org/viewvc/llvm-project?rev=60659&view=rev Log: Try to guess when the auto-generated cl::Sink option should be marked 'extern'. This would be much easier to do if the CommandLine library didn't use global state. Global state is evil. Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=60659&r1=60658&r2=60659&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Sun Dec 7 10:42:47 2008 @@ -1427,7 +1427,7 @@ /// EmitOptionDefintions - Iterate over a list of option descriptions /// and emit registration code. void EmitOptionDefintions (const OptionDescriptions& descs, - bool HasSink, + bool HasSink, bool HasExterns, std::ostream& O) { std::vector Aliases; @@ -1503,7 +1503,9 @@ // Emit the sink option. if (HasSink) - O << "cl::list " << SinkOptionName << "(cl::Sink);\n"; + O << (HasExterns ? "extern cl" : "cl") + << "::list " << SinkOptionName + << (HasExterns ? ";\n" : "(cl::Sink);\n"); O << '\n'; } @@ -1744,20 +1746,32 @@ struct PluginData { OptionDescriptions OptDescs; bool HasSink; + bool HasExterns; ToolDescriptions ToolDescs; RecordVector Edges; int Priority; }; /// HasSink - Go through the list of tool descriptions and check if -/// there is one with the 'sink' property set. +/// there are any with the 'sink' property set. bool HasSink(const ToolDescriptions& ToolDescs) { for (ToolDescriptions::const_iterator B = ToolDescs.begin(), E = ToolDescs.end(); B != E; ++B) if ((*B)->isSink()) return true; - return false; + return false; +} + +/// HasExterns - Go through the list of option descriptions and check +/// if there are any external options. +bool HasExterns(const OptionDescriptions& OptDescs) { + for (OptionDescriptions::const_iterator B = OptDescs.begin(), + E = OptDescs.end(); B != E; ++B) + if (B->second.isExtern()) + return true; + + return false; } /// CollectPluginData - Collect tool and option properties, @@ -1773,6 +1787,7 @@ const RecordVector& Tools = Records.getAllDerivedDefinitions("Tool"); CollectToolDescriptions(Tools.begin(), Tools.end(), Data.ToolDescs); Data.HasSink = HasSink(Data.ToolDescs); + Data.HasExterns = HasExterns(Data.OptDescs); // Collect compilation graph edges. const RecordVector& CompilationGraphs = @@ -1805,7 +1820,7 @@ EmitIncludes(O); // Emit global option registration code. - EmitOptionDefintions(Data.OptDescs, Data.HasSink, O); + EmitOptionDefintions(Data.OptDescs, Data.HasSink, Data.HasExterns, O); // Emit hook declarations. EmitHookDeclarations(Data.ToolDescs, O); From foldr at codedgers.com Sun Dec 7 10:43:17 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Sun, 07 Dec 2008 16:43:17 -0000 Subject: [llvm-commits] [llvm] r60660 - in /llvm/trunk/tools/llvmc/plugins: Clang/Clang.td Hello/Hello.cpp Message-ID: <200812071643.mB7GhHrb002362@zion.cs.uiuc.edu> Author: foldr Date: Sun Dec 7 10:43:17 2008 New Revision: 60660 URL: http://llvm.org/viewvc/llvm-project?rev=60660&view=rev Log: Update plugins to use (actions). Modified: llvm/trunk/tools/llvmc/plugins/Clang/Clang.td llvm/trunk/tools/llvmc/plugins/Hello/Hello.cpp Modified: llvm/trunk/tools/llvmc/plugins/Clang/Clang.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/plugins/Clang/Clang.td?rev=60660&r1=60659&r2=60660&view=diff ============================================================================== --- llvm/trunk/tools/llvmc/plugins/Clang/Clang.td (original) +++ llvm/trunk/tools/llvmc/plugins/Clang/Clang.td Sun Dec 7 10:43:17 2008 @@ -1,4 +1,5 @@ -// A (first stab at a) replacement for the Clang's ccc script. +// A replacement for the Clang's ccc script. +// Depends on the Base plugin. // To compile, use this command: // cd $LLVMC2_DIR // make DRIVER_NAME=ccc2 BUILTIN_PLUGINS=Clang @@ -6,8 +7,10 @@ include "llvm/CompilerDriver/Common.td" def Options : OptionList<[ -(switch_option "E", - (help "Stop after the preprocessing stage, do not run the compiler")) +(extern_switch "E", + (help "Stop after the preprocessing stage, do not run the compiler")), +(extern_list "L", (help "Specify a library search path")), +(switch_option "clang", (help "Use Clang instead of llvm-gcc")) ]>; class clang_based : Tool< @@ -23,7 +26,8 @@ !strconcat(cmd, " -E $INFILE")), (default), !strconcat(cmd, " -emit-llvm-bc $INFILE -o $OUTFILE"))), - (switch_option "E", (stop_compilation), (output_suffix "i")), + (actions (case (switch_on "E"), + [(stop_compilation), (output_suffix "i")])), (sink) ]>; @@ -39,7 +43,7 @@ (out_language "executable"), (output_suffix "out"), (cmd_line "llvm-ld -native -disable-internalize $INFILE -o $OUTFILE"), - (prefix_list_option "L", (forward), (help "Specify a library search path")), + (actions (case (not_empty "L"), (forward "L"))), (join) ]>; @@ -56,9 +60,12 @@ // Compilation graph def CompilationGraph : CompilationGraph<[ - Edge<"root", "clang_c">, - Edge<"root", "clang_cpp">, - Edge<"root", "clang_objective_c">, + OptionalEdge<"root", "clang_c", + (case (switch_on "clang"), (inc_weight))>, + OptionalEdge<"root", "clang_cpp", + (case (switch_on "clang"), (inc_weight))>, + OptionalEdge<"root", "clang_objective_c", + (case (switch_on "clang"), (inc_weight))>, Edge<"clang_c", "llvm_ld">, Edge<"clang_cpp", "llvm_ld">, Edge<"clang_objective_c", "llvm_ld"> Modified: llvm/trunk/tools/llvmc/plugins/Hello/Hello.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/plugins/Hello/Hello.cpp?rev=60660&r1=60659&r2=60660&view=diff ============================================================================== --- llvm/trunk/tools/llvmc/plugins/Hello/Hello.cpp (original) +++ llvm/trunk/tools/llvmc/plugins/Hello/Hello.cpp Sun Dec 7 10:43:17 2008 @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// Test plugin for LLVMC. +// Test plugin for LLVMC. Shows how to write plugins without using TableGen. // //===----------------------------------------------------------------------===// From foldr at codedgers.com Sun Dec 7 10:43:42 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Sun, 07 Dec 2008 16:43:42 -0000 Subject: [llvm-commits] [llvm] r60661 - /llvm/trunk/tools/llvmc/Makefile Message-ID: <200812071643.mB7Ghhpx002384@zion.cs.uiuc.edu> Author: foldr Date: Sun Dec 7 10:43:42 2008 New Revision: 60661 URL: http://llvm.org/viewvc/llvm-project?rev=60661&view=rev Log: Enable the Clang plugin by default. This will eventually replace `ccc`. The command `llvmc -clang` now uses the Clang toolchain instead of `llvm-gcc`. Modified: llvm/trunk/tools/llvmc/Makefile Modified: llvm/trunk/tools/llvmc/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/Makefile?rev=60661&r1=60660&r2=60661&view=diff ============================================================================== --- llvm/trunk/tools/llvmc/Makefile (original) +++ llvm/trunk/tools/llvmc/Makefile Sun Dec 7 10:43:42 2008 @@ -9,7 +9,7 @@ LEVEL = ../.. -BUILTIN_PLUGINS = Base +BUILTIN_PLUGINS = Base Clang DRIVER_NAME = llvmc DIRS = plugins driver From foldr at codedgers.com Sun Dec 7 10:44:15 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Sun, 07 Dec 2008 16:44:15 -0000 Subject: [llvm-commits] [llvm] r60662 - /llvm/trunk/test/LLVMC/TestWarnings.td Message-ID: <200812071644.mB7GiFqT002437@zion.cs.uiuc.edu> Author: foldr Date: Sun Dec 7 10:44:15 2008 New Revision: 60662 URL: http://llvm.org/viewvc/llvm-project?rev=60662&view=rev Log: Add some clarifying comments. Modified: llvm/trunk/test/LLVMC/TestWarnings.td Modified: llvm/trunk/test/LLVMC/TestWarnings.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/TestWarnings.td?rev=60662&r1=60661&r2=60662&view=diff ============================================================================== --- llvm/trunk/test/LLVMC/TestWarnings.td (original) +++ llvm/trunk/test/LLVMC/TestWarnings.td Sun Dec 7 10:44:15 2008 @@ -1,4 +1,5 @@ -// Check that the compiler warns about unused options!. +// Check that the compiler warns about unused options. +// This should fail because the output is printed on stderr. // RUN: tblgen -I $srcroot/include --gen-llvmc %s | grep extern // XFAIL: * From foldr at codedgers.com Sun Dec 7 10:44:48 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Sun, 07 Dec 2008 16:44:48 -0000 Subject: [llvm-commits] [llvm] r60663 - /llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Message-ID: <200812071644.mB7GimXO002461@zion.cs.uiuc.edu> Author: foldr Date: Sun Dec 7 10:44:47 2008 New Revision: 60663 URL: http://llvm.org/viewvc/llvm-project?rev=60663&view=rev Log: Re-apply Cedric's changes. Use B instead of Beg (for consistency), but NodeA and NodeB instead of A and B. Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=60663&r1=60662&r2=60663&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Sun Dec 7 10:44:47 2008 @@ -713,12 +713,12 @@ E = EdgeVector.end(); B != E; ++B) { const Record* Edge = *B; - const std::string& A = Edge->getValueAsString("a"); - const std::string& B = Edge->getValueAsString("b"); + const std::string& NodeA = Edge->getValueAsString("a"); + const std::string& NodeB = Edge->getValueAsString("b"); - if (A != "root") - ToolsInGraph.insert(A); - ToolsInGraph.insert(B); + if (NodeA != "root") + ToolsInGraph.insert(NodeA); + ToolsInGraph.insert(NodeB); } // Filter ToolPropertiesList. @@ -759,18 +759,18 @@ for (RecordVector::const_iterator B = EdgeVector.begin(), E = EdgeVector.end(); B != E; ++B) { const Record* Edge = *B; - const std::string& A = Edge->getValueAsString("a"); - const std::string& B = Edge->getValueAsString("b"); - StringMap::iterator IA = ToolToOutLang.find(A); - StringMap >::iterator IB = ToolToInLang.find(B); + const std::string& NodeA = Edge->getValueAsString("a"); + const std::string& NodeB = Edge->getValueAsString("b"); + StringMap::iterator IA = ToolToOutLang.find(NodeA); + StringMap >::iterator IB = ToolToInLang.find(NodeB); - if (A != "root") { + if (NodeA != "root") { if (IA != IAE && IB != IBE && IB->second.count(IA->second) == 0) - throw "Edge " + A + "->" + B + throw "Edge " + NodeA + "->" + NodeB + ": output->input language mismatch"; } - if (B == "root") + if (NodeB == "root") throw std::string("Edges back to the root are not allowed!"); } } @@ -1591,14 +1591,14 @@ const OptionDescriptions& OptDescs, std::ostream& O) { int i = 0; - for (RecordVector::const_iterator Beg = EdgeVector.begin(), - E = EdgeVector.end(); Beg != E; ++Beg) { - const Record* Edge = *Beg; - const std::string& B = Edge->getValueAsString("b"); + for (RecordVector::const_iterator B = EdgeVector.begin(), + E = EdgeVector.end(); B != E; ++B) { + const Record* Edge = *B; + const std::string& NodeB = Edge->getValueAsString("b"); DagInit* Weight = Edge->getValueAsDag("weight"); if (!isDagEmpty(Weight)) - EmitEdgeClass(i, B, Weight, OptDescs, O); + EmitEdgeClass(i, NodeB, Weight, OptDescs, O); ++i; } } @@ -1621,17 +1621,17 @@ // Insert edges. int i = 0; - for (RecordVector::const_iterator Beg = EdgeVector.begin(), - E = EdgeVector.end(); Beg != E; ++Beg) { - const Record* Edge = *Beg; - const std::string& A = Edge->getValueAsString("a"); - const std::string& B = Edge->getValueAsString("b"); + for (RecordVector::const_iterator B = EdgeVector.begin(), + E = EdgeVector.end(); B != E; ++B) { + const Record* Edge = *B; + const std::string& NodeA = Edge->getValueAsString("a"); + const std::string& NodeB = Edge->getValueAsString("b"); DagInit* Weight = Edge->getValueAsDag("weight"); - O << Indent1 << "G.insertEdge(\"" << A << "\", "; + O << Indent1 << "G.insertEdge(\"" << NodeA << "\", "; if (isDagEmpty(Weight)) - O << "new SimpleEdge(\"" << B << "\")"; + O << "new SimpleEdge(\"" << NodeB << "\")"; else O << "new Edge" << i << "()"; From foldr at codedgers.com Sun Dec 7 10:45:13 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Sun, 07 Dec 2008 16:45:13 -0000 Subject: [llvm-commits] [llvm] r60664 - /llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Message-ID: <200812071645.mB7GjD82002487@zion.cs.uiuc.edu> Author: foldr Date: Sun Dec 7 10:45:12 2008 New Revision: 60664 URL: http://llvm.org/viewvc/llvm-project?rev=60664&view=rev Log: Better error message. Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=60664&r1=60663&r2=60664&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Sun Dec 7 10:45:12 2008 @@ -584,7 +584,12 @@ void onActions (const DagInit* d) { checkNumberOfArguments(d, 1); - toolDesc_.Actions = d->getArg(0); + Init* Case = d->getArg(0); + if (typeid(*Case) != typeid(DagInit) || + static_cast(Case)->getOperator()->getAsString() != "case") + throw + std::string("The argument to (actions) should be a 'case' construct!"); + toolDesc_.Actions = Case; } void onCmdLine (const DagInit* d) { From foldr at codedgers.com Sun Dec 7 10:45:37 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Sun, 07 Dec 2008 16:45:37 -0000 Subject: [llvm-commits] [llvm] r60665 - /llvm/trunk/tools/llvmc/driver/CompilationGraph.cpp Message-ID: <200812071645.mB7GjbsW002544@zion.cs.uiuc.edu> Author: foldr Date: Sun Dec 7 10:45:37 2008 New Revision: 60665 URL: http://llvm.org/viewvc/llvm-project?rev=60665&view=rev Log: Join tools couldn't be used in the middle of the toolchain. Modified: llvm/trunk/tools/llvmc/driver/CompilationGraph.cpp Modified: llvm/trunk/tools/llvmc/driver/CompilationGraph.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/driver/CompilationGraph.cpp?rev=60665&r1=60664&r2=60665&view=diff ============================================================================== --- llvm/trunk/tools/llvmc/driver/CompilationGraph.cpp (original) +++ llvm/trunk/tools/llvmc/driver/CompilationGraph.cpp Sun Dec 7 10:45:37 2008 @@ -308,7 +308,6 @@ for (std::vector::iterator B = JTV.begin(), E = JTV.end(); B != E; ++B) { - sys::Path Out; const Node* CurNode = *B; JoinTool* JT = &dynamic_cast(*CurNode->ToolPtr.getPtr()); @@ -325,10 +324,10 @@ if (CurAction.StopCompilation()) return 0; - const Node* NextNode = - &getNode(ChooseEdge(CurNode->OutEdges, InLangs, - CurNode->Name())->ToolName()); - PassThroughGraph(Out, NextNode, InLangs, TempDir, LangMap); + const Node* NextNode = &getNode(ChooseEdge(CurNode->OutEdges, InLangs, + CurNode->Name())->ToolName()); + PassThroughGraph(sys::Path(CurAction.OutFile()), NextNode, + InLangs, TempDir, LangMap); } return 0; From foldr at codedgers.com Sun Dec 7 10:46:23 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Sun, 07 Dec 2008 16:46:23 -0000 Subject: [llvm-commits] [llvm] r60666 - in /llvm/trunk: include/llvm/CompilerDriver/Tools.td tools/llvmc/plugins/Clang/Clang.td Message-ID: <200812071646.mB7GkN8L002576@zion.cs.uiuc.edu> Author: foldr Date: Sun Dec 7 10:46:23 2008 New Revision: 60666 URL: http://llvm.org/viewvc/llvm-project?rev=60666&view=rev Log: Plugin updates: support more options. Modified: llvm/trunk/include/llvm/CompilerDriver/Tools.td llvm/trunk/tools/llvmc/plugins/Clang/Clang.td Modified: llvm/trunk/include/llvm/CompilerDriver/Tools.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CompilerDriver/Tools.td?rev=60666&r1=60665&r2=60666&view=diff ============================================================================== --- llvm/trunk/include/llvm/CompilerDriver/Tools.td (original) +++ llvm/trunk/include/llvm/CompilerDriver/Tools.td Sun Dec 7 10:46:23 2008 @@ -24,6 +24,8 @@ (help "Stop after compilation, do not assemble")), (switch_option "c", (help "Compile and assemble, but do not link")), + (switch_option "pthread", + (help "Enable threads")), (parameter_option "linker", (help "Choose linker (possible values: gcc, g++)")), (parameter_list_option "include", @@ -57,10 +59,11 @@ (actions (case (switch_on "emit-llvm"), (stop_compilation), - (switch_on "E"), (stop_compilation), + (switch_on "E"), [(stop_compilation), (output_suffix "i")], + (switch_on "S"), (stop_compilation), (switch_on "fsyntax-only"), (stop_compilation), (not_empty "include"), (forward "include"), - (not_empty "I"), (forward "include"))), + (not_empty "I"), (forward "I"))), (sink) ]>; @@ -83,15 +86,6 @@ (cmd_line "llvm-as $INFILE -o $OUTFILE") ]>; -def llc : Tool< -[(in_language "llvm-bitcode"), - (out_language "assembler"), - (output_suffix "s"), - (actions (case - (switch_on "S"), (stop_compilation))), - (cmd_line "llc -f $INFILE -o $OUTFILE") -]>; - def llvm_gcc_assembler : Tool< [(in_language "assembler"), (out_language "object-code"), @@ -102,6 +96,14 @@ (not_empty "Wa,"), (unpack_values "Wa,"))) ]>; +def llc : Tool< +[(in_language "llvm-bitcode"), + (out_language "assembler"), + (output_suffix "s"), + (cmd_line "llc -relocation-model=pic -f $INFILE -o $OUTFILE"), + (actions (case (switch_on "S"), (stop_compilation))) +]>; + // Base class for linkers class llvm_gcc_based_linker : Tool< [(in_language "object-code"), @@ -110,6 +112,7 @@ (cmd_line !strconcat(cmd_prefix, " $INFILE -o $OUTFILE")), (join), (actions (case + (switch_on "pthread"), (append_cmd "-lpthread"), (not_empty "L"), (forward "L"), (not_empty "l"), (forward "l"), (not_empty "Wl,"), (unpack_values "Wl,"))) @@ -125,9 +128,12 @@ def LanguageMap : LanguageMap< [LangToSuffixes<"c++", ["cc", "cp", "cxx", "cpp", "CPP", "c++", "C"]>, LangToSuffixes<"c", ["c"]>, + LangToSuffixes<"c-cpp-output", ["i"]>, + LangToSuffixes<"objective-c-cpp-output", ["mi"]>, LangToSuffixes<"objective-c++", ["mm"]>, LangToSuffixes<"objective-c", ["m"]>, LangToSuffixes<"assembler", ["s"]>, + LangToSuffixes<"assembler-with-cpp", ["S"]>, LangToSuffixes<"llvm-assembler", ["ll"]>, LangToSuffixes<"llvm-bitcode", ["bc"]>, LangToSuffixes<"object-code", ["o"]>, Modified: llvm/trunk/tools/llvmc/plugins/Clang/Clang.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/plugins/Clang/Clang.td?rev=60666&r1=60665&r2=60666&view=diff ============================================================================== --- llvm/trunk/tools/llvmc/plugins/Clang/Clang.td (original) +++ llvm/trunk/tools/llvmc/plugins/Clang/Clang.td Sun Dec 7 10:46:23 2008 @@ -6,14 +6,24 @@ include "llvm/CompilerDriver/Common.td" +def Priority : PluginPriority<1>; + def Options : OptionList<[ -(extern_switch "E", - (help "Stop after the preprocessing stage, do not run the compiler")), -(extern_list "L", (help "Specify a library search path")), +(extern_switch "E"), +(extern_switch "c"), +(extern_switch "fsyntax-only"), +(extern_switch "emit-llvm"), +(extern_switch "pthread"), +(extern_list "I"), +(extern_list "include"), +(extern_list "L"), +(extern_list "l"), +(extern_list "Wa,"), +(extern_list "Wl,"), (switch_option "clang", (help "Use Clang instead of llvm-gcc")) ]>; -class clang_based : Tool< +class clang_based : Tool< [(in_language language), (out_language "llvm-bitcode"), (output_suffix "bc"), @@ -24,38 +34,58 @@ !strconcat(cmd, " -E $INFILE -o $OUTFILE"), (default), !strconcat(cmd, " -E $INFILE")), + (switch_on "c"), + !strconcat(cmd, " -fsyntax-only $INFILE"), (default), !strconcat(cmd, " -emit-llvm-bc $INFILE -o $OUTFILE"))), (actions (case (switch_on "E"), - [(stop_compilation), (output_suffix "i")])), + [(stop_compilation), (output_suffix ext_E)], + (switch_on "c"), (stop_compilation), + (switch_on "fsyntax-only"), (stop_compilation), + (switch_on "emit-llvm"), (stop_compilation), + (not_empty "include"), (forward "include"), + (not_empty "I"), (forward "I"))), (sink) ]>; -def clang_c : clang_based<"c", "clang -x c">; -def clang_cpp : clang_based<"c++", "clang -x c++">; -def clang_objective_c : clang_based<"objective-c", "clang -x objective-c">; +def clang_c : clang_based<"c", "clang -x c", "i">; +def clang_cpp : clang_based<"c++", "clang -x c++", "i">; +def clang_objective_c : clang_based<"objective-c", + "clang -x objective-c", "mi">; def clang_objective_cpp : clang_based<"objective-c++", - "clang -x objective-c++">; + "clang -x objective-c++", "mi">; + +def as : Tool< +[(in_language "assembler"), + (out_language "object-code"), + (output_suffix "o"), + (cmd_line "as $INFILE -o $OUTFILE"), + (actions (case (not_empty "Wa,"), (unpack_values "Wa,"))) +]>; // Default linker def llvm_ld : Tool< -[(in_language "llvm-bitcode"), +[(in_language "object-code"), (out_language "executable"), (output_suffix "out"), (cmd_line "llvm-ld -native -disable-internalize $INFILE -o $OUTFILE"), - (actions (case (not_empty "L"), (forward "L"))), + (actions (case + (switch_on "pthread"), (append_cmd "-lpthread"), + (not_empty "L"), (forward "L"), + (not_empty "l"), (forward "l"), + (not_empty "Wl,"), (unpack_values "Wl,"))), (join) ]>; // Language map -def LanguageMap : LanguageMap< - [LangToSuffixes<"c++", ["cc", "cp", "cxx", "cpp", "CPP", "c++", "C"]>, - LangToSuffixes<"c", ["c"]>, - LangToSuffixes<"objective-c", ["m"]>, - LangToSuffixes<"c-cpp-output", ["i"]>, - LangToSuffixes<"objective-c-cpp-output", ["mi"]> - ]>; +def LanguageMap : LanguageMap<[ + LangToSuffixes<"c++", ["cc", "cp", "cxx", "cpp", "CPP", "c++", "C"]>, + LangToSuffixes<"c", ["c"]>, + LangToSuffixes<"objective-c", ["m"]>, + LangToSuffixes<"c-cpp-output", ["i"]>, + LangToSuffixes<"objective-c-cpp-output", ["mi"]> +]>; // Compilation graph @@ -66,7 +96,12 @@ (case (switch_on "clang"), (inc_weight))>, OptionalEdge<"root", "clang_objective_c", (case (switch_on "clang"), (inc_weight))>, - Edge<"clang_c", "llvm_ld">, - Edge<"clang_cpp", "llvm_ld">, - Edge<"clang_objective_c", "llvm_ld"> - ]>; + OptionalEdge<"root", "clang_objective_cpp", + (case (switch_on "clang"), (inc_weight))>, + Edge<"clang_c", "llc">, + Edge<"clang_cpp", "llc">, + Edge<"clang_objective_c", "llc">, + Edge<"clang_objective_cpp", "llc">, + OptionalEdge<"llc", "as", (case (switch_on "clang"), (inc_weight))>, + Edge<"as", "llvm_ld"> +]>; From foldr at codedgers.com Sun Dec 7 10:47:12 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Sun, 07 Dec 2008 16:47:12 -0000 Subject: [llvm-commits] [llvm] r60667 - in /llvm/trunk: include/llvm/CompilerDriver/Common.td test/LLVMC/ExternOptions.td tools/llvmc/plugins/Clang/Clang.td utils/TableGen/LLVMCConfigurationEmitter.cpp Message-ID: <200812071647.mB7GlDAL002636@zion.cs.uiuc.edu> Author: foldr Date: Sun Dec 7 10:47:12 2008 New Revision: 60667 URL: http://llvm.org/viewvc/llvm-project?rev=60667&view=rev Log: Make 'extern' an option property. Makes (forward) work better. Modified: llvm/trunk/include/llvm/CompilerDriver/Common.td llvm/trunk/test/LLVMC/ExternOptions.td llvm/trunk/tools/llvmc/plugins/Clang/Clang.td llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Modified: llvm/trunk/include/llvm/CompilerDriver/Common.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CompilerDriver/Common.td?rev=60667&r1=60666&r2=60667&view=diff ============================================================================== --- llvm/trunk/include/llvm/CompilerDriver/Common.td (original) +++ llvm/trunk/include/llvm/CompilerDriver/Common.td Sun Dec 7 10:47:12 2008 @@ -34,16 +34,13 @@ def prefix_option; def prefix_list_option; -def extern_switch; -def extern_parameter; -def extern_list; - // Possible option properties. def help; def hidden; def really_hidden; def required; +def extern; // Empty DAG marker. def empty; Modified: llvm/trunk/test/LLVMC/ExternOptions.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/ExternOptions.td?rev=60667&r1=60666&r2=60667&view=diff ============================================================================== --- llvm/trunk/test/LLVMC/ExternOptions.td (original) +++ llvm/trunk/test/LLVMC/ExternOptions.td Sun Dec 7 10:47:12 2008 @@ -1,11 +1,12 @@ // Check that extern options work. // The dummy tool and graph are required to silence warnings. -// RUN: tblgen -I $srcroot/include --gen-llvmc %s | grep extern +// RUN: tblgen -I $srcroot/include --gen-llvmc %s | grep {extern .* AutoGeneratedSwitch_Wall} include "llvm/CompilerDriver/Common.td" -def OptList : OptionList<[(extern_switch "Wall"), - (extern_parameter "std"), (extern_list "L")]>; +def OptList : OptionList<[(switch_option "Wall", (extern)), + (parameter_option "std", (extern)), + (prefix_list_option "L", (extern))]>; def dummy_tool : Tool<[ (cmd_line "dummy_cmd"), Modified: llvm/trunk/tools/llvmc/plugins/Clang/Clang.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/plugins/Clang/Clang.td?rev=60667&r1=60666&r2=60667&view=diff ============================================================================== --- llvm/trunk/tools/llvmc/plugins/Clang/Clang.td (original) +++ llvm/trunk/tools/llvmc/plugins/Clang/Clang.td Sun Dec 7 10:47:12 2008 @@ -9,17 +9,17 @@ def Priority : PluginPriority<1>; def Options : OptionList<[ -(extern_switch "E"), -(extern_switch "c"), -(extern_switch "fsyntax-only"), -(extern_switch "emit-llvm"), -(extern_switch "pthread"), -(extern_list "I"), -(extern_list "include"), -(extern_list "L"), -(extern_list "l"), -(extern_list "Wa,"), -(extern_list "Wl,"), +(switch_option "E", (extern)), +(switch_option "c", (extern)), +(switch_option "fsyntax-only", (extern)), +(switch_option "emit-llvm", (extern)), +(switch_option "pthread", (extern)), +(parameter_list_option "I", (extern)), +(parameter_list_option "include", (extern)), +(parameter_list_option "L", (extern)), +(parameter_list_option "l", (extern)), +(prefix_list_option "Wa,", (extern)), +(prefix_list_option "Wl,", (extern)), (switch_option "clang", (help "Use Clang instead of llvm-gcc")) ]>; Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=60667&r1=60666&r2=60667&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Sun Dec 7 10:47:12 2008 @@ -85,7 +85,7 @@ // checkNumberOfArguments - Ensure that the number of args in d is // less than or equal to min_arguments, otherwise throw an exception. void checkNumberOfArguments (const DagInit* d, unsigned min_arguments) { - if (d->getNumArgs() < min_arguments) + if (!d || d->getNumArgs() < min_arguments) throw "Property " + d->getOperator()->getAsString() + " has too few arguments!"; } @@ -127,19 +127,18 @@ /// Extern* options are those that are defined in some other plugin. namespace OptionType { enum OptionType { Alias, Switch, Parameter, ParameterList, - Prefix, PrefixList, - ExternSwitch, ExternParameter, ExternList }; + Prefix, PrefixList}; bool IsList (OptionType t) { - return (t == ParameterList || t == PrefixList || t == ExternList); + return (t == ParameterList || t == PrefixList); } bool IsSwitch (OptionType t) { - return (t == Switch || t == ExternSwitch); + return (t == Switch); } bool IsParameter (OptionType t) { - return (t == Parameter || t == Prefix || t == ExternParameter); + return (t == Parameter || t == Prefix); } } @@ -157,19 +156,13 @@ return OptionType::Prefix; else if (T == "prefix_list_option") return OptionType::PrefixList; - else if (T == "extern_switch") - return OptionType::ExternSwitch; - else if (T == "extern_parameter") - return OptionType::ExternParameter; - else if (T == "extern_list") - return OptionType::ExternList; else throw "Unknown option type: " + T + '!'; } namespace OptionDescriptionFlags { enum OptionDescriptionFlags { Required = 0x1, Hidden = 0x2, - ReallyHidden = 0x4 }; + ReallyHidden = 0x4, Extern = 0x8 }; } /// OptionDescription - Represents data contained in a single @@ -200,7 +193,9 @@ // Misc convenient getters/setters. bool isAlias() const; + bool isExtern() const; + void setExtern(); bool isRequired() const; void setRequired(); @@ -232,8 +227,10 @@ } bool OptionDescription::isExtern() const { - return (Type == OptionType::ExternList || Type == OptionType::ExternParameter - || Type == OptionType::ExternSwitch); + return Flags & OptionDescriptionFlags::Extern; +} +void OptionDescription::setExtern() { + Flags |= OptionDescriptionFlags::Extern; } bool OptionDescription::isRequired() const { @@ -261,14 +258,11 @@ switch (Type) { case OptionType::Alias: return "cl::alias"; - case OptionType::ExternList: case OptionType::PrefixList: case OptionType::ParameterList: return "cl::list"; case OptionType::Switch: - case OptionType::ExternSwitch: return "cl::opt"; - case OptionType::ExternParameter: case OptionType::Parameter: case OptionType::Prefix: default: @@ -283,12 +277,9 @@ return "AutoGeneratedAlias_" + EscapedName; case OptionType::PrefixList: case OptionType::ParameterList: - case OptionType::ExternList: return "AutoGeneratedList_" + EscapedName; - case OptionType::ExternSwitch: case OptionType::Switch: return "AutoGeneratedSwitch_" + EscapedName; - case OptionType::ExternParameter: case OptionType::Prefix: case OptionType::Parameter: default: @@ -402,6 +393,7 @@ : HandlerTable(this), optDesc_(OD) { if (!staticMembersInitialized_) { + AddHandler("extern", &CollectOptionProperties::onExtern); AddHandler("help", &CollectOptionProperties::onHelp); AddHandler("hidden", &CollectOptionProperties::onHidden); AddHandler("really_hidden", &CollectOptionProperties::onReallyHidden); @@ -416,39 +408,31 @@ /// Option property handlers -- /// Methods that handle option properties such as (help) or (hidden). + void onExtern (const DagInit* d) { + checkNumberOfArguments(d, 0); + optDesc_.setExtern(); + } + void onHelp (const DagInit* d) { checkNumberOfArguments(d, 1); - const std::string& help_message = InitPtrToString(d->getArg(0)); - optDesc_.Help = help_message; + optDesc_.Help = InitPtrToString(d->getArg(0)); } void onHidden (const DagInit* d) { checkNumberOfArguments(d, 0); - checkToolProps(d); optDesc_.setHidden(); } void onReallyHidden (const DagInit* d) { checkNumberOfArguments(d, 0); - checkToolProps(d); optDesc_.setReallyHidden(); } void onRequired (const DagInit* d) { checkNumberOfArguments(d, 0); - checkToolProps(d); optDesc_.setRequired(); } - // Helper functions - - /// checkToolProps - Throw an error if toolProps_ == 0. - void checkToolProps(const DagInit* d) { - if (!d) - throw "Option property " + d->getOperator()->getAsString() - + " can't be used in this context"; - } - }; /// AddOption - A function object that is applied to every option @@ -1163,11 +1147,9 @@ switch (D.Type) { case OptionType::Switch: - case OptionType::ExternSwitch: O << Indent << "vec.push_back(\"" << Name << "\");\n"; break; case OptionType::Parameter: - case OptionType::ExternParameter: O << Indent << "vec.push_back(\"" << Name << "\");\n"; O << Indent << "vec.push_back(" << D.GenVariableName() << ");\n"; break; @@ -1183,7 +1165,6 @@ << "*B);\n"; break; case OptionType::ParameterList: - case OptionType::ExternList: O << Indent << "for (" << D.GenTypeDeclaration() << "::iterator B = " << D.GenVariableName() << ".begin(),\n" << Indent << "E = " << D.GenVariableName() From foldr at codedgers.com Sun Dec 7 10:47:42 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Sun, 07 Dec 2008 16:47:42 -0000 Subject: [llvm-commits] [llvm] r60668 - /llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst Message-ID: <200812071647.mB7Glgi5002702@zion.cs.uiuc.edu> Author: foldr Date: Sun Dec 7 10:47:42 2008 New Revision: 60668 URL: http://llvm.org/viewvc/llvm-project?rev=60668&view=rev Log: Describe recent changes in the documentation. Modified: llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst Modified: llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst?rev=60668&r1=60667&r2=60668&view=diff ============================================================================== --- llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst (original) +++ llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst Sun Dec 7 10:47:42 2008 @@ -58,6 +58,10 @@ $ ./a.out hello +By default, LLVMC uses ``llvm-gcc`` to compile the source code. It is +also possible to choose the work-in-progress ``clang`` compiler with +the ``-clang`` option. + Predefined options ================== @@ -146,23 +150,6 @@ $ cd $LLVMC_DIR $ make BUILTIN_PLUGINS="" -How plugins are loaded -====================== - -It is possible for LLVMC plugins to depend on each other. For example, -one can create edges between nodes defined in some other plugin. To -make this work, however, that plugin should be loaded first. To -achieve this, the concept of plugin priority was introduced. By -default, every plugin has priority zero; to specify the priority -explicitly, put the following line in your plugin's TableGen file:: - - def Priority : PluginPriority<$PRIORITY_VALUE>; - # Where PRIORITY_VALUE is some integer > 0 - -Plugins are loaded in order of their (increasing) priority, starting -with 0. Therefore, the plugin with the highest priority value will be -loaded last. - Customizing LLVMC: the compilation graph ======================================== @@ -241,71 +228,23 @@ debugging), run ``llvmc --view-graph``. You will need ``dot`` and ``gsview`` installed for this to work properly. +Describing options +================== -Writing a tool description -========================== - -As was said earlier, nodes in the compilation graph represent tools, -which are described separately. A tool definition looks like this -(taken from the ``include/llvm/CompilerDriver/Tools.td`` file):: - - def llvm_gcc_cpp : Tool<[ - (in_language "c++"), - (out_language "llvm-assembler"), - (output_suffix "bc"), - (cmd_line "llvm-g++ -c $INFILE -o $OUTFILE -emit-llvm"), - (sink) - ]>; - -This defines a new tool called ``llvm_gcc_cpp``, which is an alias for -``llvm-g++``. As you can see, a tool definition is just a list of -properties; most of them should be self-explanatory. The ``sink`` -property means that this tool should be passed all command-line -options that lack explicit descriptions. - -The complete list of the currently implemented tool properties follows: - -* Possible tool properties: - - - ``in_language`` - input language name. Can be either a string or a - list, in case the tool supports multiple input languages. - - - ``out_language`` - output language name. - - - ``output_suffix`` - output file suffix. - - - ``cmd_line`` - the actual command used to run the tool. You can - use ``$INFILE`` and ``$OUTFILE`` variables, output redirection - with ``>``, hook invocations (``$CALL``), environment variables - (via ``$ENV``) and the ``case`` construct (more on this below). - - - ``join`` - this tool is a "join node" in the graph, i.e. it gets a - list of input files and joins them together. Used for linkers. - - - ``sink`` - all command-line options that are not handled by other - tools are passed to this tool. - -The next tool definition is slightly more complex:: +Command-line options that the plugin supports are defined by using an +``OptionList``:: - def llvm_gcc_linker : Tool<[ - (in_language "object-code"), - (out_language "executable"), - (output_suffix "out"), - (cmd_line "llvm-gcc $INFILE -o $OUTFILE"), - (join), - (prefix_list_option "L", (forward), - (help "add a directory to link path")), - (prefix_list_option "l", (forward), - (help "search a library when linking")), - (prefix_list_option "Wl", (unpack_values), - (help "pass options to linker")) - ]>; + def Options : OptionList<[ + (switch_option "E", (help "Help string")), + (alias_option "quiet", "q") + ... + ]>; -This tool has a "join" property, which means that it behaves like a -linker. This tool also defines several command-line options: ``-l``, -``-L`` and ``-Wl`` which have their usual meaning. An option has two -attributes: a name and a (possibly empty) list of properties. All -currently implemented option types and properties are described below: +As you can see, the option list is just a list of DAGs, where each DAG +is an option description consisting of the option name and some +properties. A plugin can define more than one option list (they are +all merged together in the end), which can be handy if one wants to +separate option groups syntactically. * Possible option types: @@ -331,23 +270,6 @@ * Possible option properties: - - ``append_cmd`` - append a string to the tool invocation command. - - - ``forward`` - forward this option unchanged. - - - ``forward_as`` - Change the name of this option, but forward the - argument unchanged. Example: ``(forward_as "--disable-optimize")``. - - - ``output_suffix`` - modify the output suffix of this - tool. Example: ``(switch "E", (output_suffix "i")``. - - - ``stop_compilation`` - stop compilation after this phase. - - - ``unpack_values`` - used for for splitting and forwarding - comma-separated lists of options, e.g. ``-Wa,-foo=bar,-baz`` is - converted to ``-foo=bar -baz`` and appended to the tool invocation - command. - - ``help`` - help string associated with this option. Used for ``--help`` output. @@ -359,80 +281,55 @@ - ``really_hidden`` - the option should not appear in any help output. + - ``extern`` - this option is defined in some other plugin, see below. -Option list - specifying all options in a single place -====================================================== +External options +---------------- -It can be handy to have all information about options gathered in a -single place to provide an overview. This can be achieved by using a -so-called ``OptionList``:: +Sometimes, when linking several plugins together, one plugin needs to +access options defined in some other plugin. Because of the way +options are implemented, such options should be marked as +``extern``. This is what the ``extern`` option property is +for. Example:: - def Options : OptionList<[ - (switch_option "E", (help "Help string")), - (alias_option "quiet", "q") - ... - ]>; - -``OptionList`` is also a good place to specify option aliases. + ... + (switch_option "E", (extern)) + ... -Tool-specific option properties like ``append_cmd`` have (obviously) -no meaning in the context of ``OptionList``, so the only properties -allowed there are ``help`` and ``required``. +See also the section on plugin `priorities`__. -Option lists are used at file scope. See the file -``plugins/Clang/Clang.td`` for an example of ``OptionList`` usage. +__ priorities_ -.. _hooks: +.. _case: -Using hooks and environment variables in the ``cmd_line`` property -================================================================== - -Normally, LLVMC executes programs from the system ``PATH``. Sometimes, -this is not sufficient: for example, we may want to specify tool names -in the configuration file. This can be achieved via the mechanism of -hooks - to write your own hooks, just add their definitions to the -``PluginMain.cpp`` or drop a ``.cpp`` file into the -``$LLVMC_DIR/driver`` directory. Hooks should live in the ``hooks`` -namespace and have the signature ``std::string hooks::MyHookName -(void)``. They can be used from the ``cmd_line`` tool property:: - - (cmd_line "$CALL(MyHook)/path/to/file -o $CALL(AnotherHook)") - -It is also possible to use environment variables in the same manner:: - - (cmd_line "$ENV(VAR1)/path/to/file -o $ENV(VAR2)") - -To change the command line string based on user-provided options use -the ``case`` expression (documented below):: - - (cmd_line - (case - (switch_on "E"), - "llvm-g++ -E -x c $INFILE -o $OUTFILE", - (default), - "llvm-g++ -c -x c $INFILE -o $OUTFILE -emit-llvm")) - -Conditional evaluation: the ``case`` expression -=============================================== +Conditional evaluation +====================== -The 'case' construct can be used to calculate weights of the optional -edges and to choose between several alternative command line strings -in the ``cmd_line`` tool property. It is designed after the -similarly-named construct in functional languages and takes the form -``(case (test_1), statement_1, (test_2), statement_2, ... (test_N), -statement_N)``. The statements are evaluated only if the corresponding -tests evaluate to true. +The 'case' construct is the main means by which programmability is +achieved in LLVMC. It can be used to calculate edge weights, program +actions and modify the shell commands to be executed. The 'case' +expression is designed after the similarly-named construct in +functional languages and takes the form ``(case (test_1), statement_1, +(test_2), statement_2, ... (test_N), statement_N)``. The statements +are evaluated only if the corresponding tests evaluate to true. Examples:: + // Edge weight calculation + // Increases edge weight by 5 if "-A" is provided on the // command-line, and by 5 more if "-B" is also provided. (case (switch_on "A"), (inc_weight 5), (switch_on "B"), (inc_weight 5)) - // Evaluates to "cmdline1" if option "-A" is provided on the - // command line, otherwise to "cmdline2" + + // Tool command line specification + + // Evaluates to "cmdline1" if the option "-A" is provided on the + // command line; to "cmdline2" if "-B" is provided; + // otherwise to "cmdline3". + (case (switch_on "A"), "cmdline1", (switch_on "B"), "cmdline2", @@ -456,29 +353,29 @@ * Possible tests are: - ``switch_on`` - Returns true if a given command-line switch is - provided by the user. Example: ``(switch_on "opt")``. Note that - you have to define all possible command-line options separately in - the tool descriptions. See the next section for the discussion of - different kinds of command-line options. + provided by the user. Example: ``(switch_on "opt")``. - ``parameter_equals`` - Returns true if a command-line parameter equals - a given value. Example: ``(parameter_equals "W", "all")``. + a given value. + Example: ``(parameter_equals "W", "all")``. - - ``element_in_list`` - Returns true if a command-line parameter list - includes a given value. Example: ``(parameter_in_list "l", "pthread")``. + - ``element_in_list`` - Returns true if a command-line parameter + list contains a given value. + Example: ``(parameter_in_list "l", "pthread")``. - ``input_languages_contain`` - Returns true if a given language - belongs to the current input language set. Example: - ``(input_languages_contain "c++")``. + belongs to the current input language set. + Example: ``(input_languages_contain "c++")``. - - ``in_language`` - Evaluates to true if the language of the input - file equals to the argument. At the moment works only with - ``cmd_line`` property on non-join nodes. Example: ``(in_language - "c++")``. + - ``in_language`` - Evaluates to true if the input file language + equals to the argument. At the moment works only with ``cmd_line`` + and ``actions`` (on non-join nodes). + Example: ``(in_language "c++")``. - ``not_empty`` - Returns true if a given option (which should be either a parameter or a parameter list) is set by the - user. Example: ``(not_empty "o")``. + user. + Example: ``(not_empty "o")``. - ``default`` - Always evaluates to true. Should always be the last test in the ``case`` expression. @@ -493,14 +390,122 @@ (test2), ... (testN))``. +Writing a tool description +========================== + +As was said earlier, nodes in the compilation graph represent tools, +which are described separately. A tool definition looks like this +(taken from the ``include/llvm/CompilerDriver/Tools.td`` file):: + + def llvm_gcc_cpp : Tool<[ + (in_language "c++"), + (out_language "llvm-assembler"), + (output_suffix "bc"), + (cmd_line "llvm-g++ -c $INFILE -o $OUTFILE -emit-llvm"), + (sink) + ]>; + +This defines a new tool called ``llvm_gcc_cpp``, which is an alias for +``llvm-g++``. As you can see, a tool definition is just a list of +properties; most of them should be self-explanatory. The ``sink`` +property means that this tool should be passed all command-line +options that aren't mentioned in the option list. + +The complete list of all currently implemented tool properties follows. + +* Possible tool properties: + + - ``in_language`` - input language name. Can be either a string or a + list, in case the tool supports multiple input languages. + + - ``out_language`` - output language name. Tools are not allowed to + have multiple output languages. + + - ``output_suffix`` - output file suffix. Can also be changed + dynamically, see documentation on actions. + + - ``cmd_line`` - the actual command used to run the tool. You can + use ``$INFILE`` and ``$OUTFILE`` variables, output redirection + with ``>``, hook invocations (``$CALL``), environment variables + (via ``$ENV``) and the ``case`` construct. + + - ``join`` - this tool is a "join node" in the graph, i.e. it gets a + list of input files and joins them together. Used for linkers. + + - ``sink`` - all command-line options that are not handled by other + tools are passed to this tool. + + - ``actions`` - A single big ``case`` expression that specifies how + this tool reacts on command-line options (described in more detail + below). + +Actions +------- + +A tool often needs to react to command-line options, and this is +precisely what the ``actions`` property is for. The next example +illustrates this feature:: + + def llvm_gcc_linker : Tool<[ + (in_language "object-code"), + (out_language "executable"), + (output_suffix "out"), + (cmd_line "llvm-gcc $INFILE -o $OUTFILE"), + (join), + (actions (case (not_empty "L"), (forward "L"), + (not_empty "l"), (forward "l"), + (not_empty "dummy"), + [(append_cmd "-dummy1"), (append_cmd "-dummy2")]) + ]>; + +The ``actions`` tool property is implemented on top of the omnipresent +``case`` expression. It associates one or more different *actions* +with given conditions - in the example, the actions are ``forward``, +which forwards a given option unchanged, and ``append_cmd``, which +appends a given string to the tool execution command. Multiple actions +can be associated with a single condition by using a list of actions +(used in the example to append some dummy options). The same ``case`` +construct can also be used in the ``cmd_line`` property to modify the +tool command line. + +The "join" property used in the example means that this tool behaves +like a linker. + +The list of all possible actions follows. + +* Possible actions: + + - ``append_cmd`` - append a string to the tool invocation + command. + Example: ``(case (switch_on "pthread"), (append_cmd "-lpthread"))`` + + - ``forward`` - forward an option unchanged. + Example: ``(forward "Wall")``. + + - ``forward_as`` - Change the name of an option, but forward the + argument unchanged. + Example: ``(forward_as "O0" "--disable-optimization")``. + + - ``output_suffix`` - modify the output suffix of this + tool. + Example: ``(output_suffix "i")``. + + - ``stop_compilation`` - stop compilation after this tool processes + its input. Used without arguments. + + - ``unpack_values`` - used for for splitting and forwarding + comma-separated lists of options, e.g. ``-Wa,-foo=bar,-baz`` is + converted to ``-foo=bar -baz`` and appended to the tool invocation + command. + Example: ``(unpack_values "Wa,")``. + Language map ============ -One last thing that you will need to modify when adding support for a -new language to LLVMC is the language map, which defines mappings from -file extensions to language names. It is used to choose the proper -toolchain(s) for a given input file set. Language map definition looks -like this:: +If you are adding support for a new language to LLVMC, you'll need to +modify the language map, which defines mappings from file extensions +to language names. It is used to choose the proper toolchain(s) for a +given input file set. Language map definition looks like this:: def LanguageMap : LanguageMap< [LangToSuffixes<"c++", ["cc", "cp", "cxx", "cpp", "CPP", "c++", "C"]>, @@ -508,8 +513,73 @@ ... ]>; +For example, without those definitions the following command wouldn't work:: + + $ llvmc hello.cpp + llvmc: Unknown suffix: cpp + +The language map entries should be added only for tools that are +linked with the root node. Since tools are not allowed to have +multiple output languages, for nodes "inside" the graph the input and +output languages should match. This is enforced at compile-time. + + +More advanced topics +==================== + +.. _hooks: + +Hooks and environment variables +------------------------------- + +Normally, LLVMC executes programs from the system ``PATH``. Sometimes, +this is not sufficient: for example, we may want to specify tool names +in the configuration file. This can be achieved via the mechanism of +hooks - to write your own hooks, just add their definitions to the +``PluginMain.cpp`` or drop a ``.cpp`` file into the +``$LLVMC_DIR/driver`` directory. Hooks should live in the ``hooks`` +namespace and have the signature ``std::string hooks::MyHookName +(void)``. They can be used from the ``cmd_line`` tool property:: + + (cmd_line "$CALL(MyHook)/path/to/file -o $CALL(AnotherHook)") + +It is also possible to use environment variables in the same manner:: + + (cmd_line "$ENV(VAR1)/path/to/file -o $ENV(VAR2)") + +To change the command line string based on user-provided options use +the ``case`` expression (documented `above`__):: + + (cmd_line + (case + (switch_on "E"), + "llvm-g++ -E -x c $INFILE -o $OUTFILE", + (default), + "llvm-g++ -c -x c $INFILE -o $OUTFILE -emit-llvm")) + +__ case_ + +.. _priorities: + +How plugins are loaded +---------------------- + +It is possible for LLVMC plugins to depend on each other. For example, +one can create edges between nodes defined in some other plugin. To +make this work, however, that plugin should be loaded first. To +achieve this, the concept of plugin priority was introduced. By +default, every plugin has priority zero; to specify the priority +explicitly, put the following line in your plugin's TableGen file:: + + def Priority : PluginPriority<$PRIORITY_VALUE>; + # Where PRIORITY_VALUE is some integer > 0 + +Plugins are loaded in order of their (increasing) priority, starting +with 0. Therefore, the plugin with the highest priority value will be +loaded last. + Debugging -========= +--------- When writing LLVMC plugins, it can be useful to get a visual view of the resulting compilation graph. This can be achieved via the command From foldr at codedgers.com Sun Dec 7 10:48:07 2008 From: foldr at codedgers.com (Mikhail Glushenkov) Date: Sun, 07 Dec 2008 16:48:07 -0000 Subject: [llvm-commits] [llvm] r60669 - /llvm/trunk/docs/CommandGuide/llvmc.pod Message-ID: <200812071648.mB7Gm7rJ002748@zion.cs.uiuc.edu> Author: foldr Date: Sun Dec 7 10:48:07 2008 New Revision: 60669 URL: http://llvm.org/viewvc/llvm-project?rev=60669&view=rev Log: Man page update. Modified: llvm/trunk/docs/CommandGuide/llvmc.pod Modified: llvm/trunk/docs/CommandGuide/llvmc.pod URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CommandGuide/llvmc.pod?rev=60669&r1=60668&r2=60669&view=diff ============================================================================== --- llvm/trunk/docs/CommandGuide/llvmc.pod (original) +++ llvm/trunk/docs/CommandGuide/llvmc.pod Sun Dec 7 10:48:07 2008 @@ -81,6 +81,10 @@ =over +=item B<-clang> + +Use Clang instead of llvm-gcc. + =item B<-I> I Add a directory to the header file search path. This option can be @@ -102,6 +106,14 @@ of native object (or assembly). If B<-emit-llvm> is given without either B<-c> or B<-S> it has no effect. +=item B<-Wa> + +Pass options to assembler. + +=item B<-Wl> + +Pass options to linker. + =back =head1 EXIT STATUS From ofv at wanadoo.es Sun Dec 7 11:01:16 2008 From: ofv at wanadoo.es (Oscar Fuentes) Date: Sun, 07 Dec 2008 17:01:16 -0000 Subject: [llvm-commits] [llvm] r60670 - /llvm/trunk/tools/llvmc/driver/CMakeLists.txt Message-ID: <200812071701.mB7H1GS9003360@zion.cs.uiuc.edu> Author: ofv Date: Sun Dec 7 11:01:16 2008 New Revision: 60670 URL: http://llvm.org/viewvc/llvm-project?rev=60670&view=rev Log: CMake: Added Tool.cpp to tools/llvmc/driver. Modified: llvm/trunk/tools/llvmc/driver/CMakeLists.txt Modified: llvm/trunk/tools/llvmc/driver/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/driver/CMakeLists.txt?rev=60670&r1=60669&r2=60670&view=diff ============================================================================== --- llvm/trunk/tools/llvmc/driver/CMakeLists.txt (original) +++ llvm/trunk/tools/llvmc/driver/CMakeLists.txt Sun Dec 7 11:01:16 2008 @@ -6,4 +6,5 @@ CompilationGraph.cpp llvmc.cpp Plugin.cpp + Tool.cpp ) From gohman at apple.com Sun Dec 7 11:29:55 2008 From: gohman at apple.com (Dan Gohman) Date: Sun, 7 Dec 2008 09:29:55 -0800 Subject: [llvm-commits] two-byte return optimization for AMD In-Reply-To: <493B8729.6000300@mxc.ca> References: <493B8729.6000300@mxc.ca> Message-ID: <14A00655-9DF3-4D8D-8AEC-EAC253075AB8@apple.com> Hi NIck, The AMD family 10h aka Barcelona optimization guide recommends using "ret 0" for this purpose, which is a three-byte ret. The guide for earlier AMD processors does recommend "rep ret" though. I don't know how much difference this makes. addAssemblyEmitter isn't an ideal place to add the pass because it's not used on the JIT path. I think it would be appropriate to add a new TargetMachine hook here. > + MachineInstr &MI = MBB.front(); > + if (MI.getOpcode() == X86::RET) { It might be useful to skip past any labels or IMPLICIT_DEF at the beginning of the block, since those don't produce any actual instructions. > + BuildMI(MBB, MBB.begin(), TII->get(X86::REP_RET)); > + MI.eraseFromParent(); You can use MI.setDesc(TII->get(X86::REP_RET)) to change the instruction in-place. Dan On Dec 7, 2008, at 12:19 AM, Nick Lewycky wrote: > The AMD optimization manual suggests avoiding branches to 'ret' > instructions, preferring to emit 'rep; ret'. The attached patch > implements this. > > This doesn't apply very often across llvm-test. The largest is > kimwitu++ which produces 28 of these two-byte rets. The performance > impact seems to be less than noise, at least on my system. > > Please review! > > Nick > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Sun Dec 7 12:21:39 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 07 Dec 2008 18:21:39 -0000 Subject: [llvm-commits] [llvm] r60671 - /llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Message-ID: <200812071821.mB7ILdhk005559@zion.cs.uiuc.edu> Author: lattner Date: Sun Dec 7 12:21:37 2008 New Revision: 60671 URL: http://llvm.org/viewvc/llvm-project?rev=60671&view=rev Log: fix a typo duncan noticed! Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60671&r1=60670&r2=60671&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Sun Dec 7 12:21:37 2008 @@ -156,7 +156,7 @@ typedef PointerIntPair ValueIsLoadPair; /// CachedNonLocalPointerInfo - This map stores the cached results of doing - /// a pointer lookup at the bottom of a block. Key key of this map is the + /// a pointer lookup at the bottom of a block. The key of this map is the /// pointer+isload bit, the value is a list of result> mappings. typedef DenseMapCachedNonLocalPointerInfo; CachedNonLocalPointerInfo NonLocalPointerDeps; From nicholas at mxc.ca Sun Dec 7 12:28:34 2008 From: nicholas at mxc.ca (Nick Lewycky) Date: Sun, 07 Dec 2008 10:28:34 -0800 Subject: [llvm-commits] two-byte return optimization for AMD In-Reply-To: <14A00655-9DF3-4D8D-8AEC-EAC253075AB8@apple.com> References: <493B8729.6000300@mxc.ca> <14A00655-9DF3-4D8D-8AEC-EAC253075AB8@apple.com> Message-ID: <493C15D2.2060909@mxc.ca> Dan Gohman wrote: > Hi NIck, > > The AMD family 10h aka Barcelona optimization guide recommends using > "ret 0" for this purpose, which is a three-byte ret. The guide for > earlier AMD > processors does recommend "rep ret" though. I don't know how much > difference this makes. The Intel manual states that rep is only defined for the string instructions, making "rep ret" an illegal instruction. It still works on every X86 CPU and is one byte cheaper than a three byte ret. Regardless, this should only be used on AuthenticAMD CPUs. > addAssemblyEmitter isn't an ideal place to add the pass because it's not > used on the JIT path. I think it would be appropriate to add a new > TargetMachine hook here. Thanks. I moved it to addPreEmitPass, as you suggested on IRC. > > + MachineInstr &MI = MBB.front(); > > + if (MI.getOpcode() == X86::RET) { > > It might be useful to skip past any labels or IMPLICIT_DEF at the > beginning > of the block, since those don't produce any actual instructions. Good catch! That improved the number of two-byte rets. Is there a better way to look for labels than testing the opcode against DBG_LABEL, EH_LABEL and GC_LABEL? I don't see any 'isLabel()' method on TII for example. > > + BuildMI(MBB, MBB.begin(), TII->get(X86::REP_RET)); > > + MI.eraseFromParent(); > > You can use MI.setDesc(TII->get(X86::REP_RET)) to change the > instruction in-place. That's much better. Thanks for the review! Nick > Dan > > On Dec 7, 2008, at 12:19 AM, Nick Lewycky wrote: > >> The AMD optimization manual suggests avoiding branches to 'ret' >> instructions, preferring to emit 'rep; ret'. The attached patch >> implements this. >> >> This doesn't apply very often across llvm-test. The largest is >> kimwitu++ which produces 28 of these two-byte rets. The performance >> impact seems to be less than noise, at least on my system. >> >> Please review! >> >> Nick >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > -------------- next part -------------- A non-text attachment was scrubbed... Name: x86-twobyteret.patch Type: text/x-diff Size: 9985 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081207/a8736f59/attachment.bin From sabre at nondot.org Sun Dec 7 12:39:13 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 07 Dec 2008 18:39:13 -0000 Subject: [llvm-commits] [llvm] r60672 - /llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200812071839.mB7IdD1Z006030@zion.cs.uiuc.edu> Author: lattner Date: Sun Dec 7 12:39:13 2008 New Revision: 60672 URL: http://llvm.org/viewvc/llvm-project?rev=60672&view=rev Log: factor some code, fixing some fixme's. Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60672&r1=60671&r2=60672&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sun Dec 7 12:39:13 2008 @@ -57,6 +57,21 @@ return false; } +/// RemoveFromReverseMap - This is a helper function that removes Val from +/// 'Inst's set in ReverseMap. If the set becomes empty, remove Inst's entry. +template +static void RemoveFromReverseMap(DenseMap > &ReverseMap, + Instruction *Inst, KeyTy *Val) { + typename DenseMap >::iterator + InstIt = ReverseMap.find(Inst); + assert(InstIt != ReverseMap.end() && "Reverse map out of sync?"); + bool Found = InstIt->second.erase(Val); + assert(Found && "Invalid reverse map!"); Found=Found; + if (InstIt->second.empty()) + ReverseMap.erase(InstIt); +} + /// getCallSiteDependencyFrom - Private helper for finding the local /// dependencies of a call site. @@ -207,12 +222,7 @@ if (Instruction *Inst = LocalCache.getInst()) { ScanPos = Inst; - SmallPtrSet &InstMap = ReverseLocalDeps[Inst]; - bool Found = InstMap.erase(QueryInst); - assert(Found && "Invalid reverse map!"); Found=Found; - if (InstMap.empty()) - // FIXME: use an iterator to avoid looking up inst again. - ReverseLocalDeps.erase(Inst); + RemoveFromReverseMap(ReverseLocalDeps, Inst, QueryInst); } BasicBlock *QueryParent = QueryInst->getParent(); @@ -363,13 +373,8 @@ if (ExistingResult) { if (Instruction *Inst = ExistingResult->getInst()) { ScanPos = Inst; - // We're removing QueryInst's use of Inst. - SmallPtrSet &InstMap = ReverseNonLocalDeps[Inst]; - bool Found = InstMap.erase(QueryInst); - assert(Found && "Invalid reverse map!"); Found=Found; - // FIXME: Use an iterator to avoid looking up inst again. - if (InstMap.empty()) ReverseNonLocalDeps.erase(Inst); + RemoveFromReverseMap(ReverseNonLocalDeps, Inst, QueryInst); } } @@ -527,11 +532,8 @@ ScanPos = ExistingResult->getInst(); // Eliminating the dirty entry from 'Cache', so update the reverse info. - SmallPtrSet &InstMap = ReverseNonLocalPtrDeps[ScanPos]; - bool Contained = InstMap.erase(CacheKey.getOpaqueValue()); - assert(Contained && "Invalid cache entry"); Contained=Contained; - // FIXME: Use an iterator to avoid a repeated lookup in ".erase". - if (InstMap.empty()) ReverseNonLocalPtrDeps.erase(ScanPos); + RemoveFromReverseMap(ReverseNonLocalPtrDeps, ScanPos, + CacheKey.getOpaqueValue()); } else { ++NumUncacheNonLocalPtr; } @@ -595,12 +597,7 @@ assert(Target->getParent() == PInfo[i].first && Target != P.getPointer()); // Eliminating the dirty entry from 'Cache', so update the reverse info. - SmallPtrSet &InstMap = ReverseNonLocalPtrDeps[Target]; - bool Contained = InstMap.erase(P.getOpaqueValue()); - assert(Contained && "Invalid cache entry"); Contained=Contained; - - // FIXME: Use an iterator to avoid a repeated lookup in ".erase". - if (InstMap.empty()) ReverseNonLocalPtrDeps.erase(Target); + RemoveFromReverseMap(ReverseNonLocalPtrDeps, Target, P.getOpaqueValue()); } // Remove P from NonLocalPointerDeps (which deletes NonLocalDepInfo). @@ -620,7 +617,7 @@ for (NonLocalDepInfo::iterator DI = BlockMap.begin(), DE = BlockMap.end(); DI != DE; ++DI) if (Instruction *Inst = DI->second.getInst()) - ReverseNonLocalDeps[Inst].erase(RemInst); + RemoveFromReverseMap(ReverseNonLocalDeps, Inst, RemInst); NonLocalDeps.erase(NLDI); } @@ -629,14 +626,8 @@ LocalDepMapType::iterator LocalDepEntry = LocalDeps.find(RemInst); if (LocalDepEntry != LocalDeps.end()) { // Remove us from DepInst's reverse set now that the local dep info is gone. - if (Instruction *Inst = LocalDepEntry->second.getInst()) { - SmallPtrSet &RLD = ReverseLocalDeps[Inst]; - bool Found = RLD.erase(RemInst); - assert(Found && "Invalid reverse map!"); Found=Found; - // FIXME: Use an iterator to avoid looking up Inst again. - if (RLD.empty()) - ReverseLocalDeps.erase(Inst); - } + if (Instruction *Inst = LocalDepEntry->second.getInst()) + RemoveFromReverseMap(ReverseLocalDeps, Inst, RemInst); // Remove this local dependency info. LocalDeps.erase(LocalDepEntry); From sabre at nondot.org Sun Dec 7 12:42:51 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 07 Dec 2008 18:42:51 -0000 Subject: [llvm-commits] [llvm] r60673 - /llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200812071842.mB7Igp2J006137@zion.cs.uiuc.edu> Author: lattner Date: Sun Dec 7 12:42:51 2008 New Revision: 60673 URL: http://llvm.org/viewvc/llvm-project?rev=60673&view=rev Log: factor some code better. Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60673&r1=60672&r2=60673&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sun Dec 7 12:42:51 2008 @@ -647,6 +647,16 @@ // Loop over all of the things that depend on the instruction we're removing. // SmallVector, 8> ReverseDepsToAdd; + + // If we find RemInst as a clobber or Def in any of the maps for other values, + // we need to replace its entry with a dirty version of the instruction after + // it. If RemInst is a terminator, we use a null dirty value. + // + // Using a dirty version of the instruction after RemInst saves having to scan + // the entire block to get to this point. + MemDepResult NewDirtyVal; + if (!RemInst->isTerminator()) + NewDirtyVal = MemDepResult::getDirty(++BasicBlock::iterator(RemInst)); ReverseDepMapType::iterator ReverseDepIt = ReverseLocalDeps.find(RemInst); if (ReverseDepIt != ReverseLocalDeps.end()) { @@ -655,22 +665,18 @@ assert(!ReverseDeps.empty() && !isa(RemInst) && "Nothing can locally depend on a terminator"); - // Anything that was locally dependent on RemInst is now going to be - // dependent on the instruction after RemInst. It will have the dirty flag - // set so it will rescan. This saves having to scan the entire block to get - // to this point. - Instruction *NewDepInst = ++BasicBlock::iterator(RemInst); - for (SmallPtrSet::iterator I = ReverseDeps.begin(), E = ReverseDeps.end(); I != E; ++I) { Instruction *InstDependingOnRemInst = *I; assert(InstDependingOnRemInst != RemInst && "Already removed our local dep info"); - LocalDeps[InstDependingOnRemInst] = MemDepResult::getDirty(NewDepInst); + LocalDeps[InstDependingOnRemInst] = NewDirtyVal; // Make sure to remember that new things depend on NewDepInst. - ReverseDepsToAdd.push_back(std::make_pair(NewDepInst, + assert(NewDirtyVal.getInst() && "There is no way something else can have " + "a local dep on this if it is a terminator!"); + ReverseDepsToAdd.push_back(std::make_pair(NewDirtyVal.getInst(), InstDependingOnRemInst)); } @@ -701,12 +707,10 @@ if (DI->second.getInst() != RemInst) continue; // Convert to a dirty entry for the subsequent instruction. - Instruction *NextI = 0; - if (!RemInst->isTerminator()) { - NextI = ++BasicBlock::iterator(RemInst); + DI->second = NewDirtyVal; + + if (Instruction *NextI = NewDirtyVal.getInst()) ReverseDepsToAdd.push_back(std::make_pair(NextI, *I)); - } - DI->second = MemDepResult::getDirty(NextI); } } @@ -737,10 +741,6 @@ NonLocalDepInfo &NLPDI = NonLocalPointerDeps[P]; - MemDepResult NewDirtyVal; - if (!RemInst->isTerminator()) - NewDirtyVal = MemDepResult::getDirty(++BasicBlock::iterator(RemInst)); - // Update any entries for RemInst to use the instruction after it. for (NonLocalDepInfo::iterator DI = NLPDI.begin(), DE = NLPDI.end(); DI != DE; ++DI) { From sabre at nondot.org Sun Dec 7 12:45:15 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 07 Dec 2008 18:45:15 -0000 Subject: [llvm-commits] [llvm] r60674 - /llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200812071845.mB7IjGjS006203@zion.cs.uiuc.edu> Author: lattner Date: Sun Dec 7 12:45:15 2008 New Revision: 60674 URL: http://llvm.org/viewvc/llvm-project?rev=60674&view=rev Log: add an assert. the cast<> below would catch this but a message is more useful. Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60674&r1=60673&r2=60674&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sun Dec 7 12:45:15 2008 @@ -454,6 +454,8 @@ void MemoryDependenceAnalysis:: getNonLocalPointerDependency(Value *Pointer, bool isLoad, BasicBlock *FromBB, SmallVectorImpl &Result) { + assert(isa(Pointer->getType()) && + "Can't get pointer deps of a non-pointer!"); Result.clear(); // We know that the pointer value is live into FromBB find the def/clobbers From sabre at nondot.org Sun Dec 7 12:50:27 2008 From: sabre at nondot.org (Chris Lattner) Date: Sun, 07 Dec 2008 18:50:27 -0000 Subject: [llvm-commits] [test-suite] r60675 - /test-suite/trunk/Makefile.programs Message-ID: <200812071850.mB7IoSS2006337@zion.cs.uiuc.edu> Author: lattner Date: Sun Dec 7 12:50:27 2008 New Revision: 60675 URL: http://llvm.org/viewvc/llvm-project?rev=60675&view=rev Log: Two changes: 1) opt appends to the .info file, so remove it before opt runs. 2) emit -stats output in the "opt" .info file in addition to timing info. Modified: test-suite/trunk/Makefile.programs Modified: test-suite/trunk/Makefile.programs URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/Makefile.programs?rev=60675&r1=60674&r2=60675&view=diff ============================================================================== --- test-suite/trunk/Makefile.programs (original) +++ test-suite/trunk/Makefile.programs Sun Dec 7 12:50:27 2008 @@ -261,7 +261,8 @@ # standard compilation optimizations. $(PROGRAMS_TO_TEST:%=Output/%.linked.bc): \ Output/%.linked.bc: Output/%.linked.rbc $(LOPT) - -$(LOPT) -std-compile-opts -time-passes -info-output-file=$(CURDIR)/$@.info $(STATS) $(EXTRA_LOPT_OPTIONS) $< -o $@ -f + $(VERB) $(RM) -f $(CURDIR)/$@.info + -$(LOPT) -std-compile-opts -time-passes -stats -info-output-file=$(CURDIR)/$@.info $(STATS) $(EXTRA_LOPT_OPTIONS) $< -o $@ -f $(PROGRAMS_TO_TEST:%=Output/%.llvm.stripped.bc): \ Output/%.llvm.stripped.bc: Output/%.llvm.bc $(LOPT) @@ -269,7 +270,8 @@ $(PROGRAMS_TO_TEST:%=Output/%.linked.optbeta.bc): \ Output/%.linked.optbeta.bc: Output/%.linked.rbc $(LOPT) - -$(LOPT) $(OPTBETAOPTIONS) -time-passes -info-output-file=$(CURDIR)/$@.info $(STATS) $< -o $@ -f + $(VERB) $(RM) -f $(CURDIR)/$@.info + -$(LOPT) $(OPTBETAOPTIONS) -time-passes -stats -info-output-file=$(CURDIR)/$@.info $(STATS) $< -o $@ -f ifndef DISABLE_FOR_LLVM_PROGRAMS From gohman at apple.com Sun Dec 7 15:28:11 2008 From: gohman at apple.com (Dan Gohman) Date: Sun, 07 Dec 2008 21:28:11 -0000 Subject: [llvm-commits] [llvm] r60677 - /llvm/trunk/include/llvm/ADT/PointerIntPair.h Message-ID: <200812072128.mB7LSCIA010806@zion.cs.uiuc.edu> Author: djg Date: Sun Dec 7 15:28:00 2008 New Revision: 60677 URL: http://llvm.org/viewvc/llvm-project?rev=60677&view=rev Log: Use intptr_t instead of unsigned here, which is more appropriate in a really obscure way, but more importantly has the side effect of avoiding a GCC warning in the case that IntType is bool. Modified: llvm/trunk/include/llvm/ADT/PointerIntPair.h Modified: llvm/trunk/include/llvm/ADT/PointerIntPair.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/PointerIntPair.h?rev=60677&r1=60676&r2=60677&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/PointerIntPair.h (original) +++ llvm/trunk/include/llvm/ADT/PointerIntPair.h Sun Dec 7 15:28:00 2008 @@ -53,7 +53,7 @@ } void setInt(IntType Int) { - assert(unsigned(Int) < (1 << IntBits) && "Integer too large for field"); + assert(intptr_t(Int) < (1 << IntBits) && "Integer too large for field"); Value = reinterpret_cast(getPointer()) | (intptr_t)Int; } From gohman at apple.com Sun Dec 7 15:33:27 2008 From: gohman at apple.com (Dan Gohman) Date: Sun, 07 Dec 2008 21:33:27 -0000 Subject: [llvm-commits] [llvm] r60678 - /llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Message-ID: <200812072133.mB7LXSIT010944@zion.cs.uiuc.edu> Author: djg Date: Sun Dec 7 15:33:27 2008 New Revision: 60678 URL: http://llvm.org/viewvc/llvm-project?rev=60678&view=rev Log: Use bool instead of int, now that it no longer evokes a warning. Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60678&r1=60677&r2=60678&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original) +++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Sun Dec 7 15:33:27 2008 @@ -153,7 +153,7 @@ private: /// ValueIsLoadPair - This is a pair where the bool is true if /// the dependence is a read only dependence, false if read/write. - typedef PointerIntPair ValueIsLoadPair; + typedef PointerIntPair ValueIsLoadPair; /// CachedNonLocalPointerInfo - This map stores the cached results of doing /// a pointer lookup at the bottom of a block. The key of this map is the From overminddl1 at gmail.com Sun Dec 7 16:47:09 2008 From: overminddl1 at gmail.com (OvermindDL1) Date: Sun, 7 Dec 2008 15:47:09 -0700 Subject: [llvm-commits] Functor Patch for Visual Studio and Documentation fix to update the Visual Studio page Message-ID: <3f49a9f40812071447k7dc31df6mc6cbe0dad2958ac@mail.gmail.com> Attached is first a patch to add a const qualifier on a functor so Visual Studio 2005 will build (the standard says it should be there, but is not strictly required by it, however it is required by VS2k5). Also included are fixes to update the GettingStartedVS.html page to make it more up-to-date. Also included is a fix to GettingStarted.html to update the minimum Visual Studio version required. -------------- next part -------------- A non-text attachment was scrubbed... Name: FunctorAndDocs.patch Type: application/octet-stream Size: 6020 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081207/949ac60c/attachment.obj From nicholas at mxc.ca Sun Dec 7 17:43:55 2008 From: nicholas at mxc.ca (Nick Lewycky) Date: Sun, 07 Dec 2008 15:43:55 -0800 Subject: [llvm-commits] Functor Patch for Visual Studio and Documentation fix to update the Visual Studio page In-Reply-To: <3f49a9f40812071447k7dc31df6mc6cbe0dad2958ac@mail.gmail.com> References: <3f49a9f40812071447k7dc31df6mc6cbe0dad2958ac@mail.gmail.com> Message-ID: <493C5FBB.9030707@mxc.ca> OvermindDL1 wrote: > Attached is first a patch to add a const qualifier on a functor so > Visual Studio 2005 will build (the standard says it should be there, > but is not strictly required by it, however it is required by VS2k5). That change looks right to me. Thanks for working on it. > Also included are fixes to update the GettingStartedVS.html page to > make it more up-to-date. > > Also included is a fix to GettingStarted.html to update the minimum > Visual Studio version required. +
  3. If CMake is installed then the most simple way is to just start the gui gui -> GUI + compiling is complete
  4. Add a full stop like the other bullet points have. + (and please submit a patch if you do). Earlier version of Visual Studio Pluralize version to versions. Do you have commit access? Nick > > > ------------------------------------------------------------------------ > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From overminddl1 at gmail.com Sun Dec 7 18:22:47 2008 From: overminddl1 at gmail.com (OvermindDL1) Date: Sun, 7 Dec 2008 17:22:47 -0700 Subject: [llvm-commits] Functor Patch for Visual Studio and Documentation fix to update the Visual Studio page In-Reply-To: <493C5FBB.9030707@mxc.ca> References: <3f49a9f40812071447k7dc31df6mc6cbe0dad2958ac@mail.gmail.com> <493C5FBB.9030707@mxc.ca> Message-ID: <3f49a9f40812071622m2f40474al8b1c43e08f1c46d5@mail.gmail.com> On Sun, Dec 7, 2008 at 4:43 PM, Nick Lewycky wrote: > OvermindDL1 wrote: >> Attached is first a patch to add a const qualifier on a functor so >> Visual Studio 2005 will build (the standard says it should be there, >> but is not strictly required by it, however it is required by VS2k5). > > That change looks right to me. Thanks for working on it. > >> Also included are fixes to update the GettingStartedVS.html page to >> make it more up-to-date. >> >> Also included is a fix to GettingStarted.html to update the minimum >> Visual Studio version required. > > +
  5. If CMake is installed then the most simple way is to just start > the gui > > gui -> GUI > > + compiling is complete
  6. > > Add a full stop like the other bullet points have. > > + (and please submit a patch if you do). Earlier version of Visual Studio > > Pluralize version to versions. Patch updated with the above changes and attached (also change from "gui interface" to "CMake GUI" as it is more explicit). On Sun, Dec 7, 2008 at 4:43 PM, Nick Lewycky wrote: > Do you have commit access? No, I do not have any access beyond anonymous. -------------- next part -------------- A non-text attachment was scrubbed... Name: FunctorAndDocs1.patch Type: application/octet-stream Size: 6011 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20081207/fc862f6d/attachment.obj From nicholas at mxc.ca Sun Dec 7 18:45:04 2008 From: nicholas at mxc.ca (Nick Lewycky) Date: Mon, 08 Dec 2008 00:45:04 -0000 Subject: [llvm-commits] [llvm] r60679 - in /llvm/trunk: docs/GettingStarted.html docs/GettingStartedVS.html lib/Support/Annotation.cpp Message-ID: <200812080045.mB80j4OM016603@zion.cs.uiuc.edu> Author: nicholas Date: Sun Dec 7 18:45:02 2008 New Revision: 60679 URL: http://llvm.org/viewvc/llvm-project?rev=60679&view=rev Log: Fixes for Visual Studio users. Patch by OvermindDL1 on llvm-dev! Modified: llvm/trunk/docs/GettingStarted.html llvm/trunk/docs/GettingStartedVS.html llvm/trunk/lib/Support/Annotation.cpp Modified: llvm/trunk/docs/GettingStarted.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/GettingStarted.html?rev=60679&r1=60678&r2=60679&view=diff ============================================================================== --- llvm/trunk/docs/GettingStarted.html (original) +++ llvm/trunk/docs/GettingStarted.html Sun Dec 7 18:45:02 2008 @@ -268,7 +268,7 @@ Windows x861 - Visual Studio .NET4,5 + Visual Studio 2005 SP1 or higher4,5 AIX3,4 PowerPC @@ -305,7 +305,7 @@ up
  7. Code generation supported for 32-bit ABI only
  8. No native code generation
  9. -
  10. Build is not complete: one or more tools don't link
  11. +
  12. Build is not complete: one or more tools do not link or function
  13. The GCC-based C/C++ frontend does not build
  14. The port is done using the MSYS shell. Download and install Modified: llvm/trunk/docs/GettingStartedVS.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/GettingStartedVS.html?rev=60679&r1=60678&r2=60679&view=diff ============================================================================== --- llvm/trunk/docs/GettingStartedVS.html (original) +++ llvm/trunk/docs/GettingStartedVS.html Sun Dec 7 18:45:02 2008 @@ -65,12 +65,12 @@

    The LLVM test suite cannot be run on the Visual Studio port at this time.

    -

    Most of the tools build and work. llvm-db does not build at this - time. bugpoint does build, but does not work. +

    Most of the tools build and work. bugpoint does build, but does + not work. The other tools 'should' work, but have not been fully tested.

    Additional information about the LLVM directory structure and tool chain can be found on the main Getting Started - page.

    + page.

    @@ -108,11 +108,38 @@
  15. cd llvm
+ +
  • Use CMake to generate up-to-date + project files: +
    • This step is currently optional as LLVM does still come with a + normal Visual Studio solution file, but it is not always kept up-to-date + and will soon be deprecated in favor of the multi-platform generator + CMake.
    • +
    • If CMake is installed then the most simple way is to just start the + CMake GUI, select the directory where you have LLVM extracted to, and + the default options should all be fine. The one option you may really + want to change, regardless of anything else, might be the + CMAKE_INSTALL_PREFIX setting to select a directory to INSTALL to once + compiling is complete.
    • +
    • If you use CMake to generate the Visual Studio solution and project + files, then the Solution will have a few extra options compared to the + current included one. The projects may still be built individually, but + to build them all do not just select all of them in batch build (as some + are meant as configuration projects), but rather select and build just + the ALL_BUILD project to build everything, or the INSTALL project, which + first builds the ALL_BUILD project, then installs the LLVM headers, libs, + and other useful things to the directory set by the CMAKE_INSTALL_PREFIX + setting when you first configured CMake.
    • +
    +
  • Start Visual Studio -
      -
    1. Simply double click on the solution file llvm/win32/llvm.sln. -
    2. +
        +
      • If you did not use CMake, then simply double click on the solution + file llvm/win32/llvm.sln.
      • +
      • If you used CMake, then the directory you created the project files, + the root directory will have an llvm.sln file, just + double-click on that to open Visual Studio.
  • Build the LLVM Suite: @@ -151,8 +178,8 @@
    -

    Any system that can adequately run Visual Studio .NET 2003 is fine. The - LLVM source tree and object files, libraries and executables will consume +

    Any system that can adequately run Visual Studio .NET 2005 SP1 is fine. + The LLVM source tree and object files, libraries and executables will consume approximately 3GB.

    @@ -161,11 +188,15 @@
    -

    You will need Visual Studio .NET 2003. Earlier versions cannot open the - solution/project files. The VS 2005 beta can, but will migrate these files - to its own format in the process. While it should work with the VS 2005 - beta, there are no guarantees and there is no support for it at this time. - It has been reported that VC++ Express also works.

    +

    You will need Visual Studio .NET 2005 SP1 or higher. The VS2005 SP1 + beta and the normal VS2005 still have bugs that are not completely + compatible. VS2003 would work except (at last check) it has a bug with + friend classes that you can work-around with some minor code rewriting + (and please submit a patch if you do). Earlier versions of Visual Studio + do not support the C++ standard well enough and will not work.

    + +

    You will also need the CMake build + system since it generates the project files you will use to build with.

    If you plan to modify any .y or .l files, you will need to have bison and/or flex installed where Visual Studio can find them. Otherwise, you do Modified: llvm/trunk/lib/Support/Annotation.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Annotation.cpp?rev=60679&r1=60678&r2=60679&view=diff ============================================================================== --- llvm/trunk/lib/Support/Annotation.cpp (original) +++ llvm/trunk/lib/Support/Annotation.cpp Sun Dec 7 18:45:02 2008 @@ -31,7 +31,7 @@ namespace { class StrCmp { public: - bool operator()(const char *a, const char *b) { + bool operator()(const char *a, const char *b) const { return strcmp(a, b) < 0; } }; From gohman at apple.com Sun Dec 7 22:02:47 2008 From: gohman at apple.com (Dan Gohman) Date: Mon, 08 Dec 2008 04:02:47 -0000 Subject: [llvm-commits] [llvm] r60681 - in /llvm/trunk: docs/CommandGuide/bugpoint.pod tools/bugpoint/BugDriver.cpp tools/bugpoint/BugDriver.h tools/bugpoint/ExecutionDriver.cpp tools/bugpoint/Miscompilation.cpp Message-ID: <200812080402.mB842m67023129@zion.cs.uiuc.edu> Author: djg Date: Sun Dec 7 22:02:47 2008 New Revision: 60681 URL: http://llvm.org/viewvc/llvm-project?rev=60681&view=rev Log: Generalize bugpoint's concept of a "safe" backend, and add options to allow the "safe" backend to be run with a different path, and/or with different command-line options. This enables the following use cases: - bugpoint llc against an llc command from a different build - bugpoint llc against the same llc with different command-line options - and more... Also, document the existing "custom" interpreter options. Modified: llvm/trunk/docs/CommandGuide/bugpoint.pod llvm/trunk/tools/bugpoint/BugDriver.cpp llvm/trunk/tools/bugpoint/BugDriver.h llvm/trunk/tools/bugpoint/ExecutionDriver.cpp llvm/trunk/tools/bugpoint/Miscompilation.cpp Modified: llvm/trunk/docs/CommandGuide/bugpoint.pod URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CommandGuide/bugpoint.pod?rev=60681&r1=60680&r2=60681&view=diff ============================================================================== --- llvm/trunk/docs/CommandGuide/bugpoint.pod (original) +++ llvm/trunk/docs/CommandGuide/bugpoint.pod Sun Dec 7 22:02:47 2008 @@ -57,6 +57,11 @@ options starting with C<-> to be part of the B<--tool-args> option, not as options to B itself. (See B<--args>, above.) +=item B<--safe-tool-args> I + +Pass all arguments specified after --safe-tool-args to the "safe" execution +tool. + =item B<--disable-{dce,simplifycfg}> Do not run the specified passes to clean up and reduce the size of the test @@ -103,18 +108,41 @@ Whenever the test program produces output on its standard output stream, it should match the contents of F (the "reference output"). If you do not use this option, B will attempt to generate a reference output -by compiling the program with the C backend and running it. +by compiling the program with the "safe" backend and running it. =item B<--profile-info-file> F Profile file loaded by B<--profile-loader>. -=item B<--run-{int,jit,llc,cbe}> +=item B<--run-{int,jit,llc,cbe,custom}> Whenever the test program is compiled, B should generate code for it using the specified code generator. These options allow you to choose the -interpreter, the JIT compiler, the static native code compiler, or the C -backend, respectively. +interpreter, the JIT compiler, the static native code compiler, the C +backend, or a custom command (see B<--exec-command>) respectively. + +=item B<--safe-{llc,cbe,custom}> + +When debugging a code generator, B should use the specified code +generator as the "safe" code generator. This is a known-good code generator +used to generate the "reference output" if it has not been provided, and to +compile portions of the program that as they are excluded from the testcase. +These options allow you to choose the +static native code compiler, the C backend, or a custom command, +(see B<--exec-command>) respectively. The interpreter and the JIT backends +cannot currently be used as the "safe" backends. + +=item B<--exec-command> I + +This option defines the command to use with the B<--run-custom> and +B<--safe-custom> options to execute the bitcode testcase. This can +be useful for cross-compilation. + +=item B<--safe-path> I + +This option defines the path to the command to execute with the +B<--safe-{int,jit,llc,cbe,custom}> +option. =back Modified: llvm/trunk/tools/bugpoint/BugDriver.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/BugDriver.cpp?rev=60681&r1=60680&r2=60681&view=diff ============================================================================== --- llvm/trunk/tools/bugpoint/BugDriver.cpp (original) +++ llvm/trunk/tools/bugpoint/BugDriver.cpp Sun Dec 7 22:02:47 2008 @@ -65,7 +65,8 @@ BugDriver::BugDriver(const char *toolname, bool as_child, bool find_bugs, unsigned timeout, unsigned memlimit) : ToolName(toolname), ReferenceOutputFile(OutputFile), - Program(0), Interpreter(0), cbe(0), gcc(0), run_as_child(as_child), + Program(0), Interpreter(0), SafeInterpreter(0), gcc(0), + run_as_child(as_child), run_find_bugs(find_bugs), Timeout(timeout), MemoryLimit(memlimit) {} Modified: llvm/trunk/tools/bugpoint/BugDriver.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/BugDriver.h?rev=60681&r1=60680&r2=60681&view=diff ============================================================================== --- llvm/trunk/tools/bugpoint/BugDriver.h (original) +++ llvm/trunk/tools/bugpoint/BugDriver.h Sun Dec 7 22:02:47 2008 @@ -45,7 +45,7 @@ Module *Program; // The raw program, linked together std::vector PassesToRun; AbstractInterpreter *Interpreter; // How to run the program - AbstractInterpreter *cbe; + AbstractInterpreter *SafeInterpreter; // To generate reference output, etc. GCC *gcc; bool run_as_child; bool run_find_bugs; @@ -140,9 +140,9 @@ return OldProgram; } - AbstractInterpreter *switchToCBE() { + AbstractInterpreter *switchToSafeInterpreter() { AbstractInterpreter *Old = Interpreter; - Interpreter = (AbstractInterpreter*)cbe; + Interpreter = (AbstractInterpreter*)SafeInterpreter; return Old; } @@ -172,11 +172,11 @@ AbstractInterpreter *AI = 0, bool *ProgramExitedNonzero = 0); - /// executeProgramWithCBE - Used to create reference output with the C + /// executeProgramSafely - Used to create reference output with the "safe" /// backend, if reference output is not provided. If there is a problem with /// the code generator (e.g., llc crashes), this will throw an exception. /// - std::string executeProgramWithCBE(std::string OutputFile = ""); + std::string executeProgramSafely(std::string OutputFile = ""); /// createReferenceFile - calls compileProgram and then records the output /// into ReferenceOutputFile. Returns true if reference file created, false Modified: llvm/trunk/tools/bugpoint/ExecutionDriver.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/ExecutionDriver.cpp?rev=60681&r1=60680&r2=60681&view=diff ============================================================================== --- llvm/trunk/tools/bugpoint/ExecutionDriver.cpp (original) +++ llvm/trunk/tools/bugpoint/ExecutionDriver.cpp Sun Dec 7 22:02:47 2008 @@ -39,7 +39,7 @@ cl::init(0.0)); cl::opt - InterpreterSel(cl::desc("Specify how LLVM code should be executed:"), + InterpreterSel(cl::desc("Specify the \"test\" i.e. suspect back-end:"), cl::values(clEnumValN(AutoPick, "auto", "Use best guess"), clEnumValN(RunLLI, "run-int", "Execute with the interpreter"), @@ -54,6 +54,22 @@ clEnumValEnd), cl::init(AutoPick)); + cl::opt + SafeInterpreterSel(cl::desc("Specify \"safe\" i.e. known-good backend:"), + cl::values(clEnumValN(AutoPick, "safe-auto", "Use best guess"), + clEnumValN(RunLLC, "safe-run-llc", "Compile with LLC"), + clEnumValN(RunCBE, "safe-run-cbe", "Compile with CBE"), + clEnumValN(Custom, "safe-run-custom", + "Use -exec-command to define a command to execute " + "the bitcode. Useful for cross-compilation."), + clEnumValEnd), + cl::init(AutoPick)); + + cl::opt + SafeInterpreterPath("safe-path", + cl::desc("Specify the path to the \"safe\" backend program"), + cl::init("")); + cl::opt AppendProgramExitCode("append-exit-code", cl::desc("Append the exit code to the output so it gets diff'd too"), @@ -84,10 +100,17 @@ cl::list InputArgv("args", cl::Positional, cl::desc("..."), cl::ZeroOrMore, cl::PositionalEatsArgs); +} +namespace { cl::list ToolArgv("tool-args", cl::Positional, cl::desc("..."), cl::ZeroOrMore, cl::PositionalEatsArgs); + + cl::list + SafeToolArgv("safe-tool-args", cl::Positional, + cl::desc("..."), + cl::ZeroOrMore, cl::PositionalEatsArgs); } //===----------------------------------------------------------------------===// @@ -102,14 +125,14 @@ // Create an instance of the AbstractInterpreter interface as specified on // the command line - cbe = 0; + SafeInterpreter = 0; std::string Message; switch (InterpreterSel) { case AutoPick: InterpreterSel = RunCBE; - Interpreter = cbe = AbstractInterpreter::createCBE(getToolName(), Message, - &ToolArgv); + Interpreter = + AbstractInterpreter::createCBE(getToolName(), Message, &ToolArgv); if (!Interpreter) { InterpreterSel = RunJIT; Interpreter = AbstractInterpreter::createJIT(getToolName(), Message, @@ -135,6 +158,7 @@ &ToolArgv); break; case RunLLC: + case LLC_Safe: Interpreter = AbstractInterpreter::createLLC(getToolName(), Message, &ToolArgv); break; @@ -142,10 +166,6 @@ Interpreter = AbstractInterpreter::createJIT(getToolName(), Message, &ToolArgv); break; - case LLC_Safe: - Interpreter = AbstractInterpreter::createLLC(getToolName(), Message, - &ToolArgv); - break; case RunCBE: case CBE_bug: Interpreter = AbstractInterpreter::createCBE(getToolName(), Message, @@ -164,20 +184,71 @@ else // Display informational messages on stdout instead of stderr std::cout << Message; - // Initialize auxiliary tools for debugging - if (InterpreterSel == RunCBE) { - // We already created a CBE, reuse it. - cbe = Interpreter; - } else if (InterpreterSel == CBE_bug || InterpreterSel == LLC_Safe) { - // We want to debug the CBE itself or LLC is known-good. Use LLC as the - // 'known-good' compiler. - std::vector ToolArgs; - ToolArgs.push_back("--relocation-model=pic"); - cbe = AbstractInterpreter::createLLC(getToolName(), Message, &ToolArgs); - } else { - cbe = AbstractInterpreter::createCBE(getToolName(), Message, &ToolArgv); + std::string Path = SafeInterpreterPath; + if (Path.empty()) + Path = getToolName(); + std::vector SafeToolArgs = SafeToolArgv; + switch (SafeInterpreterSel) { + case AutoPick: + // In "cbe-bug" mode, default to using LLC as the "safe" backend. + if (!SafeInterpreter && + InterpreterSel == CBE_bug) { + SafeInterpreterSel = RunLLC; + SafeToolArgs.push_back("--relocation-model=pic"); + SafeInterpreter = AbstractInterpreter::createLLC(Path, Message, + &SafeToolArgs); + } + + // In "llc-safe" mode, default to using LLC as the "safe" backend. + if (!SafeInterpreter && + InterpreterSel == LLC_Safe) { + SafeInterpreterSel = RunLLC; + SafeToolArgs.push_back("--relocation-model=pic"); + SafeInterpreter = AbstractInterpreter::createLLC(Path, Message, + &SafeToolArgs); + } + + // Pick a backend that's different from the test backend. The JIT and + // LLC backends share a lot of code, so prefer to use the CBE as the + // safe back-end when testing them. + if (!SafeInterpreter && + InterpreterSel != RunCBE) { + SafeInterpreterSel = RunCBE; + SafeInterpreter = AbstractInterpreter::createCBE(Path, Message, + &SafeToolArgs); + } + if (!SafeInterpreter && + InterpreterSel != RunLLC && + InterpreterSel != RunJIT) { + SafeInterpreterSel = RunLLC; + SafeToolArgs.push_back("--relocation-model=pic"); + SafeInterpreter = AbstractInterpreter::createLLC(Path, Message, + &SafeToolArgs); + } + if (!SafeInterpreter) { + SafeInterpreterSel = AutoPick; + Message = "Sorry, I can't automatically select an interpreter!\n"; + } + break; + case RunLLC: + SafeToolArgs.push_back("--relocation-model=pic"); + SafeInterpreter = AbstractInterpreter::createLLC(Path, Message, + &SafeToolArgs); + break; + case RunCBE: + SafeInterpreter = AbstractInterpreter::createCBE(Path, Message, + &SafeToolArgs); + break; + case Custom: + SafeInterpreter = AbstractInterpreter::createCustom(Path, Message, + CustomExecCommand); + break; + default: + Message = "Sorry, this back-end is not supported by bugpoint as the " + "\"safe\" backend right now!\n"; + break; } - if (!cbe) { std::cout << Message << "\nExiting.\n"; exit(1); } + if (!SafeInterpreter) { std::cout << Message << "\nExiting.\n"; exit(1); } gcc = GCC::create(getToolName(), Message); if (!gcc) { std::cout << Message << "\nExiting.\n"; exit(1); } @@ -264,20 +335,9 @@ if (!SharedObj.empty()) SharedObjs.push_back(SharedObj); - - // If this is an LLC or CBE run, then the GCC compiler might get run to - // compile the program. If so, we should pass the user's -Xlinker options - // as the GCCArgs. - int RetVal = 0; - if (InterpreterSel == RunLLC || InterpreterSel == RunCBE || - InterpreterSel == CBE_bug || InterpreterSel == LLC_Safe) - RetVal = AI->ExecuteProgram(BitcodeFile, InputArgv, InputFile, - OutputFile, AdditionalLinkerArgs, SharedObjs, - Timeout, MemoryLimit); - else - RetVal = AI->ExecuteProgram(BitcodeFile, InputArgv, InputFile, - OutputFile, std::vector(), - SharedObjs, Timeout, MemoryLimit); + int RetVal = AI->ExecuteProgram(BitcodeFile, InputArgv, InputFile, + OutputFile, AdditionalLinkerArgs, SharedObjs, + Timeout, MemoryLimit); if (RetVal == -1) { std::cerr << ""; @@ -305,12 +365,12 @@ return OutputFile; } -/// executeProgramWithCBE - Used to create reference output with the C +/// executeProgramSafely - Used to create reference output with the "safe" /// backend, if reference output is not provided. /// -std::string BugDriver::executeProgramWithCBE(std::string OutputFile) { +std::string BugDriver::executeProgramSafely(std::string OutputFile) { bool ProgramExitedNonzero; - std::string outFN = executeProgram(OutputFile, "", "", cbe, + std::string outFN = executeProgram(OutputFile, "", "", SafeInterpreter, &ProgramExitedNonzero); return outFN; } @@ -319,8 +379,8 @@ assert(Interpreter && "Interpreter should have been created already!"); sys::Path OutputFile; - // Using CBE - GCC::FileType FT = cbe->OutputCode(BitcodeFile, OutputFile); + // Using the known-good backend. + GCC::FileType FT = SafeInterpreter->OutputCode(BitcodeFile, OutputFile); std::string SharedObjectFile; if (gcc->MakeSharedObject(OutputFile.toString(), FT, @@ -345,14 +405,15 @@ return false; } try { - ReferenceOutputFile = executeProgramWithCBE(Filename); + ReferenceOutputFile = executeProgramSafely(Filename); std::cout << "Reference output is: " << ReferenceOutputFile << "\n\n"; } catch (ToolExecutionError &TEE) { std::cerr << TEE.what(); - if (Interpreter != cbe) { - std::cerr << "*** There is a bug running the C backend. Either debug" - << " it (use the -run-cbe bugpoint option), or fix the error" - << " some other way.\n"; + if (Interpreter != SafeInterpreter) { + std::cerr << "*** There is a bug running the \"safe\" backend. Either" + << " debug it (for example with the -run-cbe bugpoint option," + << " if CBE is being used as the \"safe\" backend), or fix the" + << " error some other way.\n"; } return false; } Modified: llvm/trunk/tools/bugpoint/Miscompilation.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/Miscompilation.cpp?rev=60681&r1=60680&r2=60681&view=diff ============================================================================== --- llvm/trunk/tools/bugpoint/Miscompilation.cpp (original) +++ llvm/trunk/tools/bugpoint/Miscompilation.cpp Sun Dec 7 22:02:47 2008 @@ -277,7 +277,7 @@ // we're going to test the newly loop extracted program to make sure nothing // has broken. If something broke, then we'll inform the user and stop // extraction. - AbstractInterpreter *AI = BD.switchToCBE(); + AbstractInterpreter *AI = BD.switchToSafeInterpreter(); if (TestMergedProgram(BD, ToOptimizeLoopExtracted, ToNotOptimize, false)) { BD.switchToInterpreter(AI); @@ -838,13 +838,15 @@ /// debugCodeGenerator - debug errors in LLC, LLI, or CBE. /// bool BugDriver::debugCodeGenerator() { - if ((void*)cbe == (void*)Interpreter) { - std::string Result = executeProgramWithCBE("bugpoint.cbe.out"); - std::cout << "\n*** The C backend cannot match the reference diff, but it " - << "is used as the\n 'known good' code generator, so I can't" - << " debug it. Perhaps you have a\n front-end problem? As a" - << " sanity check, I left the result of executing the\n " - << "program with the C backend in this file for you: '" + if ((void*)SafeInterpreter == (void*)Interpreter) { + std::string Result = executeProgramSafely("bugpoint.safe.out"); + std::cout << "\n*** The \"safe\" i.e. 'known good' backend cannot match " + << "the reference diff. This may be due to a\n front-end " + << "bug or a bug in the original program, but this can also " + << "happen if bugpoint isn't running the program with the " + << "right flags or input.\n I left the result of executing " + << "the program with the \"safe\" backend in this file for " + << "you: '" << Result << "'.\n"; return true; } From gohman at apple.com Sun Dec 7 22:11:57 2008 From: gohman at apple.com (Dan Gohman) Date: Mon, 08 Dec 2008 04:11:57 -0000 Subject: [llvm-commits] [llvm] r60682 - /llvm/trunk/tools/llvmc/plugins/Clang/ Message-ID: <200812080411.mB84BwLV023434@zion.cs.uiuc.edu> Author: djg Date: Sun Dec 7 22:11:50 2008 New Revision: 60682 URL: http://llvm.org/viewvc/llvm-project?rev=60682&view=rev Log: Add svn:ignore property. Modified: llvm/trunk/tools/llvmc/plugins/Clang/ (props changed) Propchange: llvm/trunk/tools/llvmc/plugins/Clang/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Sun Dec 7 22:11:50 2008 @@ -0,0 +1,4 @@ +AutoGenerated.inc +Debug +Release +Release-Asserts From gohman at apple.com Sun Dec 7 22:53:23 2008 From: gohman at apple.com (Dan Gohman) Date: Mon, 08 Dec 2008 04:53:23 -0000 Subject: [llvm-commits] [llvm] r60683 - /llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <200812080453.mB84rOuX024818@zion.cs.uiuc.edu> Author: djg Date: Sun Dec 7 22:53:23 2008 New Revision: 60683 URL: http://llvm.org/viewvc/llvm-project?rev=60683&view=rev Log: Clarify some comments. Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=60683&r1=60682&r2=60683&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Sun Dec 7 22:53:23 2008 @@ -918,7 +918,7 @@ MachineRegisterInfo::def_iterator I = mri_->def_begin(Reg), E = mri_->def_end(); - // For the def, it should be the only def. + // For the def, it should be the only def of that register. if (MO.isDef() && (next(I) != E || IsLiveIn)) return false; @@ -931,7 +931,7 @@ else if (Reg != ImpUse) return false; } - // For uses, there should be only one associate def. + // For the use, there should be only one associated def. if (I != E && (next(I) != E || IsLiveIn)) return false; } From gohman at apple.com Sun Dec 7 22:54:11 2008 From: gohman at apple.com (Dan Gohman) Date: Mon, 08 Dec 2008 04:54:11 -0000 Subject: [llvm-commits] [llvm] r60684 - in /llvm/trunk: include/llvm/CodeGen/MachineRegisterInfo.h lib/CodeGen/MachineRegisterInfo.cpp Message-ID: <200812080454.mB84sBaN024852@zion.cs.uiuc.edu> Author: djg Date: Sun Dec 7 22:54:11 2008 New Revision: 60684 URL: http://llvm.org/viewvc/llvm-project?rev=60684&view=rev Log: Move createVirtualRegister out-of-line. Modified: llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp Modified: llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h?rev=60684&r1=60683&r2=60684&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h Sun Dec 7 22:54:11 2008 @@ -164,19 +164,7 @@ /// createVirtualRegister - Create and return a new virtual register in the /// function with the specified register class. /// - unsigned createVirtualRegister(const TargetRegisterClass *RegClass) { - assert(RegClass && "Cannot create register without RegClass!"); - // Add a reg, but keep track of whether the vector reallocated or not. - void *ArrayBase = VRegInfo.empty() ? 0 : &VRegInfo[0]; - VRegInfo.push_back(std::make_pair(RegClass, (MachineOperand*)0)); - - if (!((&VRegInfo[0] == ArrayBase || VRegInfo.size() == 1))) - // The vector reallocated, handle this now. - HandleVRegListReallocation(); - unsigned VR = getLastVirtReg(); - RegClass2VRegMap[RegClass->getID()].push_back(VR); - return VR; - } + unsigned createVirtualRegister(const TargetRegisterClass *RegClass); /// getLastVirtReg - Return the highest currently assigned virtual register. /// Modified: llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp?rev=60684&r1=60683&r2=60684&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp Sun Dec 7 22:54:11 2008 @@ -35,6 +35,24 @@ delete [] PhysRegUseDefLists; } +/// createVirtualRegister - Create and return a new virtual register in the +/// function with the specified register class. +/// +unsigned +MachineRegisterInfo::createVirtualRegister(const TargetRegisterClass *RegClass){ + assert(RegClass && "Cannot create register without RegClass!"); + // Add a reg, but keep track of whether the vector reallocated or not. + void *ArrayBase = VRegInfo.empty() ? 0 : &VRegInfo[0]; + VRegInfo.push_back(std::make_pair(RegClass, (MachineOperand*)0)); + + if (!((&VRegInfo[0] == ArrayBase || VRegInfo.size() == 1))) + // The vector reallocated, handle this now. + HandleVRegListReallocation(); + unsigned VR = getLastVirtReg(); + RegClass2VRegMap[RegClass->getID()].push_back(VR); + return VR; +} + /// HandleVRegListReallocation - We just added a virtual register to the /// VRegInfo info list and it reallocated. Update the use/def lists info /// pointers. From gohman at apple.com Sun Dec 7 22:54:59 2008 From: gohman at apple.com (Dan Gohman) Date: Mon, 08 Dec 2008 04:54:59 -0000 Subject: [llvm-commits] [llvm] r60685 - /llvm/trunk/include/llvm/Target/TargetLowering.h Message-ID: <200812080454.mB84sxcI024885@zion.cs.uiuc.edu> Author: djg Date: Sun Dec 7 22:54:58 2008 New Revision: 60685 URL: http://llvm.org/viewvc/llvm-project?rev=60685&view=rev Log: Clarify a comment. Modified: llvm/trunk/include/llvm/Target/TargetLowering.h Modified: llvm/trunk/include/llvm/Target/TargetLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=60685&r1=60684&r2=60685&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) +++ llvm/trunk/include/llvm/Target/TargetLowering.h Sun Dec 7 22:54:58 2008 @@ -1171,7 +1171,7 @@ } /// GetPossiblePreceedingTailCall - Get preceeding TailCallNodeOpCode node if - /// it exists skip possible ISD:TokenFactor. + /// it exists. Skip a possible ISD:TokenFactor. static SDValue GetPossiblePreceedingTailCall(SDValue Chain, unsigned TailCallNodeOpCode) { if (Chain.getOpcode() == TailCallNodeOpCode) {